Skip to main content

Contract

Trait Contract 

Source
pub trait Contract<T> {
    // Required methods
    fn matmul<'a, D0, D1, D2, La, Lb>(
        &self,
        a: &'a Slice<T, (D0, D1), La>,
        b: &'a Slice<T, (D1, D2), Lb>,
    ) -> impl MatmulBuilder<'a, T, D0, D1, D2, La, Lb>
       where D0: Dim,
             D1: Dim,
             D2: Dim,
             La: Layout,
             Lb: Layout;
    fn contract_all<'a, Sa, Sb, La, Lb>(
        &self,
        a: &'a Slice<T, Sa, La>,
        b: &'a Slice<T, Sb, Lb>,
    ) -> T
       where T: 'a,
             Sa: Shape,
             Sb: Shape,
             La: Layout,
             Lb: Layout;
    fn contract_n<'a, Sa, Sb, La, Lb>(
        &self,
        a: &'a Slice<T, Sa, La>,
        b: &'a Slice<T, Sb, Lb>,
        n: usize,
    ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
       where T: 'a,
             Sa: Shape,
             Sb: Shape,
             La: Layout,
             Lb: Layout;
    fn contract_pairs<'a, Sa, Sb, La, Lb>(
        &self,
        a: &'a Slice<T, Sa, La>,
        b: &'a Slice<T, Sb, Lb>,
        axes_a: &'a [usize],
        axes_b: &'a [usize],
    ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
       where T: 'a,
             Sa: Shape,
             Sb: Shape,
             La: Layout,
             Lb: Layout;
    fn contract<'a, Sa, Sb, La, Lb>(
        &self,
        a: &'a Slice<T, Sa, La>,
        b: &'a Slice<T, Sb, Lb>,
        indices_a: &'a [u8],
        indices_b: &'a [u8],
        indices_c: &'a [u8],
    ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
       where T: 'a,
             Sa: Shape,
             Sb: Shape,
             La: Layout,
             Lb: Layout;
}
Expand description

Tensor contraction and related operations

Required Methods§

Source

fn matmul<'a, D0, D1, D2, La, Lb>( &self, a: &'a Slice<T, (D0, D1), La>, b: &'a Slice<T, (D1, D2), Lb>, ) -> impl MatmulBuilder<'a, T, D0, D1, D2, La, Lb>
where D0: Dim, D1: Dim, D2: Dim, La: Layout, Lb: Layout,

Matrix multiplication.

use mdarray::tensor;
use mdarray_linalg::{Naive, prelude::*};

let a = tensor![[1., 2.], [3., 4.]];
let b = tensor![[5., 6.], [7., 8.]];
assert_eq!(Naive.matmul(&a, &b).eval(), tensor![[19., 22.], [43., 50.]]);
Source

fn contract_all<'a, Sa, Sb, La, Lb>( &self, a: &'a Slice<T, Sa, La>, b: &'a Slice<T, Sb, Lb>, ) -> T
where T: 'a, Sa: Shape, Sb: Shape, La: Layout, Lb: Layout,

Contracts all axes of a with all axes of b.

This is the full reduction case, i.e. a scalar result.

Source

fn contract_n<'a, Sa, Sb, La, Lb>( &self, a: &'a Slice<T, Sa, La>, b: &'a Slice<T, Sb, Lb>, n: usize, ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
where T: 'a, Sa: Shape, Sb: Shape, La: Layout, Lb: Layout,

Contracts the last n axes of a with the first n axes of b.

For matrices, contract_n(1) is standard matrix multiplication.

Source

fn contract_pairs<'a, Sa, Sb, La, Lb>( &self, a: &'a Slice<T, Sa, La>, b: &'a Slice<T, Sb, Lb>, axes_a: &'a [usize], axes_b: &'a [usize], ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
where T: 'a, Sa: Shape, Sb: Shape, La: Layout, Lb: Layout,

Contracts explicit pairs of axes.

This is the structured contraction API. contract_pairs(&a, &b, &[1], &[0]) is matrix multiplication for 2D inputs.

Source

fn contract<'a, Sa, Sb, La, Lb>( &self, a: &'a Slice<T, Sa, La>, b: &'a Slice<T, Sb, Lb>, indices_a: &'a [u8], indices_b: &'a [u8], indices_c: &'a [u8], ) -> impl ContractBuilder<'a, T, Sa, Sb, La, Lb>
where T: 'a, Sa: Shape, Sb: Shape, La: Layout, Lb: Layout,

Fully general contraction of two tensors, à la einsum.

use mdarray::array;
use mdarray_linalg::{Naive, prelude::*};

let a = array![[1., 2.], [3., 4.]].into_dyn();
let b = array![[5., 6.], [7., 8.]].into_dyn();
let c = Naive.contract(&a, &b, &[0, 1], &[1, 2], &[0, 2]).eval();
assert_eq!(c, array![[19., 22.], [43., 50.]].into_dyn());

New indices in indices_a and indices_b must be subsequent integers starting with 0. For example, having [0, 1, 1, 2] or [0, 1, 0, 2] for indices_a is OK, but [0, 2, 2, 3] is not. Note that this is not limiting in any way. Any legal einsum can be specified in this way.

Note that this is a low-level operation. The above restrictions allow to avoid runtime checks. We will add a more user-friendly higher-level wrapper.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T> Contract<T> for Naive
where T: ComplexFloat + Zero + One + MulAdd<Output = T> + AddAssign + Sum,