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