1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17
18
19 //! \addtogroup fn_eig_gen
20 //! @{
21
22
23 template<typename T1>
24 arma_warn_unused
25 inline
26 typename enable_if2< is_supported_blas_type<typename T1::pod_type>::value, Col< std::complex<typename T1::pod_type> > >::result
eig_gen(const Base<typename T1::elem_type,T1> & expr,const char * option="nobalance")27 eig_gen
28 (
29 const Base<typename T1::elem_type, T1>& expr,
30 const char* option = "nobalance"
31 )
32 {
33 arma_extra_debug_sigprint();
34
35 typedef typename T1::pod_type T;
36 typedef typename std::complex<T> eT;
37
38 const char sig = (option != nullptr) ? option[0] : char(0);
39
40 arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" );
41
42 if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); }
43
44 Col<eT> eigvals;
45 Mat<eT> eigvecs;
46
47 const bool status = (sig == 'b') ? auxlib::eig_gen_balance(eigvals, eigvecs, false, expr.get_ref()) : auxlib::eig_gen(eigvals, eigvecs, false, expr.get_ref());
48
49 if(status == false)
50 {
51 eigvals.soft_reset();
52 arma_stop_runtime_error("eig_gen(): decomposition failed");
53 }
54
55 return eigvals;
56 }
57
58
59
60 template<typename T1>
61 inline
62 typename enable_if2< is_supported_blas_type<typename T1::pod_type>::value, bool >::result
eig_gen(Col<std::complex<typename T1::pod_type>> & eigvals,const Base<typename T1::elem_type,T1> & expr,const char * option="nobalance")63 eig_gen
64 (
65 Col< std::complex<typename T1::pod_type> >& eigvals,
66 const Base< typename T1::elem_type, T1>& expr,
67 const char* option = "nobalance"
68 )
69 {
70 arma_extra_debug_sigprint();
71
72 typedef typename T1::pod_type T;
73 typedef typename std::complex<T> eT;
74
75 const char sig = (option != nullptr) ? option[0] : char(0);
76
77 arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" );
78
79 if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); }
80
81 Mat<eT> eigvecs;
82
83 const bool status = (sig == 'b') ? auxlib::eig_gen_balance(eigvals, eigvecs, false, expr.get_ref()) : auxlib::eig_gen(eigvals, eigvecs, false, expr.get_ref());
84
85 if(status == false)
86 {
87 eigvals.soft_reset();
88 arma_debug_warn_level(3, "eig_gen(): decomposition failed");
89 }
90
91 return status;
92 }
93
94
95
96 template<typename T1>
97 inline
98 typename enable_if2< is_supported_blas_type<typename T1::pod_type>::value, bool >::result
eig_gen(Col<std::complex<typename T1::pod_type>> & eigvals,Mat<std::complex<typename T1::pod_type>> & eigvecs,const Base<typename T1::elem_type,T1> & expr,const char * option="nobalance")99 eig_gen
100 (
101 Col< std::complex<typename T1::pod_type> >& eigvals,
102 Mat< std::complex<typename T1::pod_type> >& eigvecs,
103 const Base<typename T1::elem_type, T1>& expr,
104 const char* option = "nobalance"
105 )
106 {
107 arma_extra_debug_sigprint();
108
109 arma_debug_check( (void_ptr(&eigvals) == void_ptr(&eigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" );
110
111 const char sig = (option != nullptr) ? option[0] : char(0);
112
113 arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" );
114
115 if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); }
116
117 const bool status = (sig == 'b') ? auxlib::eig_gen_balance(eigvals, eigvecs, true, expr.get_ref()) : auxlib::eig_gen(eigvals, eigvecs, true, expr.get_ref());
118
119 if(status == false)
120 {
121 eigvals.soft_reset();
122 eigvecs.soft_reset();
123 arma_debug_warn_level(3, "eig_gen(): decomposition failed");
124 }
125
126 return status;
127 }
128
129
130
131 template<typename T1>
132 inline
133 typename enable_if2< is_supported_blas_type<typename T1::pod_type>::value, bool >::result
eig_gen(Col<std::complex<typename T1::pod_type>> & eigvals,Mat<std::complex<typename T1::pod_type>> & leigvecs,Mat<std::complex<typename T1::pod_type>> & reigvecs,const Base<typename T1::elem_type,T1> & expr,const char * option="nobalance")134 eig_gen
135 (
136 Col< std::complex<typename T1::pod_type> >& eigvals,
137 Mat< std::complex<typename T1::pod_type> >& leigvecs,
138 Mat< std::complex<typename T1::pod_type> >& reigvecs,
139 const Base<typename T1::elem_type, T1>& expr,
140 const char* option = "nobalance"
141 )
142 {
143 arma_extra_debug_sigprint();
144
145 arma_debug_check( (void_ptr(&eigvals) == void_ptr(&leigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'leigvec'" );
146 arma_debug_check( (void_ptr(&eigvals) == void_ptr(&reigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'reigvec'" );
147 arma_debug_check( (void_ptr(&leigvecs) == void_ptr(&reigvecs)), "eig_gen(): parameter 'leigvec' is an alias of parameter 'reigvec'" );
148
149 const char sig = (option != nullptr) ? option[0] : char(0);
150
151 arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" );
152
153 if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); }
154
155 const bool status = (sig == 'b') ? auxlib::eig_gen_twosided_balance(eigvals, leigvecs, reigvecs, expr.get_ref()) : auxlib::eig_gen_twosided(eigvals, leigvecs, reigvecs, expr.get_ref());
156
157 if(status == false)
158 {
159 eigvals.soft_reset();
160 leigvecs.soft_reset();
161 reigvecs.soft_reset();
162 arma_debug_warn_level(3, "eig_gen(): decomposition failed");
163 }
164
165 return status;
166 }
167
168
169
170 //! @}
171