dimforge / nalgebra

Linear algebra library for Rust.
https://nalgebra.org
Apache License 2.0
4.03k stars 481 forks source link

Is it possible to have a function with arbitrarily sized matricies? #330

Open martindeegan opened 6 years ago

martindeegan commented 6 years ago

I've been trying for a few hours to create a simple generic function for arbitrary matrices, but nothing seems to work. I've been looking at this guide from the documentation.

use na::Dim;
use na::Matrix;

type Matrixd<R, C, S> = Matrix<f64, R, C, S>;

pub fn mult<R: Dim,  C: Dim, MS: Storage<f64, R, C>, VS: Storage<f64, C, U1>>
        (A: Matrixd<R, C, MS>, v:Matrixd<C, U1, VS>) -> Matrixd<C, U1, VS>  {
             A * v
 }

I get the error:

error[E0369]: binary operation `*` cannot be applied to type `na::Matrix<f64, R, C, MS>`
  --> src/lib.rs:21:21
   |
21 |                     A * v
   |                     ^^^^^
   |
   = note: an implementation of `std::ops::Mul` might be missing for `na::Matrix<f64, R, C, MS>`

When trying the alga crate way:

use alga::linear as lin;

pub fn mult<M: lin::Matrix, V: lin::Matrix>
                (A: M, v: V) -> V {
                    A * v
                }

pub fn use_mult() {
    let A: Matrix3<f64> = Matrix3::identity();
    let v: Vector3<f64> = Vector3::x();

    let out = mult(A, v);
}

I get the following errors:

error[E0308]: mismatched types
  --> src/lib.rs:21:25
   |
21 |                     A * v
   |                         ^ expected associated type, found type parameter
   |
   = note: expected type `<M as alga::linear::Matrix>::Row`
              found type `V`

error[E0308]: mismatched types
  --> src/lib.rs:21:21
   |
20 |                 (A: M, v: V) -> V {
   |                                 - expected `V` because of return type
21 |                     A * v
   |                     ^^^^^ expected type parameter, found associated type
   |
   = note: expected type `V`
              found type `<M as alga::linear::Matrix>::Column`

error[E0277]: the trait bound `na::Matrix<f64, na::U3, na::U3, na::MatrixArray<f64, na::U3, na::U3>>: alga::linear::Matrix` is not satisfied
  --> src/lib.rs:28:15
   |
28 |     let out = mult(A, v);
   |               ^^^^ the trait `alga::linear::Matrix` is not implemented for `na::Matrix<f64, na::U3, na::U3, na::MatrixArray<f64, na::U3, na::U3>>`
   |
note: required by `mult`
  --> src/lib.rs:19:1
   |
19 | / pub fn mult<M: lin::Matrix, V: lin::Matrix>
20 | |                 (A: M, v: V) -> V {
21 | |                     A * v
22 | |                 }
   | |_________________^

error[E0277]: the trait bound `na::Matrix<f64, na::U3, na::U1, na::MatrixArray<f64, na::U3, na::U1>>: alga::linear::Matrix` is not satisfied
  --> src/lib.rs:28:15
   |
28 |     let out = mult(A, v);
   |               ^^^^ the trait `alga::linear::Matrix` is not implemented for `na::Matrix<f64, na::U3, na::U1, na::MatrixArray<f64, na::U3, na::U1>>`
   |
note: required by `mult`
  --> src/lib.rs:19:1
   |
19 | / pub fn mult<M: lin::Matrix, V: lin::Matrix>
20 | |                 (A: M, v: V) -> V {
21 | |                     A * v
22 | |                 }
   | |_________________^

The alga traits don't seem to be implemented for nalgebra::Matrix ?

robsmith11 commented 6 years ago

Not sure if it helps for the completely general Matrix type, but for arbitrarily sized MatrixMN types, I use something like this:

pub fn tanh<R:DimName,C:DimName>(x:MatrixMN<f64,R,C>) -> MatrixMN<f64,R,C>
    where DefaultAllocator:Allocator<f64,R,C> {
    x.map(approx_tanh)
}
dhardy commented 5 years ago

The alga traits don't seem to be implemented for nalgebra::Matrix ?

I just wrote a generic function over alga::linear::Matrix... but it seems I can't use this with an nalgebra::MatrixMN type.