rustrust-ndarray

Rust ndarray crate dot product: error[E0275]: overflow evaluating the requirement `&ArrayBase<_, _>: Not`


        let layers: &mut Vec<Layer::Layer> = &mut self.Layers;
        let (input, hidden) = layers.split_at_mut(1);
        let I = &input[0];
        let F = &mut hidden[0];

        println!("{}\nShape:{:?}", I.W, I.W.shape());
        println!("{}\nShape:{:?}", F.W, F.W.shape());
        /*
        [[0.01039958, 0.03311491, 0.2649846, 0.014533758, -0.22459972, ..., -0.030018449, -0.0015552044, -0.28607285, -0.40191603, -0.056303382],
        [-0.47217917, -0.45989895, 0.44472742, -0.2978593, -0.12105167, ..., 0.4173746, -0.093189, -0.44422615, -0.28673685, 0.3816806],
        [0.18819237, 0.19896662, 0.3983196, 0.20608664, 0.26259327, ..., -0.38343704, -0.18535256, -0.46597314, 0.08027923, 0.40879965],
        [0.34159064, -0.36455226, 0.06522405, 0.09252155, -0.46043622, ..., 0.24050498, 0.47806084, -0.093515396, -0.17399406, -0.120973706],
        [0.37301958, -0.10888398, 0.4068719, 0.09092343, -0.31563437, ..., -0.4025743, -0.15646517, 0.04115975, 0.29357255, 0.104565024],
        ...,
        [-0.011818051, 0.19975579, 0.45078945, 0.39523375, -0.0041544437, ..., -0.13249898, -0.19197714, 0.18585587, 0.22137606, -0.23492491],
        [0.04481578, -0.45961678, -0.16609538, -0.017008066, -0.44350708, ..., -0.22982013, 0.42763937, 0.13396072, -0.33895278, 0.20609057],
        [0.020810723, 0.15540254, -0.03213215, 0.37126696, 0.37407553, ..., -0.21246314, 0.11485529, -0.29719722, 0.15202522, -0.3234682],
        [-0.3844545, 0.069857955, -0.24911714, -0.13778293, -0.0078908205, ..., 0.45725167, 0.32145667, 0.24182773, -0.45967317, 0.15664446],
        [-0.017565489, -0.25189304, 0.22706962, 0.23143291, -0.23744631, ..., -0.13094687, 0.29178417, -0.22469902, 0.176566, -0.41180527]]
        Shape:[420, 784]
        [[0, 0, 0, 0, 0, ..., 0.08627451, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, ..., 0, 0, 0, 0.015686275, 0.43137255],
        [0.8980392, 0.9764706, 0.98039216, 0.98039216, 0.98039216, ..., 0.95686275, 0.54509807, 0.32156864, 0.02745098, 0],
        [0, 0, 0, 0, 0, ..., 0.49803922, 0.98039216, 0.8509804, 0.14509805, 0],
        [0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0],
        ...,
        [0.9490196, 0.99607843, 0.99607843, 0.99607843, 0.99607843, ..., 0, 0, 0, 0.03529412, 0.54509807],
        [0.98039216, 0.8156863, 0.18039216, 0, 0, ..., 0, 0, 0, 0, 0],
        [0.03137255, 0.30980393, 0.9098039, 0.9019608, 0.48235294, ..., 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, ..., 0.07058824, 0.14901961, 0.19607843, 0.44705883, 0.5019608],
        [0.627451, 0.6666667, 0.54509807, 0.49019608, 0.32156864, ..., 0, 0, 0, 0, 0]]
        Shape:[784, 112800]
         */
        //type of I.W: pub W: ArrayBase<OwnedRepr<f32>, Dim<IxDynImpl>>
        //type of F.W: pub W: ArrayBase<OwnedRepr<f32>, Dim<IxDynImpl>>
        F.Z = F.W.dot(&I.W);

Hi, I am trying to implement a simple neural network in rust (mostly from scratch) using the ndarray crate. I have barely used rust before and this is an exercise more than a real project. I am trying to calculate the dot product between my input layer and the first hidden layer, however I cannot compile this due to:

error[E0275]: overflow evaluating the requirement `&ArrayBase<_, _>: Not`
  --> src\NN\Network.rs:48:19
   |
48 |         F.Z = F.W.dot(&I.W);
   |                   ^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`Rust_EMNIST`)
   = note: required for `&ArrayBase<_, _>` to implement `Not`
   = note: 127 redundant requirements hidden
   = note: required for `&ArrayBase<OwnedRepr<f32>, nd::Dim<IxDynImpl>>` to implement `Not`

I have tried to extended the recursion limit with no luck. I have no idea what the error message even means in this context. I have tried to use ndarray::prelude::*; but that did not change anything (this bit of code is in a local module)


Solution

  • The problem is caused by using ndarray::ArrayD. The dot product is only a valid call for ndarray::Array2 (or lower dimensions) -- even if the ArrayD is of the same size.

    use ndarray::prelude::*;
    fn main() {
        let mat1 = Array2::from_shape_vec((3, 2), vec![3.0; 6]).unwrap();
        let mat2 = Array2::from_shape_vec((2, 3), vec![1.0; 6]).unwrap();
        let dot = mat1.dot(&mat2);
    }
    

    works, while

    use ndarray::prelude::*;
    fn main() {
        let mat1 = ArrayD::from_shape_vec(vec![3, 2], vec![3.0; 6]).unwrap();
        let mat2 = ArrayD::from_shape_vec(vec![2, 3], vec![1.0; 6]).unwrap();
        let dot = mat1.dot(&mat2);
    }
    

    does not