Skip to content

Commit 09f9226

Browse files
committed
Add RcondWork
1 parent acd7858 commit 09f9226

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

lax/src/rcond.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,125 @@ use crate::{error::*, layout::MatrixLayout, *};
22
use cauchy::*;
33
use num_traits::Zero;
44

5+
pub struct RcondWork<T: Scalar> {
6+
pub layout: MatrixLayout,
7+
pub work: Vec<MaybeUninit<T>>,
8+
pub rwork: Option<Vec<MaybeUninit<T::Real>>>,
9+
pub iwork: Option<Vec<MaybeUninit<i32>>>,
10+
}
11+
12+
pub trait RcondWorkImpl {
13+
type Elem: Scalar;
14+
fn new(l: MatrixLayout) -> Self;
15+
fn calc(
16+
&mut self,
17+
a: &[Self::Elem],
18+
anorm: <Self::Elem as Scalar>::Real,
19+
) -> Result<<Self::Elem as Scalar>::Real>;
20+
}
21+
22+
macro_rules! impl_rcond_work_c {
23+
($c:ty, $con:path) => {
24+
impl RcondWorkImpl for RcondWork<$c> {
25+
type Elem = $c;
26+
27+
fn new(layout: MatrixLayout) -> Self {
28+
let (n, _) = layout.size();
29+
let work = vec_uninit(2 * n as usize);
30+
let rwork = vec_uninit(2 * n as usize);
31+
RcondWork {
32+
layout,
33+
work,
34+
rwork: Some(rwork),
35+
iwork: None,
36+
}
37+
}
38+
39+
fn calc(
40+
&mut self,
41+
a: &[Self::Elem],
42+
anorm: <Self::Elem as Scalar>::Real,
43+
) -> Result<<Self::Elem as Scalar>::Real> {
44+
let (n, _) = self.layout.size();
45+
let mut rcond = <Self::Elem as Scalar>::Real::zero();
46+
let mut info = 0;
47+
let norm_type = match self.layout {
48+
MatrixLayout::C { .. } => NormType::Infinity,
49+
MatrixLayout::F { .. } => NormType::One,
50+
};
51+
unsafe {
52+
$con(
53+
norm_type.as_ptr(),
54+
&n,
55+
AsPtr::as_ptr(a),
56+
&self.layout.lda(),
57+
&anorm,
58+
&mut rcond,
59+
AsPtr::as_mut_ptr(&mut self.work),
60+
AsPtr::as_mut_ptr(self.rwork.as_mut().unwrap()),
61+
&mut info,
62+
)
63+
};
64+
info.as_lapack_result()?;
65+
Ok(rcond)
66+
}
67+
}
68+
};
69+
}
70+
impl_rcond_work_c!(c64, lapack_sys::zgecon_);
71+
impl_rcond_work_c!(c32, lapack_sys::cgecon_);
72+
73+
macro_rules! impl_rcond_work_r {
74+
($r:ty, $con:path) => {
75+
impl RcondWorkImpl for RcondWork<$r> {
76+
type Elem = $r;
77+
78+
fn new(layout: MatrixLayout) -> Self {
79+
let (n, _) = layout.size();
80+
let work = vec_uninit(4 * n as usize);
81+
let iwork = vec_uninit(n as usize);
82+
RcondWork {
83+
layout,
84+
work,
85+
rwork: None,
86+
iwork: Some(iwork),
87+
}
88+
}
89+
90+
fn calc(
91+
&mut self,
92+
a: &[Self::Elem],
93+
anorm: <Self::Elem as Scalar>::Real,
94+
) -> Result<<Self::Elem as Scalar>::Real> {
95+
let (n, _) = self.layout.size();
96+
let mut rcond = <Self::Elem as Scalar>::Real::zero();
97+
let mut info = 0;
98+
let norm_type = match self.layout {
99+
MatrixLayout::C { .. } => NormType::Infinity,
100+
MatrixLayout::F { .. } => NormType::One,
101+
};
102+
unsafe {
103+
$con(
104+
norm_type.as_ptr(),
105+
&n,
106+
AsPtr::as_ptr(a),
107+
&self.layout.lda(),
108+
&anorm,
109+
&mut rcond,
110+
AsPtr::as_mut_ptr(&mut self.work),
111+
AsPtr::as_mut_ptr(self.iwork.as_mut().unwrap()),
112+
&mut info,
113+
)
114+
};
115+
info.as_lapack_result()?;
116+
Ok(rcond)
117+
}
118+
}
119+
};
120+
}
121+
impl_rcond_work_r!(f64, lapack_sys::dgecon_);
122+
impl_rcond_work_r!(f32, lapack_sys::sgecon_);
123+
5124
pub trait Rcond_: Scalar + Sized {
6125
/// Estimates the the reciprocal of the condition number of the matrix in 1-norm.
7126
///

0 commit comments

Comments
 (0)