@@ -10,140 +10,3 @@ pub use lu::*;
1010pub use matrix:: * ;
1111pub use rcond:: * ;
1212pub use solve:: * ;
13-
14- use crate :: { error:: * , layout:: * , * } ;
15- use cauchy:: * ;
16- use num_traits:: Zero ;
17-
18- /// Wraps `*gttrf`, `*gtcon` and `*gttrs`
19- pub trait Tridiagonal_ : Scalar + Sized {
20- /// Computes the LU factorization of a tridiagonal `m x n` matrix `a` using
21- /// partial pivoting with row interchanges.
22- fn lu_tridiagonal ( a : Tridiagonal < Self > ) -> Result < LUFactorizedTridiagonal < Self > > ;
23-
24- fn rcond_tridiagonal ( lu : & LUFactorizedTridiagonal < Self > ) -> Result < Self :: Real > ;
25-
26- fn solve_tridiagonal (
27- lu : & LUFactorizedTridiagonal < Self > ,
28- bl : MatrixLayout ,
29- t : Transpose ,
30- b : & mut [ Self ] ,
31- ) -> Result < ( ) > ;
32- }
33-
34- macro_rules! impl_tridiagonal {
35- ( @real, $scalar: ty, $gttrf: path, $gtcon: path, $gttrs: path) => {
36- impl_tridiagonal!( @body, $scalar, $gttrf, $gtcon, $gttrs, iwork) ;
37- } ;
38- ( @complex, $scalar: ty, $gttrf: path, $gtcon: path, $gttrs: path) => {
39- impl_tridiagonal!( @body, $scalar, $gttrf, $gtcon, $gttrs, ) ;
40- } ;
41- ( @body, $scalar: ty, $gttrf: path, $gtcon: path, $gttrs: path, $( $iwork: ident) * ) => {
42- impl Tridiagonal_ for $scalar {
43- fn lu_tridiagonal( mut a: Tridiagonal <Self >) -> Result <LUFactorizedTridiagonal <Self >> {
44- let ( n, _) = a. l. size( ) ;
45- let mut du2 = vec_uninit( ( n - 2 ) as usize ) ;
46- let mut ipiv = vec_uninit( n as usize ) ;
47- // We have to calc one-norm before LU factorization
48- let a_opnorm_one = a. opnorm_one( ) ;
49- let mut info = 0 ;
50- unsafe {
51- $gttrf(
52- & n,
53- AsPtr :: as_mut_ptr( & mut a. dl) ,
54- AsPtr :: as_mut_ptr( & mut a. d) ,
55- AsPtr :: as_mut_ptr( & mut a. du) ,
56- AsPtr :: as_mut_ptr( & mut du2) ,
57- AsPtr :: as_mut_ptr( & mut ipiv) ,
58- & mut info,
59- )
60- } ;
61- info. as_lapack_result( ) ?;
62- let du2 = unsafe { du2. assume_init( ) } ;
63- let ipiv = unsafe { ipiv. assume_init( ) } ;
64- Ok ( LUFactorizedTridiagonal {
65- a,
66- du2,
67- ipiv,
68- a_opnorm_one,
69- } )
70- }
71-
72- fn rcond_tridiagonal( lu: & LUFactorizedTridiagonal <Self >) -> Result <Self :: Real > {
73- let ( n, _) = lu. a. l. size( ) ;
74- let ipiv = & lu. ipiv;
75- let mut work: Vec <MaybeUninit <Self >> = vec_uninit( 2 * n as usize ) ;
76- $(
77- let mut $iwork: Vec <MaybeUninit <i32 >> = vec_uninit( n as usize ) ;
78- ) *
79- let mut rcond = Self :: Real :: zero( ) ;
80- let mut info = 0 ;
81- unsafe {
82- $gtcon(
83- NormType :: One . as_ptr( ) ,
84- & n,
85- AsPtr :: as_ptr( & lu. a. dl) ,
86- AsPtr :: as_ptr( & lu. a. d) ,
87- AsPtr :: as_ptr( & lu. a. du) ,
88- AsPtr :: as_ptr( & lu. du2) ,
89- ipiv. as_ptr( ) ,
90- & lu. a_opnorm_one,
91- & mut rcond,
92- AsPtr :: as_mut_ptr( & mut work) ,
93- $( AsPtr :: as_mut_ptr( & mut $iwork) , ) *
94- & mut info,
95- ) ;
96- }
97- info. as_lapack_result( ) ?;
98- Ok ( rcond)
99- }
100-
101- fn solve_tridiagonal(
102- lu: & LUFactorizedTridiagonal <Self >,
103- b_layout: MatrixLayout ,
104- t: Transpose ,
105- b: & mut [ Self ] ,
106- ) -> Result <( ) > {
107- let ( n, _) = lu. a. l. size( ) ;
108- let ipiv = & lu. ipiv;
109- // Transpose if b is C-continuous
110- let mut b_t = None ;
111- let b_layout = match b_layout {
112- MatrixLayout :: C { .. } => {
113- let ( layout, t) = transpose( b_layout, b) ;
114- b_t = Some ( t) ;
115- layout
116- }
117- MatrixLayout :: F { .. } => b_layout,
118- } ;
119- let ( ldb, nrhs) = b_layout. size( ) ;
120- let mut info = 0 ;
121- unsafe {
122- $gttrs(
123- t. as_ptr( ) ,
124- & n,
125- & nrhs,
126- AsPtr :: as_ptr( & lu. a. dl) ,
127- AsPtr :: as_ptr( & lu. a. d) ,
128- AsPtr :: as_ptr( & lu. a. du) ,
129- AsPtr :: as_ptr( & lu. du2) ,
130- ipiv. as_ptr( ) ,
131- AsPtr :: as_mut_ptr( b_t. as_mut( ) . map( |v| v. as_mut_slice( ) ) . unwrap_or( b) ) ,
132- & ldb,
133- & mut info,
134- ) ;
135- }
136- info. as_lapack_result( ) ?;
137- if let Some ( b_t) = b_t {
138- transpose_over( b_layout, & b_t, b) ;
139- }
140- Ok ( ( ) )
141- }
142- }
143- } ;
144- } // impl_tridiagonal!
145-
146- impl_tridiagonal ! ( @real, f64 , lapack_sys:: dgttrf_, lapack_sys:: dgtcon_, lapack_sys:: dgttrs_) ;
147- impl_tridiagonal ! ( @real, f32 , lapack_sys:: sgttrf_, lapack_sys:: sgtcon_, lapack_sys:: sgttrs_) ;
148- impl_tridiagonal ! ( @complex, c64, lapack_sys:: zgttrf_, lapack_sys:: zgtcon_, lapack_sys:: zgttrs_) ;
149- impl_tridiagonal ! ( @complex, c32, lapack_sys:: cgttrf_, lapack_sys:: cgtcon_, lapack_sys:: cgttrs_) ;
0 commit comments