Open
Description
I was porting some code from NumPy, and needed the pinv[1][2] function (Moore-Penrose pseudoinverse). I have started implementing it but have run into some issues making it generic over real and complex numbers.
pub trait Pinv {
type B;
type E;
type C;
fn pinv(&self, rcond: Option<Self::E>) -> Result<Self::B, Error>;
}
pub trait PInvVInto {
type B;
type E;
fn pinv(self, rcond: Option<Self::E>) -> Result<Self::B, Error>;
}
pub trait PInvInplace {
type B;
type E;
fn pinv(&mut self, rcond: Option<Self::E>) -> Result<Self::B, Error>;
}
impl<A, S> Pinv for ArrayBase<S, Ix2>
where
A: Scalar + Lapack + PartialOrd + Zero,
S: Data<Elem = A>,
{
type E = A::Real;
type B = Array2<A>;
type C = Array1<A::Real>;
fn pinv(&self, rconf: Option<Self::E>) -> Result<Self::B, Error> {
let result: (Option<Self::B>, Self::C, Option<Self::B>) =
self.svd(true, true).map_err(|_| Error::SvdFailed)?;
if let (Some(u), s, Some(vt)) = result {
// discard small singular values
let s: Self::C = if let Some(rconf) = rconf {
s.mapv(|v| if v > rconf { v } else { Zero::zero() })
} else {
s
};
let u = u.reversed_axes();
let s = s.insert_axis(Axis(1));
let x1 = s * u;
Ok(&vt.reversed_axes() * x1)
} else {
Err(Error::SvdFailed)
}
}
}
At the moment I am getting this error
error[E0277]: cannot multiply `ndarray::ArrayBase<OwnedRepr<<A as ndarray_linalg::Scalar>::Real>, Dim<[usize; 2]>>` by `ndarray::ArrayBase<OwnedRepr<A>, Dim<[usize; 2]>>`
--> numrs/src/linalg.rs:58:24
|
58 | let x1 = s * u;
| ^ no implementation for `ndarray::ArrayBase<OwnedRepr<<A as ndarray_linalg::Scalar>::Real>, Dim<[usize; 2]>> * ndarray::ArrayBase<OwnedRepr<A>, Dim<[usize; 2]>>`
|
= help: the trait `Mul<ndarray::ArrayBase<OwnedRepr<A>, Dim<[usize; 2]>>>` is not implemented for `ndarray::ArrayBase<OwnedRepr<<A as ndarray_linalg::Scalar>::Real>, Dim<[usize; 2]>>`
help: consider extending the `where` bound, but there might be an alternative better way to express this requirement
|
38 | S: Data<Elem = A>, ndarray::ArrayBase<OwnedRepr<<A as ndarray_linalg::Scalar>::Real>, Dim<[usize; 2]>>: Mul<ndarray::ArrayBase<OwnedRepr<A>, Dim<[usize; 2]>>>
My understanding this is because I am trying to multiple Scalar::Real with a Scalar, but I am not sure how this should be fixed.
Metadata
Metadata
Assignees
Labels
No labels