pub fn inner(&'a self, other: &'a Self) -> Option<T> {
        match (&self.shape, &other.shape) {
            // scalar * scalar
            (Shape::Scalar(_), Shape::Scalar(_)) => {
                return self
                    .values
                    .get(0)
                    .and_then(|a| other.values.get(0).map(|b| *a * *b))
            }
            // multiply the internal array with the scalar and sum it
            (Shape::Scalar(_), Shape::Matrix([_, _]))
            | (Shape::Scalar(_), Shape::Tensor(_))
            | (Shape::Scalar(_), Shape::Vector(_)) => {
                return self.values.get(0).map(|a| {
                    other
                        .values
                        .iter()
                        .fold(T::default(), |res, b| res + (*a * *b))
                })
            }
            // multiply the internal array with the scalar and sum it
            (Shape::Vector(_), Shape::Scalar(_))
            | (Shape::Matrix([_, _]), Shape::Scalar(_))
            | (Shape::Tensor(_), Shape::Scalar(_)) => {
                return other.values.get(0).map(|a| {
                    self.values
                        .iter()
                        .fold(T::default(), |res, b| res + (*a * *b))
                })
            }

            // ordinary inner-product
            (Shape::Vector(_), Shape::Vector(_)) => {
                let val = self
                    .values
                    .iter()
                    .zip(other.values.iter())
                    .map(|(a, b)| *a * *b)
                    .fold(Default::default(), |a: T, b| a + b);
                return Some(val);
            }

            // sum over the rows, vector products
            (Shape::Matrix([c, _]), Shape::Vector([n]))
            | (Shape::Vector([n]), Shape::Matrix([c, _])) => {
                if *c != *n {
                    return None;
                }
            }

            (Shape::Tensor(shape), Shape::Vector([n]))
            | (Shape::Vector([n]), Shape::Tensor(shape)) => {
                if *shape.last()? != *n {
                    return None;
                }
            }

            // Frobenius inner product
            //
            (Shape::Matrix([c1, r1]), Shape::Matrix([c2, r2])) => {
                if c1 != c2 || r1 != r2 {
                    return None;
                }
            }

            // Frobenius inner product for nd arrays
            //
            (Shape::Matrix([c, r]), Shape::Tensor(s))
            | (Shape::Tensor(s), Shape::Matrix([c, r])) => {
                if s.last()? != r {
                    return None;
                }
                let num_rows: u32 = s[..s.len() - 1].iter().product();
                if num_rows != *c {
                    return None;
                }
            }
            (Shape::Tensor(sa), Shape::Tensor(sb)) => {
                if sa.last()? != sb.last()? {
                    // row size mismatch
                    return None;
                }
                if self.values.len() != other.values.len() {
                    // number of rows mismatch
                    return None;
                }
            }
        }

        let res = other
            .iter_rows()
            .map(|col| {
                // dot product result
                self.values
                    .iter()
                    .zip(col.iter())
                    .map(|(a, b)| *a * *b)
                    .fold(T::default(), |a, b| a + b)
            })
            // sum over the dot product result vector
            .fold(T::default(), |a, b| a + b);
        Some(res)
    }
/// Ordinary inner product of vectors for 1-D arrays (without complex conjugation),
/// in higher dimensions a sum product over the last axes.
///
/// Returns None if the shapes are invalid
Ordinary inner product of vectors for 1-D arrays (without complex conjugation),
in higher dimensions a sum product over the last axes.

Returns None if the shapes are invalid
Ordinary inner product of vectors for 1 - D arrays ( without complex conjugation ) in higher dimensions a sum product over the last axes . Returns None if the shapes are invalid
pub fn inner(&'a self, other: &'a Self) -> Option<T> {
        match (&self.shape, &other.shape) {
            // scalar * scalar
            (Shape::Scalar(_), Shape::Scalar(_)) => {
                return self
                    .values
                    .get(0)
                    .and_then(|a| other.values.get(0).map(|b| *a * *b))
            }
            // multiply the internal array with the scalar and sum it
            (Shape::Scalar(_), Shape::Matrix([_, _]))
            | (Shape::Scalar(_), Shape::Tensor(_))
            | (Shape::Scalar(_), Shape::Vector(_)) => {
                return self.values.get(0).map(|a| {
                    other
                        .values
                        .iter()
                        .fold(T::default(), |res, b| res + (*a * *b))
                })
            }
            // multiply the internal array with the scalar and sum it
            (Shape::Vector(_), Shape::Scalar(_))
            | (Shape::Matrix([_, _]), Shape::Scalar(_))
            | (Shape::Tensor(_), Shape::Scalar(_)) => {
                return other.values.get(0).map(|a| {
                    self.values
                        .iter()
                        .fold(T::default(), |res, b| res + (*a * *b))
                })
            }
            // ordinary inner-product
            (Shape::Vector(_), Shape::Vector(_)) => {
                let val = self
                    .values
                    .iter()
                    .zip(other.values.iter())
                    .map(|(a, b)| *a * *b)
                    .fold(Default::default(), |a: T, b| a + b);
                return Some(val);
            }
            // sum over the rows, vector products
            (Shape::Matrix([c, _]), Shape::Vector([n]))
            | (Shape::Vector([n]), Shape::Matrix([c, _])) => {
                if *c != *n {
                    return None;
                }
            }
            (Shape::Tensor(shape), Shape::Vector([n]))
            | (Shape::Vector([n]), Shape::Tensor(shape)) => {
                if *shape.last()? != *n {
                    return None;
                }
            }
            // Frobenius inner product
            //
            (Shape::Matrix([c1, r1]), Shape::Matrix([c2, r2])) => {
                if c1 != c2 || r1 != r2 {
                    return None;
                }
            }
            // Frobenius inner product for nd arrays
            //
            (Shape::Matrix([c, r]), Shape::Tensor(s))
            | (Shape::Tensor(s), Shape::Matrix([c, r])) => {
                if s.last()? != r {
                    return None;
                }
                let num_rows: u32 = s[..s.len() - 1].iter().product();
                if num_rows != *c {
                    return None;
                }
            }
            (Shape::Tensor(sa), Shape::Tensor(sb)) => {
                if sa.last()? != sb.last()? {
                    // row size mismatch
                    return None;
                }
                if self.values.len() != other.values.len() {
                    // number of rows mismatch
                    return None;
                }
            }
        }
        let res = other
            .iter_rows()
            .map(|col| {
                // dot product result
                self.values
                    .iter()
                    .zip(col.iter())
                    .map(|(a, b)| *a * *b)
                    .fold(T::default(), |a, b| a + b)
            })
            // sum over the dot product result vector
            .fold(T::default(), |a, b| a + b);
        Some(res)
    }
