Skip to content

Commit 6a35654

Browse files
committed
RcondTridiagonalWork
1 parent a8550c2 commit 6a35654

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

lax/src/tridiagonal/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
//! for tridiagonal matrix
33
44
mod matrix;
5+
mod rcond;
56
mod solve;
67

78
pub use matrix::*;
9+
pub use rcond::*;
810
pub use solve::*;
911

1012
use crate::{error::*, layout::*, *};

lax/src/tridiagonal/rcond.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use crate::*;
2+
use cauchy::*;
3+
use num_traits::Zero;
4+
5+
pub struct RcondTridiagonalWork<T: Scalar> {
6+
pub work: Vec<MaybeUninit<T>>,
7+
pub iwork: Option<Vec<MaybeUninit<i32>>>,
8+
}
9+
10+
pub trait RcondTridiagonalWorkImpl {
11+
type Elem: Scalar;
12+
fn new(layout: MatrixLayout) -> Self;
13+
fn calc(
14+
&mut self,
15+
lu: &LUFactorizedTridiagonal<Self::Elem>,
16+
) -> Result<<Self::Elem as Scalar>::Real>;
17+
}
18+
19+
macro_rules! impl_rcond_tridiagonal_work_c {
20+
($c:ty, $gtcon:path) => {
21+
impl RcondTridiagonalWorkImpl for RcondTridiagonalWork<$c> {
22+
type Elem = $c;
23+
24+
fn new(layout: MatrixLayout) -> Self {
25+
let (n, _) = layout.size();
26+
let work = vec_uninit(2 * n as usize);
27+
RcondTridiagonalWork { work, iwork: None }
28+
}
29+
30+
fn calc(
31+
&mut self,
32+
lu: &LUFactorizedTridiagonal<Self::Elem>,
33+
) -> Result<<Self::Elem as Scalar>::Real> {
34+
let (n, _) = lu.a.l.size();
35+
let ipiv = &lu.ipiv;
36+
let mut rcond = <Self::Elem as Scalar>::Real::zero();
37+
let mut info = 0;
38+
unsafe {
39+
$gtcon(
40+
NormType::One.as_ptr(),
41+
&n,
42+
AsPtr::as_ptr(&lu.a.dl),
43+
AsPtr::as_ptr(&lu.a.d),
44+
AsPtr::as_ptr(&lu.a.du),
45+
AsPtr::as_ptr(&lu.du2),
46+
ipiv.as_ptr(),
47+
&lu.a_opnorm_one,
48+
&mut rcond,
49+
AsPtr::as_mut_ptr(&mut self.work),
50+
&mut info,
51+
);
52+
}
53+
info.as_lapack_result()?;
54+
Ok(rcond)
55+
}
56+
}
57+
};
58+
}
59+
60+
impl_rcond_tridiagonal_work_c!(c64, lapack_sys::zgtcon_);
61+
impl_rcond_tridiagonal_work_c!(c32, lapack_sys::cgtcon_);
62+
63+
macro_rules! impl_rcond_tridiagonal_work_r {
64+
($c:ty, $gtcon:path) => {
65+
impl RcondTridiagonalWorkImpl for RcondTridiagonalWork<$c> {
66+
type Elem = $c;
67+
68+
fn new(layout: MatrixLayout) -> Self {
69+
let (n, _) = layout.size();
70+
let work = vec_uninit(2 * n as usize);
71+
let iwork = vec_uninit(n as usize);
72+
RcondTridiagonalWork {
73+
work,
74+
iwork: Some(iwork),
75+
}
76+
}
77+
78+
fn calc(
79+
&mut self,
80+
lu: &LUFactorizedTridiagonal<Self::Elem>,
81+
) -> Result<<Self::Elem as Scalar>::Real> {
82+
let (n, _) = lu.a.l.size();
83+
let mut rcond = <Self::Elem as Scalar>::Real::zero();
84+
let mut info = 0;
85+
unsafe {
86+
$gtcon(
87+
NormType::One.as_ptr(),
88+
&n,
89+
AsPtr::as_ptr(&lu.a.dl),
90+
AsPtr::as_ptr(&lu.a.d),
91+
AsPtr::as_ptr(&lu.a.du),
92+
AsPtr::as_ptr(&lu.du2),
93+
AsPtr::as_ptr(&lu.ipiv),
94+
&lu.a_opnorm_one,
95+
&mut rcond,
96+
AsPtr::as_mut_ptr(&mut self.work),
97+
AsPtr::as_mut_ptr(self.iwork.as_mut().unwrap()),
98+
&mut info,
99+
);
100+
}
101+
info.as_lapack_result()?;
102+
Ok(rcond)
103+
}
104+
}
105+
};
106+
}
107+
108+
impl_rcond_tridiagonal_work_r!(f64, lapack_sys::dgtcon_);
109+
impl_rcond_tridiagonal_work_r!(f32, lapack_sys::sgtcon_);

0 commit comments

Comments
 (0)