Налгебра: Реализация функции для обобщенного c MatrixMN - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь реализовать функцию exp для обобщенного c квадрата MatrixMN

pub fn exp<N, R>(m: &MatrixMN<N, R, R>, k: usize) -> MatrixMN<N, R, R>
where
    N: Scalar + One + Zero,
    R: DimName + DimNameAdd<R>,
    <R as DimName>::Value: Mul<<R as DimName>::Value>,
    <<R as DimName>::Value as Mul<<R as DimName>::Value>>::Output: generic_array::ArrayLength<N>,
{
    let mut i = MatrixMN::<N, R, R>::identity();
    i.add(&m)
}

Но я продолжаю получать такие ошибки, как это.

error[E0599]: no method named `add` found for struct `nalgebra::base::matrix::Matrix<N, R, R, nalgebra::base::array_storage::ArrayStorage<N, R, R>>` in the current scope
  --> src/state_extrapolation.rs:24:7
   |
24 |     i.add(&m)
   |       ^^^ method not found in `nalgebra::base::matrix::Matrix<N, R, R, nalgebra::base::array_storage::ArrayStorage<N, R, R>>`
   |
   = note: the method `add` exists but the following trait bounds were not satisfied:
           `&mut nalgebra::base::matrix::Matrix<N, R, R, nalgebra::base::array_storage::ArrayStorage<N, R, R>> : nalgebra::base::dimension::DimNameAdd<_>`
           `&nalgebra::base::matrix::Matrix<N, R, R, nalgebra::base::array_storage::ArrayStorage<N, R, R>> : nalgebra::base::dimension::DimNameAdd<_>`
           `nalgebra::base::matrix::Matrix<N, R, R, nalgebra::base::array_storage::ArrayStorage<N, R, R>> : nalgebra::base::dimension::DimNameAdd<_>`

Есть ли лучший способ передачи обобщенных c матриц в функции?

Я также пробовал что-то подобное

pub fn exp2<M>(m: &M, k: usize) -> M
where
    M: nalgebra::base::Matrix<_, _, _, _>,
{
    let mut i = M::identity();

    i.add(&m)
}

Но не могу придумать хорошие черты для M.

1 Ответ

1 голос
/ 27 марта 2020

Легко потеряться в чертах характера, если сделать вещи полностью обобщенными c. Мои советы:

  • Скопируйте подпись блока impl, который реализует аналогичные функции, к вашим, например, строка DefaultAllocator: Allocator<N, R, R> из здесь позволяет избавиться от многих ограничений
  • Вместо Scalar, если это будут числа с плавающей запятой, с которыми вы будете рассчитывать, проще использовать RealField, что дает вам Scalar плюс многие другие полезные свойства (например, One и Zero, необходимые для identity() function)
  • Следуйте ошибкам компилятора - он предложил добавить use std::ops::Add, что и заставило его работать в конце.

Вот код, детская площадка :

use nalgebra::{
    base::allocator::Allocator, DefaultAllocator, DimName, DimNameAdd, MatrixN, RealField,
};
use std::ops::Add;

fn exp<N, R>(m: &MatrixN<N, R>, k: usize) -> MatrixN<N, R>
where
    N: RealField,
    R: DimName + DimNameAdd<R>,
    DefaultAllocator: Allocator<N, R, R>,
{
    let i = MatrixN::<N, R>::identity();
    m.add(i)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...