@@ -2,6 +2,125 @@ use crate::{error::*, layout::MatrixLayout, *};
2
2
use cauchy:: * ;
3
3
use num_traits:: Zero ;
4
4
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
+
5
124
pub trait Rcond_ : Scalar + Sized {
6
125
/// Estimates the the reciprocal of the condition number of the matrix in 1-norm.
7
126
///
0 commit comments