How to preserve DimName Output from MatrixMN.insert_row()?

I am running into a Rust error using nalgebra 0.21 to solve a linear least-squares problem.

I’m adding a row to an MxD to allow for a bias term to create a M+1 x D matrix, and multiplying the resulting matrix by its transpose as part of a least-squares calculation. The problem seems to be that the resulting matrix has no DimName trait implementation for the generic parameter for the number of rows (M+1).

impl<M, N> LinearModel<M, N> where
    M: DimName + DimAdd<U1>,
    N: DimName,
    DefaultAllocator: Allocator<Fxx, M> + Allocator<Fxx, N> +
                      Allocator<Fxx, N, M>,
    Owned<Fxx, N>: Copy,
    Owned<Fxx, N, M>: Copy,
{
    pub fn update_bulk<D: DimName>(&self,
                                   x: &MatrixMN<Fxx, M, D>,
                                   y: &MatrixMN<Fxx, D, N>) -> () where 
        Owned<Fxx, M, D>: Copy,
        DefaultAllocator: Reallocator<Fxx, M, D, DimSum<M, U1>, D> +
            Reallocator<Fxx, DimSum<M, U1>, D, D, DimSum<M, U1>> +
            Allocator<Fxx, D, N> +
            Allocator<Fxx, D, M> + Allocator<Fxx, M, D> + Allocator<Fxx, M, M>
    {
        let x1 = x.insert_row(M::dim(), 1.0); // (M+1 x D)    OK
        let x1t = x1.transpose();             // (D x M+1)    OK
        let xxt = x1 * x1t;                   // (M+1 x M+1)  <- error

        if let Some(xxt1) = xxt.try_inverse() { 
          ....

I get an error

error[E0277]: the trait bound `<M as model::na::DimAdd<model::na::U1>>::Output: model::na::DimName` is not satisfied
  --> src/model.rs:80:22
   |
80 |         let xxt = x1 * x1t;                   // M+1 x M+1
   |                      ^ the trait `model::na::DimName` is not implemented for `<M as model::na::DimAdd<model::na::U1>>::Output`
   |
   = note: required because of the requirements on the impl of `model::na::allocator::Allocator<f64, <M as model::na::DimAdd<model::na::U1>>::Output, <M as model::na::DimAdd<model::na::U1>>::Output>` for `model::na::DefaultAllocator`
help: consider further restricting the associated type
   |
76 |             Allocator<Fxx, D, M> + Allocator<Fxx, M, D> + Allocator<Fxx, M, M>, <M as model::na::DimAdd<model::na::U1>>::Output: model::na::DimName
   |                                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I’m guessing that when I extend M to M+1 in add_row() which uses DimSum<M, U1>, that I lose Output from DimName, but I’m not sure how to update my litany of Allocator traits to include the proper Output implementation.

Thanks for any pointers, advice, wise words, incantations, etc…

Hi!

This kind of errors about DimName not being implemented often happen when you are missing an Allocator<...> bound. In your case x1 * x1t outputs a matrix of dimension M + 1 × M + 1, so you need the bound:

DefaultAllocator: Allocator<Fxx, DimSum<M, U1>, DimSum<M, U1>>

so the compiler can figure out how to allocate it.

1 Like

Fantastic! Thank you.