Skip to content

Commit a685543

Browse files
committed
Add solveh module (without test)
1 parent bc6c04d commit a685543

File tree

4 files changed

+133
-5
lines changed

4 files changed

+133
-5
lines changed

src/lapack_traits/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ use super::types::*;
2424
pub type Pivot = Vec<i32>;
2525

2626
pub trait LapackScalar
27-
: OperatorNorm_ + QR_ + SVD_ + Solve_ + Cholesky_ + Eigh_ + Triangular_ {
27+
: OperatorNorm_ + QR_ + SVD_ + Solve_ + Solveh_ + Cholesky_ + Eigh_ + Triangular_
28+
{
2829
}
2930

3031
impl LapackScalar for f32 {}

src/lapack_traits/solveh.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ pub trait Solveh_: Sized {
1414
/// Bunch-Kaufman: wrapper of `*sytrf` and `*hetrf`
1515
unsafe fn bk(MatrixLayout, UPLO, a: &mut [Self]) -> Result<Pivot>;
1616
/// Wrapper of `*sytri` and `*hetri`
17-
unsafe fn inv(MatrixLayout, UPLO, a: &mut [Self], &Pivot) -> Result<()>;
17+
unsafe fn invh(MatrixLayout, UPLO, a: &mut [Self], &Pivot) -> Result<()>;
1818
/// Wrapper of `*sytrs` and `*hetrs`
19-
unsafe fn solve(MatrixLayout, UPLO, a: &[Self], &Pivot, b: &mut [Self]) -> Result<()>;
19+
unsafe fn solveh(MatrixLayout, UPLO, a: &[Self], &Pivot, b: &mut [Self]) -> Result<()>;
2020
}
2121

2222
macro_rules! impl_solveh {
@@ -30,13 +30,13 @@ impl Solveh_ for $scalar {
3030
into_result(info, ipiv)
3131
}
3232

33-
unsafe fn inv(l: MatrixLayout, uplo: UPLO, a: &mut [Self], ipiv: &Pivot) -> Result<()> {
33+
unsafe fn invh(l: MatrixLayout, uplo: UPLO, a: &mut [Self], ipiv: &Pivot) -> Result<()> {
3434
let (n, _) = l.size();
3535
let info = $tri(l.lapacke_layout(), uplo as u8, n, a, l.lda(), ipiv);
3636
into_result(info, ())
3737
}
3838

39-
unsafe fn solve(l: MatrixLayout, uplo: UPLO, a: &[Self], ipiv: &Pivot, b: &mut [Self]) -> Result<()> {
39+
unsafe fn solveh(l: MatrixLayout, uplo: UPLO, a: &[Self], ipiv: &Pivot, b: &mut [Self]) -> Result<()> {
4040
let (n, _) = l.size();
4141
let nrhs = 1;
4242
let ldb = 1;

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub mod operator;
4242
pub mod opnorm;
4343
pub mod qr;
4444
pub mod solve;
45+
pub mod solveh;
4546
pub mod svd;
4647
pub mod trace;
4748
pub mod triangular;
@@ -59,6 +60,7 @@ pub use operator::*;
5960
pub use opnorm::*;
6061
pub use qr::*;
6162
pub use solve::*;
63+
pub use solveh::*;
6264
pub use svd::*;
6365
pub use trace::*;
6466
pub use triangular::*;

src/solveh.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//! Solve Hermite/Symmetric linear problems
2+
3+
use ndarray::*;
4+
5+
use super::convert::*;
6+
use super::error::*;
7+
use super::layout::*;
8+
use super::types::*;
9+
10+
pub use lapack_traits::{Pivot, UPLO};
11+
12+
pub struct FactorizedH<S: Data> {
13+
pub a: ArrayBase<S, Ix2>,
14+
pub ipiv: Pivot,
15+
}
16+
17+
impl<A, S> FactorizedH<S>
18+
where
19+
A: Scalar,
20+
S: Data<Elem = A>,
21+
{
22+
pub fn solveh<Sb>(&self, mut rhs: ArrayBase<Sb, Ix1>) -> Result<ArrayBase<Sb, Ix1>>
23+
where
24+
Sb: DataMut<Elem = A>,
25+
{
26+
unsafe {
27+
A::solveh(
28+
self.a.square_layout()?,
29+
UPLO::Upper,
30+
self.a.as_allocated()?,
31+
&self.ipiv,
32+
rhs.as_slice_mut().unwrap(),
33+
)?
34+
};
35+
Ok(rhs)
36+
}
37+
}
38+
39+
impl<A, S> FactorizedH<S>
40+
where
41+
A: Scalar,
42+
S: DataMut<Elem = A>,
43+
{
44+
pub fn into_inverseh(mut self) -> Result<ArrayBase<S, Ix2>> {
45+
unsafe {
46+
A::invh(
47+
self.a.square_layout()?,
48+
UPLO::Upper,
49+
self.a.as_allocated_mut()?,
50+
&self.ipiv,
51+
)?
52+
};
53+
Ok(self.a)
54+
}
55+
}
56+
57+
pub trait FactorizeH<S: Data> {
58+
fn factorizeh(&self) -> Result<FactorizedH<S>>;
59+
}
60+
61+
pub trait FactorizeHInto<S: Data> {
62+
fn factorizeh_into(self) -> Result<FactorizedH<S>>;
63+
}
64+
65+
impl<A, S> FactorizeHInto<S> for ArrayBase<S, Ix2>
66+
where
67+
A: Scalar,
68+
S: DataMut<Elem = A>,
69+
{
70+
fn factorizeh_into(mut self) -> Result<FactorizedH<S>> {
71+
let ipiv = unsafe { A::bk(self.layout()?, UPLO::Upper, self.as_allocated_mut()?)? };
72+
Ok(FactorizedH {
73+
a: self,
74+
ipiv: ipiv,
75+
})
76+
}
77+
}
78+
79+
impl<A, Si> FactorizeH<OwnedRepr<A>> for ArrayBase<Si, Ix2>
80+
where
81+
A: Scalar,
82+
Si: Data<Elem = A>,
83+
{
84+
fn factorizeh(&self) -> Result<FactorizedH<OwnedRepr<A>>> {
85+
let mut a: Array2<A> = replicate(self);
86+
let ipiv = unsafe { A::bk(a.layout()?, UPLO::Upper, a.as_allocated_mut()?)? };
87+
Ok(FactorizedH { a: a, ipiv: ipiv })
88+
}
89+
}
90+
91+
pub trait InverseH {
92+
type Output;
93+
fn invh(&self) -> Result<Self::Output>;
94+
}
95+
96+
pub trait InverseHInto {
97+
type Output;
98+
fn invh_into(self) -> Result<Self::Output>;
99+
}
100+
101+
impl<A, S> InverseHInto for ArrayBase<S, Ix2>
102+
where
103+
A: Scalar,
104+
S: DataMut<Elem = A>,
105+
{
106+
type Output = Self;
107+
108+
fn invh_into(self) -> Result<Self::Output> {
109+
let f = self.factorizeh_into()?;
110+
f.into_inverseh()
111+
}
112+
}
113+
114+
impl<A, Si> InverseH for ArrayBase<Si, Ix2>
115+
where
116+
A: Scalar,
117+
Si: Data<Elem = A>,
118+
{
119+
type Output = Array2<A>;
120+
121+
fn invh(&self) -> Result<Self::Output> {
122+
let f = self.factorizeh()?;
123+
f.into_inverseh()
124+
}
125+
}

0 commit comments

Comments
 (0)