use mdarray::{view, array, tensor, Slice, Dim, Const, expr::Expression}; // Indexing convention: C_ij <- A_ik * B_kj fn matmul( a: &Slice, b: &Slice, c: &mut Slice) { for (mut ci, ai) in c.rows_mut().zip(a.rows()) { for (aik, bk) in ai.zip(b.rows()) { for (cij, bkj) in ci.expr_mut().zip(bk) { *cij = aik.mul_add(*bkj, *cij); } } } } fn main() { let a = view![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]; let b = array![[0.0, 1.0], [1.0, 1.0]]; let b = b.reshape((Const::<2>, !0)); // .into_dyn() replaces .reshape(DynRank::from_dims(&[2, 3])).into(): let mut c: mdarray::Tensor = tensor![[0.0; 2]; 3].into_dyn(); dbg!(std::any::type_name_of_val(&a)); dbg!(std::any::type_name_of_val(&b)); dbg!(std::any::type_name_of_val(&c)); matmul(&a.reshape((3, Const::<2>)), &b, &mut c.remap_mut()); assert_eq!(c, view![[4.0, 5.0], [5.0, 7.0], [6.0, 9.0]]); // slice let d = a.view(1, ..); dbg!(std::any::type_name_of_val(&d)); // index let e = c[4]; dbg!(std::any::type_name_of_val(&e)); // permute let f = c.permute((1, 0)); dbg!(std::any::type_name_of_val(&f)); }