Hi there,
I’m trying to implement a trait on a trait, and am facing an upward battle with the allocator implementations. I am effectively trying to implement this test at a generalized level. I think I’m covering every possible case of allocators that my function would need, and yet, I get the following error (code is below).
Any hint is appreciated as I’ve hit a total roadblock and have been stalled for about ten days now.
Many thanks
> error[E0277]: cannot multiply `typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>` to `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value`
> --> src/od/mod.rs:96:5
> |
> 96 | / fn gradient(&self, t: f64, state: &VectorN<f64, Self::StateSize>) -> MatrixMN<f64, Self::StateSize, Self::StateSize>
> 97 | | where
> 98 | | DefaultAllocator: Allocator<Dual<f64>, Self::StateSize>
> 99 | | + Allocator<Dual<f64>, Self::StateSize, Self::StateSize>
> ... |
> 108 | | grad
> 109 | | }
> | |_____^ no implementation for `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value * typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>`
> |
> = help: the trait `std::ops::Mul<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>>` is not implemented for `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value`
> = help: consider adding a `where <<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value: std::ops::Mul<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>>` bound
> = note: required because of the requirements on the impl of `propagators::na::allocator::Allocator<od::dual_num::Dual<f64>, <T as od::AutoDiff>::HyperStateSize>` for `propagators::na::DefaultAllocator`
> = note: the requirement `propagators::na::DefaultAllocator: propagators::na::allocator::Allocator<od::dual_num::Dual<f64>, <T as od::AutoDiff>::HyperStateSize>` appears on the impl method but not on the corresponding trait method
>
> error[E0277]: cannot multiply `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value` to `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value`
> --> src/od/mod.rs:96:5
> |
> 96 | / fn gradient(&self, t: f64, state: &VectorN<f64, Self::StateSize>) -> MatrixMN<f64, Self::StateSize, Self::StateSize>
> 97 | | where
> 98 | | DefaultAllocator: Allocator<Dual<f64>, Self::StateSize>
> 99 | | + Allocator<Dual<f64>, Self::StateSize, Self::StateSize>
> ... |
> 108 | | grad
> 109 | | }
> | |_____^ no implementation for `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value * <<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value`
> |
> = help: the trait `std::ops::Mul` is not implemented for `<<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value`
> = help: consider adding a `where <<T as od::AutoDiff>::HyperStateSize as propagators::na::DimName>::Value: std::ops::Mul` bound
> = note: required because of the requirements on the impl of `propagators::na::allocator::Allocator<od::dual_num::Dual<f64>, <T as od::AutoDiff>::HyperStateSize, <T as od::AutoDiff>::HyperStateSize>` for `propagators::na::DefaultAllocator`
> = note: the requirement `propagators::na::DefaultAllocator: propagators::na::allocator::Allocator<od::dual_num::Dual<f64>, <T as od::AutoDiff>::HyperStateSize, <T as od::AutoDiff>::HyperStateSize>` appears on the impl method but not on the corresponding trait method
>
> error: aborting due to 2 previous errors
>
> For more information about this error, try `rustc --explain E0277`.
> error: Could not compile `nyx-space`.
Here is the relevant code:
extern crate dual_num;
extern crate hifitime;
extern crate nalgebra as na;
extern crate serde;
use self::dual_num::{partials_t, Dual};
use self::hifitime::instant::Instant;
use self::na::allocator::Allocator;
use self::na::{DefaultAllocator, DimName, MatrixMN, VectorN};
use celestia::{CoordinateFrame, State};
/// Provides the Kalman filters. The [examples](https://github.com/ChristopherRabotin/nyx/tree/master/examples) folder may help in the setup.
pub mod kalman;
/// Provides a range and range rate measuring models.
pub mod ranging;
/// A trait container to specify that given dynamics support linearization, and can be used for state transition matrix computation.
///
/// This trait will likely be made obsolete after the implementation of [#32](https://github.com/ChristopherRabotin/nyx/issues/32).
pub trait Linearization
where
Self: Sized,
{
/// Defines the state size of the estimated state
type StateSize: DimName;
/// Defines the gradient of the equations of motion for these dynamics.
fn gradient(&self, t: f64, state: &VectorN<f64, Self::StateSize>) -> MatrixMN<f64, Self::StateSize, Self::StateSize>
where
DefaultAllocator: Allocator<f64, Self::StateSize> + Allocator<f64, Self::StateSize, Self::StateSize>;
}
/// A trait defining a measurement of size `MeasurementSize`
pub trait Measurement
where
Self: Sized,
DefaultAllocator: Allocator<f64, Self::MeasurementSize> + Allocator<f64, Self::MeasurementSize, Self::StateSize>,
{
/// Defines the state size of the estimated state
type StateSize: DimName;
/// Defines how much data is measured. For example, if measuring range and range rate, this should be of size 2 (nalgebra::U2).
type MeasurementSize: DimName;
/// Computes a new measurement from the provided information.
fn new<F: CoordinateFrame>(
dt: Instant,
tx: State<F>,
rx: State<F>,
obs: VectorN<f64, Self::MeasurementSize>,
visible: bool,
) -> Self;
/// Returns the measurement/observation as a vector.
fn observation(&self) -> &VectorN<f64, Self::MeasurementSize>
where
DefaultAllocator: Allocator<f64, Self::MeasurementSize>;
/// Returns the measurement sensitivity (often referred to as H tilde).
fn sensitivity(&self) -> &MatrixMN<f64, Self::MeasurementSize, Self::StateSize>
where
DefaultAllocator: Allocator<f64, Self::StateSize, Self::MeasurementSize>;
/// Returns whether the transmitter and receiver where in line of sight.
fn visible(&self) -> bool;
/// Returns the time at which the measurement was performed.
fn at(&self) -> Instant;
}
/// A trait container to specify that given dynamics support linearization, and can be used for state transition matrix computation.
///
/// This trait will likely be made obsolete after the implementation of [#32](https://github.com/ChristopherRabotin/nyx/issues/32).
pub trait AutoDiff
where
Self: Sized,
{
/// Defines the state size of the estimated state
type HyperStateSize: DimName;
/// Defines the equations of motion for Dual numbers for these dynamics.
fn dual_eom(
&self,
t: f64,
state: &MatrixMN<Dual<f64>, Self::HyperStateSize, Self::HyperStateSize>,
) -> MatrixMN<Dual<f64>, Self::HyperStateSize, Self::HyperStateSize>
where
DefaultAllocator: Allocator<Dual<f64>, Self::HyperStateSize>
+ Allocator<Dual<f64>, Self::HyperStateSize, Self::HyperStateSize>
+ Allocator<f64, Self::HyperStateSize>
+ Allocator<f64, Self::HyperStateSize, Self::HyperStateSize>;
}
impl<T: AutoDiff> Linearization for T {
type StateSize = T::HyperStateSize;
fn gradient(&self, t: f64, state: &VectorN<f64, Self::StateSize>) -> MatrixMN<f64, Self::StateSize, Self::StateSize>
where
DefaultAllocator: Allocator<Dual<f64>, Self::StateSize>
+ Allocator<Dual<f64>, Self::StateSize, Self::StateSize>
+ Allocator<f64, Self::StateSize>
+ Allocator<f64, Self::StateSize, Self::StateSize>
+ Allocator<Dual<f64>, T::HyperStateSize>
+ Allocator<Dual<f64>, T::HyperStateSize, T::HyperStateSize>
+ Allocator<f64, T::HyperStateSize>
+ Allocator<f64, T::HyperStateSize, T::HyperStateSize>
{
let (_, grad) = partials_t(t, *state, Self::dual_eom);
grad
}
}