Help understanding trait bounds/ required allocators

The following function (simplified to absurdity) produces the below errors:

fn do_stuff<D, S, S2>( matrix_a: SquareMatrix<f64, D, S>, b: Vector<f64, D, S2>, max_iteration: usize) -> VectorN<f64, D>
    where
        D: Dim,
        S: Storage<f64, D, D>,
        S2: Storage<f64, D, U1>,
        DefaultAllocator: Allocator<f64, D, U1>   {
    let mut matrix_q = DMatrix::<f64>::zeros(max_iteration + 1, max_iteration + 1);
    matrix_q.set_column(matrix_q.ncols(), &b);
    let matrix_m = DMatrix::identity(max_iteration + 1, max_iteration + 1) - matrix_q;
    let y_i =matrix_m * b;
    matrix_q * y_i
}
error[E0277]: the trait bound `D: nalgebra::base::dimension::DimName` is not satisfied
   --> src\lin_sys.rs:120:43
    |
120 |     matrix_q.set_column(matrix_q.ncols(), &b);
    |                                           ^^ the trait `nalgebra::base::dimension::DimName` is not implemented for `D`
    |
    = help: consider adding a `where D: nalgebra::base::dimension::DimName` bound
    = note: required because of the requirements on the impl of `nalgebra::base::constraint::SameNumberOfRows<nalgebra::base::dimension::Dynamic, D>` for `nalgebra::base::constraint::ShapeConstraint`

error[E0277]: the trait bound `D: nalgebra::base::dimension::DimName` is not satisfied
   --> src\lin_sys.rs:122:23
    |
122 |     let y_i =matrix_m * b;
    |                       ^ the trait `nalgebra::base::dimension::DimName` is not implemented for `D`
    |
    = help: consider adding a `where D: nalgebra::base::dimension::DimName` bound
    = note: required because of the requirements on the impl of `nalgebra::base::constraint::DimEq<nalgebra::base::dimension::Dynamic, D>` for `nalgebra::base::constraint::ShapeConstraint`
    = note: required because of the requirements on the impl of `nalgebra::base::constraint::AreMultipliable<nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic, D, nalgebra::base::dimension::U1>` for `nalgebra::base::constraint::ShapeConstraint`
    = note: required because of the requirements on the impl of `std::ops::Mul<nalgebra::base::matrix::Matrix<f64, D, nalgebra::base::dimension::U1, S2>>` for `nalgebra::base::matrix::Matrix<f64, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic, nalgebra::base::vec_storage::VecStorage<f64, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic>>`

error[E0308]: mismatched types
   --> src\lin_sys.rs:123:5
    |
113 | fn do_stuff<D, S, S2>( matrix_a: SquareMatrix<f64, D, S>, b: Vector<f64, D, S2>, max_iteration: usize) -> VectorN<f64, D>
    |                                                                                                           --------------- expected `nalgebra::base::matrix::Matrix<f64, D, nalgebra::base::dimension::U1, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, D>>::Buffer>` because of return type
...
123 |     matrix_q * y_i
    |     ^^^^^^^^^^^^^^ expected type parameter, found struct `nalgebra::base::dimension::Dynamic`
    |
    = note: expected type `nalgebra::base::matrix::Matrix<_, D, _, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, D>>::Buffer>`
               found type `nalgebra::base::matrix::Matrix<_, nalgebra::base::dimension::Dynamic, _, nalgebra::base::vec_storage::VecStorage<f64, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::U1>>`
    = help: type parameters must be constrained to match other types
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

From topic 413 I suppose this is related to missing DefaultAllocator bounds, but I don’t understand how to tell, which Allocator I need to require. How would I approach analyzing the required Allocator from the error texts?

Thank you!

I might be mistaken here, as I only deal with statically allocated matrices, but I always use where D: DimName instead of where D: Dim.

Further, my understanding is that a statically allocated matrix is more efficient than a dynamically allocated one. Hence, unless your matrix is going to change shapes at runtime, a statically allocated one (e.g. MatrixMN or MatrixN) is preferable. You can configure the size of that matrix by typing the function call just as you do above.

Thanks @ChrisR. If my use case allowed for statically allocated matrices I would clear prefer them. But my use case is interactive and thus the user (unknowingly) creates content and length of matrices. They cannot be known at compile time.