pub fn inner ( & ' a self , other : & ' a Self ) -> Option < T > { match ( & self . shape , & other . shape ) { // scalar * scalar ( Shape :: Scalar ( _ ) , Shape :: Scalar ( _ ) ) => { return self . values . get ( 0 ) . and_then ( | a | other . values . get ( 0 ) . map ( | b | * a * * b ) ) } // multiply the internal array with the scalar and sum it ( Shape :: Scalar ( _ ) , Shape :: Matrix ( [ _ , _ ] ) ) | ( Shape :: Scalar ( _ ) , Shape :: Tensor ( _ ) ) | ( Shape :: Scalar ( _ ) , Shape :: Vector ( _ ) ) => { return self . values . get ( 0 ) . map ( | a | { other . values . iter ( ) . fold ( T :: default ( ) , | res , b | res + ( * a * * b ) ) } ) } // multiply the internal array with the scalar and sum it ( Shape :: Vector ( _ ) , Shape :: Scalar ( _ ) ) | ( Shape :: Matrix ( [ _ , _ ] ) , Shape :: Scalar ( _ ) ) | ( Shape :: Tensor ( _ ) , Shape :: Scalar ( _ ) ) => { return other . values . get ( 0 ) . map ( | a | { self . values . iter ( ) . fold ( T :: default ( ) , | res , b | res + ( * a * * b ) ) } ) } // ordinary inner-product ( Shape :: Vector ( _ ) , Shape :: Vector ( _ ) ) => { let val = self . values . iter ( ) . zip ( other . values . iter ( ) ) . map ( | ( a , b ) | * a * * b ) . fold ( Default :: default ( ) , | a : T , b | a + b ) ; return Some ( val ) ; } // sum over the rows, vector products ( Shape :: Matrix ( [ c , _ ] ) , Shape :: Vector ( [ n ] ) ) | ( Shape :: Vector ( [ n ] ) , Shape :: Matrix ( [ c , _ ] ) ) => { if * c != * n { return None ; } } ( Shape :: Tensor ( shape ) , Shape :: Vector ( [ n ] ) ) | ( Shape :: Vector ( [ n ] ) , Shape :: Tensor ( shape ) ) => { if * shape . last ( ) ? != * n { return None ; } } // Frobenius inner product // ( Shape :: Matrix ( [ c1 , r1 ] ) , Shape :: Matrix ( [ c2 , r2 ] ) ) => { if c1 != c2 || r1 != r2 { return None ; } } // Frobenius inner product for nd arrays // ( Shape :: Matrix ( [ c , r ] ) , Shape :: Tensor ( s ) ) | ( Shape :: Tensor ( s ) , Shape :: Matrix ( [ c , r ] ) ) => { if s . last ( ) ? != r { return None ; } let num_rows : u32 = s [ .. s . len ( ) - 1 ] . iter ( ) . product ( ) ; if num_rows != * c { return None ; } } ( Shape :: Tensor ( sa ) , Shape :: Tensor ( sb ) ) => { if sa . last ( ) ? != sb . last ( ) ? { // row size mismatch return None ; } if self . values . len ( ) != other . values . len ( ) { // number of rows mismatch return None ; } } } let res = other . iter_rows ( ) . map ( | col | { // dot product result self . values . iter ( ) . zip ( col . iter ( ) ) . map ( | ( a , b ) | * a * * b ) . fold ( T :: default ( ) , | a , b | a + b ) } ) // sum over the dot product result vector . fold ( T :: default ( ) , | a , b | a + b ) ; Some ( res ) }
Ordinary inner product of vectors for 1-D arrays (without complex conjugation),
in higher dimensions a sum product over the last axes.
Ordinary inner product of vectors for 1 - D arrays ( without complex conjugation ) in higher dimensions a sum product over the last axes .
&'a self
other
&'a Self