0

I'm using Rust 1.65.0 and nalgebra 0.31.3. Following this blog post, I would like to write a generic function to compute roots of polynomials, without using dynamic memory allocation:

use nalgebra::{Complex, Const, DimSub, SMatrix, ToTypenum};

fn poly_roots<const N: usize>(coeffs: [f64; N]) -> [f64; N]
where
    Const<N>: DimSub<Const<1>>,
    Const<N>: ToTypenum,
{
    let mut companion = SMatrix::<f64, N, N>::zeros();
    for i in 0..(N - 1) {
        companion[(i + 1, i)] = 1.;
        companion[(i, N - 1)] = -coeffs[i];
    }
    companion[(N - 1, N - 1)] = -coeffs[N - 1];
    companion
        .complex_eigenvalues()
        .map(|z: Complex<f64>| if z.im == 0. { z.re } else { f64::NAN })
        .into()
}

However, when I try to compile this, I get the following error:

error[E0599]: the method `complex_eigenvalues` exists for struct `Matrix<f64, Const<N>, Const<N>, ArrayStorage<f64, N, N>>`, but its trait bounds were not satisfied
  --> src/lib.rs:15:10
   |
15 |         .complex_eigenvalues()
   |          ^^^^^^^^^^^^^^^^^^^ method cannot be called on `Matrix<f64, Const<N>, Const<N>, ArrayStorage<f64, N, N>>` due to unsatisfied trait bounds
   |
  ::: /Users/samueles/.cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.31.3/src/base/default_allocator.rs:32:1
   |
32 | pub struct DefaultAllocator;
   | ---------------------------
   | |
   | doesn't satisfy `_: nalgebra::allocator::Allocator<f64, <Const<N> as DimSub<Const<1>>>::Output>`
   | doesn't satisfy `_: nalgebra::allocator::Allocator<f64, Const<N>, <Const<N> as DimSub<Const<1>>>::Output>`
   |
   = note: the following trait bounds were not satisfied:
           `DefaultAllocator: nalgebra::allocator::Allocator<f64, Const<N>, <Const<N> as DimSub<Const<1>>>::Output>`
           `DefaultAllocator: nalgebra::allocator::Allocator<f64, <Const<N> as DimSub<Const<1>>>::Output>`

For more information about this error, try `rustc --explain E0599`.

My understanding from that blog post was that the usage of const-generics should allow me to write code like this without "all the DefaultAllocator: Allocator<...> bounds", but that doesn't seem to be the case here. How can I modify the signature of my poly_roots function to get it to compile?

Sam Estep
  • 12,974
  • 2
  • 37
  • 75

0 Answers0