Cannot infer type for type parameter declared on Trait

I'm fairly new to Rust. I've been recently introduced to the Trait concept which I think I understand. However I run into an issue in my code that I don't understand.

I have 4 traits: Float, DesignMatrix, Targets and Datafit.

pub struct DatasetBase<DM, T>
where
    DM: DesignMatrix,
    T: Targets
{
    pub design_matrix: DM,
    pub targets: T,
}

pub trait DesignMatrix: Sized {
    type Elem;

    fn n_samples(&self) -> usize;
    fn n_features(&self) -> usize;

    fn matrix_type(&self) -> DesignMatrixType;
}

pub trait Targets: Sized {
    type Elem;

    fn n_tasks(&self) -> usize;
}

pub trait Datafit<F, DM, T>
where
    F: Float,
    DM: DesignMatrix<Elem = F>,
    T: Targets<Elem = F>,
{
    fn initialize(&mut self, dataset: &DatasetBase<DM, T>);
    fn Xty(&self) -> ArrayView1<F>;
}

and one implementation:

impl<F, D> Datafit<F, ArrayBase<D, Ix2>, ArrayBase<D, Ix1>> for Quadratic<F>
where
    F: Float,
    D: Data<Elem = F>,
{
    /// Initializes the datafit by pre-computing useful quantities
    fn initialize(&mut self, dataset: &DatasetBase<ArrayBase<D, Ix2>, ArrayBase<D, Ix1>>) {
        let X = dataset.design_matrix;
        let y = dataset.targets;
        self.Xty = X.t().dot(&y);
        let n_samples = F::from(X.shape()[0]).unwrap();
        let lc = X.map_axis(Axis(0), |Xj| Xj.dot(&Xj) / n_samples);
        self.lipschitz = lc;
    }

    // Getter for Xty
    fn Xty(&self) -> ArrayView1<F> {
        self.Xty.view()
    }
}

In a test function, I have the following snippet:

let X = Array2::<f64>::from_shape_vec((2, 3), vec![3.4, 2.1, 2.3, 3.4, -1.2, 0.2]).unwrap();
let y = Array1::<f64>::from_shape_vec(2, vec![-3.4, 2.1]).unwrap();
let dataset = DatasetBase::from((X, y));
let mut df = Quadratic::default();
df.initialize(&dataset);
let res = df.Xty()

However, the compiler throws an error saying cannot infer type for type parameter DM declared on the trait Datafit, and a note: note = type annotations needed, cannot satisfy _: DesignMatrix. I'm lost and I don't know how to solve this error. I don't even know why I have such an error. Any help is appreciated.

EDIT: DatasetBase implements the DesignMatrix and Targets traits.

EDIT2: Here is a playground link with a minimum reproducible code: Rust Playground

Lots of missing context in this question, but I'll give it my best. (It might be helpful to paste the full error message which usually includes inline code.)

Your Datafit trait requires a trait bound DM: DesignMatrix<Elem = F>. The impl has type Datafit<F, ArrayBase<D, Ix2>, ArrayBase<D, Ix1>> which means that ArrayBase<D, Ix2> must implement DesignMatrix<Elem = F>. You mention an implementation on DatasetBase, but this type is only used in a method argument for Datafit, not in the type itself.

Let me add some context. Here is the implementation of DesignMatrix for ArrayBase<D, Ix2>:

impl<F, S: Data<Elem = F>, I: Dimension> DesignMatrix for ArrayBase<S, I> {
    type Elem = F;

    fn n_samples(&self) -> usize {
        self.len_of(Axis(0))
    }

    fn n_features(&self) -> usize {
        self.len_of(Axis(1))
    }

    fn matrix_type(&self) -> DesignMatrixType {
        DesignMatrixType::Dense
    }
}

and here is the implementation block for DatasetBase:

impl<F, D, I> From<(ArrayBase<D, Ix2>, ArrayBase<D, I>)>
    for DatasetBase<ArrayBase<D, Ix2>, ArrayBase<D, I>>
where
    D: Data<Elem = F>,
    I: Dimension,
{
    fn from(data: (ArrayBase<D, Ix2>, ArrayBase<D, I>)) -> Self {
        DatasetBase {
            design_matrix: data.0,
            targets: data.1,
        }
    }
}

If you could provide a link to an full example in the playground (make sure to get a shareable link by clicking Share and then copying that link), it will make it much easier to help you with this. Also it is better to post the whole rustc output when encountering problems, not just the main message, as the ASCII art can contain much more information than VSCode (for example) shows.

1 Like

Here is a playground link. I tried to be as concise as possible.

1 Like