@@ -2,6 +2,125 @@ use crate::{error::*, layout::MatrixLayout, *};
22use cauchy:: * ;
33use 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+
5124pub trait Rcond_ : Scalar + Sized {
6125 /// Estimates the the reciprocal of the condition number of the matrix in 1-norm.
7126 ///
0 commit comments