pub fn tensordot<'graph, A, B, AT1, AT2, F: Float>(
    a: A,
    b: B,
    a_axes: &AT1,
    b_axes: &AT2,
) -> Tensor<'graph, F>
where
    A: AsRef<Tensor<'graph, F>> + Copy,
    B: AsRef<Tensor<'graph, F>> + Copy,
    AT1: AsTensor<'graph, F>,
    AT2: AsTensor<'graph, F>,
{
    let a = a.as_ref();
    let g = a.graph();
    // Preprocess
    let pre = &Tensor::builder(g)
        .append_input(a.as_ref(), false)
        .append_input(b.as_ref(), false)
        .append_input(&a_axes.as_tensor(g), false)
        .append_input(&b_axes.as_tensor(g), false)
        .build(dot_ops::TensordotPreprocess);
    let final_shape = nth_tensor(pre, 0);
    let perm_a = nth_tensor(pre, 1);
    let perm_b = nth_tensor(pre, 2);
    let new_shape_a = nth_tensor(pre, 3);
    let new_shape_b = nth_tensor(pre, 4);

    let a_reshaped = reshape(transpose(a, &perm_a), &new_shape_a);
    let b_reshaped = reshape(transpose(b, &perm_b), &new_shape_b);

    // matmul
    let mm = matmul(a_reshaped, b_reshaped);
    reshape(mm, &final_shape)
}
/// Computes tensor-dot-product (tensor contraction) along specified axes.
///
/// # Arguments
/// * `a` - First input tensor
/// * `b` - Second input tensor
/// * `a_axes` - `a`'s Contraction axes
/// * `b_axes` - `b`'s Contraction axes
///
/// NOTE:
///
/// * length of `a_axes` and `b_axes` must match.
/// * Each axis number can be negative.
/// * Supports only f32 and f64.
///
/// ```
/// use autograd as ag;
/// use ag::tensor_ops::*;
///
/// ag::run(|g| {
///    let a: ag::Tensor<f32> = zeros(&[3, 4, 5], g);
///    let b: ag::Tensor<f32> = zeros(&[4, 3, 2], g);
///    let c = tensordot(a, b, &[1, 0], &[0, 1]);
///    assert_eq!(c.eval(g).unwrap().shape(), &[5, 2]);
/// });
/// ```
///
/// For detailed description,
/// see <https://docs.scipy.org/doc/numpy/reference/generated/numpy.tensordot.html>.
Computes tensor-dot-product (tensor contraction) along specified axes.
Computes tensor - dot - product ( tensor contraction ) along specified axes .
pub fn tensordot<'graph, A, B, AT1, AT2, F: Float>(
    a: A,
    b: B,
    a_axes: &AT1,
    b_axes: &AT2,
) -> Tensor<'graph, F>
where
    A: AsRef<Tensor<'graph, F>> + Copy,
    B: AsRef<Tensor<'graph, F>> + Copy,
    AT1: AsTensor<'graph, F>,
    AT2: AsTensor<'graph, F>,
{
    let a = a.as_ref();
    let g = a.graph();
    // Preprocess
    let pre = &Tensor::builder(g)
        .append_input(a.as_ref(), false)
        .append_input(b.as_ref(), false)
        .append_input(&a_axes.as_tensor(g), false)
        .append_input(&b_axes.as_tensor(g), false)
        .build(dot_ops::TensordotPreprocess);
    let final_shape = nth_tensor(pre, 0);
    let perm_a = nth_tensor(pre, 1);
    let perm_b = nth_tensor(pre, 2);
    let new_shape_a = nth_tensor(pre, 3);
    let new_shape_b = nth_tensor(pre, 4);
    let a_reshaped = reshape(transpose(a, &perm_a), &new_shape_a);
    let b_reshaped = reshape(transpose(b, &perm_b), &new_shape_b);
    // matmul
    let mm = matmul(a_reshaped, b_reshaped);
    reshape(mm, &final_shape)
}
pub fn tensordot < ' graph , A , B , AT1 , AT2 , F : Float > ( a : A , b : B , a_axes : & AT1 , b_axes : & AT2 , ) -> Tensor < ' graph , F > where A : AsRef < Tensor < ' graph , F > > + Copy , B : AsRef < Tensor < ' graph , F > > + Copy , AT1 : AsTensor < ' graph , F > , AT2 : AsTensor < ' graph , F > , { let a = a . as_ref ( ) ; let g = a . graph ( ) ; // Preprocess let pre = & Tensor :: builder ( g ) . append_input ( a . as_ref ( ) , false ) . append_input ( b . as_ref ( ) , false ) . append_input ( & a_axes . as_tensor ( g ) , false ) . append_input ( & b_axes . as_tensor ( g ) , false ) . build ( dot_ops :: TensordotPreprocess ) ; let final_shape = nth_tensor ( pre , 0 ) ; let perm_a = nth_tensor ( pre , 1 ) ; let perm_b = nth_tensor ( pre , 2 ) ; let new_shape_a = nth_tensor ( pre , 3 ) ; let new_shape_b = nth_tensor ( pre , 4 ) ; let a_reshaped = reshape ( transpose ( a , & perm_a ) , & new_shape_a ) ; let b_reshaped = reshape ( transpose ( b , & perm_b ) , & new_shape_b ) ; // matmul let mm = matmul ( a_reshaped , b_reshaped ) ; reshape ( mm , & final_shape ) }
Computes tensor-dot-product (tensor contraction) along specified axes.
Computes tensor - dot - product ( tensor contraction ) along specified axes .
a
A
b
B
a_axes
&AT1
b_axes
&AT2
a
A
b
B
a_axes
&AT1
b_axes
&AT2