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?