Selva
Selva

Reputation: 1153

How to do dot product in Rust using ndarray?

I have a vector, I reshaped it to 2D array using ndarray crate. Now I wanted to do a dot product with a column vec. An example,

use ndarray::*;

pub fn main() {

    let vec1 = //Read from file
    let vec2 = //Read from file
    let mat = Array2::from_shape_vec((row, cols), vec1).unwrap();
    let final_mat = mat.dot(&vec2);
}

I get below error,

the trait `ndarray::linalg::impl_linalg::Dot<std::vec::Vec<f32>>` is not implemented for 
`ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i16>, ndarray::dimension::dim::Dim<[usize; 2]>>`

Upvotes: 2

Views: 2157

Answers (1)

Mac O&#39;Brien
Mac O&#39;Brien

Reputation: 2907

The error has all the information you need: the trait Dot<Vec<f32>>, which represents the ability to call the .dot() method with an argument of type &Vec<f32>, is not implemented for Array2<i16>.

You need to convert vec2 to a type T for which Array2<i16> implements Dot<T>.

According to the documentation for the Dot trait:

impl<A, S, S2> Dot<ArrayBase<S2, Dim<[usize; 1]>>> for ArrayBase<S, Ix2> where
    S: Data<Elem = A>,
    S2: Data<Elem = A>,
    A: LinalgScalar, 

Which, with the fancy types simplified, means that Array2<T> implements Dot<Array1<T>>. This also means that the element types of the two arrays need to be the same, but at the moment vec1 consists of i16s and vec2 consists of f32s.

Solution: convert vec2 to an Array1 and make the elements of vec1 f32s.

use ndarray::{Array1, Array2};

fn main(){
    let vec1 = // read from file, converting i16s to f32s
    let vec2 = // read from file
    let mat = Array2::from_shape_vec((row, cols), vec1).unwrap();
    let col_vec = Array1::from(vec2);
    let final_mat = mat.dot(&col_vec);
}

Upvotes: 2

Related Questions