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_eigs_gen
20 //! @{
21
22
23 //! eigenvalues of general sparse matrix X
24 template<typename T1>
25 arma_warn_unused
26 inline
27 typename enable_if2< is_real<typename T1::pod_type>::value, Col< std::complex<typename T1::pod_type> > >::result
eigs_gen(const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form="lm",const eigs_opts opts=eigs_opts ())28 eigs_gen
29 (
30 const SpBase<typename T1::elem_type, T1>& X,
31 const uword n_eigvals,
32 const char* form = "lm",
33 const eigs_opts opts = eigs_opts()
34 )
35 {
36 arma_extra_debug_sigprint();
37
38 typedef typename T1::pod_type T;
39
40 Mat< std::complex<T> > eigvec;
41 Col< std::complex<T> > eigval;
42
43 sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form);
44
45 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts);
46
47 if(status == false)
48 {
49 eigval.soft_reset();
50 arma_stop_runtime_error("eigs_gen(): decomposition failed");
51 }
52
53 return eigval;
54 }
55
56
57
58 //! this form is deprecated; use eigs_gen(X, n_eigvals, form, opts) instead
59 template<typename T1>
60 arma_deprecated
61 inline
62 typename enable_if2< is_real<typename T1::pod_type>::value, Col< std::complex<typename T1::pod_type> > >::result
eigs_gen(const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form,const typename T1::pod_type tol)63 eigs_gen
64 (
65 const SpBase<typename T1::elem_type, T1>& X,
66 const uword n_eigvals,
67 const char* form,
68 const typename T1::pod_type tol
69 )
70 {
71 arma_extra_debug_sigprint();
72
73 eigs_opts opts;
74 opts.tol = tol;
75
76 return eigs_gen(X, n_eigvals, form, opts);
77 }
78
79
80
81 template<typename T1>
82 arma_warn_unused
83 inline
84 typename enable_if2< is_real<typename T1::pod_type>::value, Col< std::complex<typename T1::pod_type> > >::result
eigs_gen(const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const std::complex<typename T1::pod_type> sigma,const eigs_opts opts=eigs_opts ())85 eigs_gen
86 (
87 const SpBase<typename T1::elem_type, T1>& X,
88 const uword n_eigvals,
89 const std::complex<typename T1::pod_type> sigma,
90 const eigs_opts opts = eigs_opts()
91 )
92 {
93 arma_extra_debug_sigprint();
94
95 typedef typename T1::pod_type T;
96
97 Mat< std::complex<T> > eigvec;
98 Col< std::complex<T> > eigval;
99
100 bool status = false;
101
102 // If X is real and sigma is truly complex, treat X as complex.
103 // The reason is that we are still not able to apply truly complex shifts to real matrices
104 if( (is_real<typename T1::elem_type>::yes) && (std::imag(sigma) != T(0)) )
105 {
106 status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex<T> > >::from(X), n_eigvals, sigma, opts);
107 }
108 else
109 {
110 status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts);
111 }
112
113 if(status == false)
114 {
115 eigval.soft_reset();
116 arma_stop_runtime_error("eigs_gen(): decomposition failed");
117 }
118
119 return eigval;
120 }
121
122
123
124 template<typename T1>
125 arma_warn_unused
126 inline
127 typename enable_if2< is_real<typename T1::pod_type>::value, Col< std::complex<typename T1::pod_type> > >::result
eigs_gen(const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const double sigma,const eigs_opts opts=eigs_opts ())128 eigs_gen
129 (
130 const SpBase<typename T1::elem_type, T1>& X,
131 const uword n_eigvals,
132 const double sigma,
133 const eigs_opts opts = eigs_opts()
134 )
135 {
136 arma_extra_debug_sigprint();
137
138 typedef typename T1::pod_type T;
139
140 Mat< std::complex<T> > eigvec;
141 Col< std::complex<T> > eigval;
142
143 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex<T>(T(sigma)), opts);
144
145 if(status == false)
146 {
147 eigval.soft_reset();
148 arma_stop_runtime_error("eigs_gen(): decomposition failed");
149 }
150
151 return eigval;
152 }
153
154
155
156 //! eigenvalues of general sparse matrix X
157 template<typename T1>
158 inline
159 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form="lm",const eigs_opts opts=eigs_opts ())160 eigs_gen
161 (
162 Col< std::complex<typename T1::pod_type> >& eigval,
163 const SpBase<typename T1::elem_type, T1>& X,
164 const uword n_eigvals,
165 const char* form = "lm",
166 const eigs_opts opts = eigs_opts()
167 )
168 {
169 arma_extra_debug_sigprint();
170
171 typedef typename T1::pod_type T;
172
173 Mat< std::complex<T> > eigvec;
174
175 sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form);
176
177 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts);
178
179 if(status == false)
180 {
181 eigval.soft_reset();
182 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
183 }
184
185 return status;
186 }
187
188
189
190 //! this form is deprecated; use eigs_gen(eigval, X, n_eigvals, form, opts) instead
191 template<typename T1>
192 arma_deprecated
193 inline
194 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form,const typename T1::pod_type tol)195 eigs_gen
196 (
197 Col< std::complex<typename T1::pod_type> >& eigval,
198 const SpBase<typename T1::elem_type, T1>& X,
199 const uword n_eigvals,
200 const char* form,
201 const typename T1::pod_type tol
202 )
203 {
204 arma_extra_debug_sigprint();
205
206 eigs_opts opts;
207 opts.tol = tol;
208
209 return eigs_gen(eigval, X, n_eigvals, form, opts);
210 }
211
212
213
214 template<typename T1>
215 inline
216 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const std::complex<typename T1::pod_type> sigma,const eigs_opts opts=eigs_opts ())217 eigs_gen
218 (
219 Col< std::complex<typename T1::pod_type> >& eigval,
220 const SpBase<typename T1::elem_type, T1>& X,
221 const uword n_eigvals,
222 const std::complex<typename T1::pod_type> sigma,
223 const eigs_opts opts = eigs_opts()
224 )
225 {
226 arma_extra_debug_sigprint();
227
228 typedef typename T1::pod_type T;
229
230 Mat< std::complex<T> > eigvec;
231
232 bool status = false;
233
234 // If X is real and sigma is truly complex, treat X as complex.
235 // The reason is that we are still not able to apply truly complex shifts to real matrices
236 if( (is_real<typename T1::elem_type>::yes) && (std::imag(sigma) != T(0)) )
237 {
238 status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex<T> > >::from(X), n_eigvals, sigma, opts);
239 }
240 else
241 {
242 status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts);
243 }
244
245 if(status == false)
246 {
247 eigval.soft_reset();
248 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
249 }
250
251 return status;
252 }
253
254
255
256 template<typename T1>
257 inline
258 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const double sigma,const eigs_opts opts=eigs_opts ())259 eigs_gen
260 (
261 Col< std::complex<typename T1::pod_type> >& eigval,
262 const SpBase<typename T1::elem_type, T1>& X,
263 const uword n_eigvals,
264 const double sigma,
265 const eigs_opts opts = eigs_opts()
266 )
267 {
268 arma_extra_debug_sigprint();
269
270 typedef typename T1::pod_type T;
271
272 Mat< std::complex<T> > eigvec;
273
274 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex<T>(T(sigma)), opts);
275
276 if(status == false)
277 {
278 eigval.soft_reset();
279 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
280 }
281
282 return status;
283 }
284
285
286
287 //! eigenvalues and eigenvectors of general sparse matrix X
288 template<typename T1>
289 inline
290 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,Mat<std::complex<typename T1::pod_type>> & eigvec,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form="lm",const eigs_opts opts=eigs_opts ())291 eigs_gen
292 (
293 Col< std::complex<typename T1::pod_type> >& eigval,
294 Mat< std::complex<typename T1::pod_type> >& eigvec,
295 const SpBase<typename T1::elem_type, T1>& X,
296 const uword n_eigvals,
297 const char* form = "lm",
298 const eigs_opts opts = eigs_opts()
299 )
300 {
301 arma_extra_debug_sigprint();
302
303 // typedef typename T1::pod_type T;
304
305 arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" );
306
307 sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form);
308
309 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts);
310
311 if(status == false)
312 {
313 eigval.soft_reset();
314 eigvec.soft_reset();
315 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
316 }
317
318 return status;
319 }
320
321
322
323 //! this form is deprecated; use eigs_gen(eigval, eigvec, X, n_eigvals, form, opts) instead
324 template<typename T1>
325 arma_deprecated
326 inline
327 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,Mat<std::complex<typename T1::pod_type>> & eigvec,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const char * form,const typename T1::pod_type tol)328 eigs_gen
329 (
330 Col< std::complex<typename T1::pod_type> >& eigval,
331 Mat< std::complex<typename T1::pod_type> >& eigvec,
332 const SpBase<typename T1::elem_type, T1>& X,
333 const uword n_eigvals,
334 const char* form,
335 const typename T1::pod_type tol
336 )
337 {
338 arma_extra_debug_sigprint();
339
340 eigs_opts opts;
341 opts.tol = tol;
342
343 return eigs_gen(eigval, eigvec, X, n_eigvals, form, opts);
344 }
345
346
347
348 template<typename T1>
349 inline
350 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,Mat<std::complex<typename T1::pod_type>> & eigvec,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const std::complex<typename T1::pod_type> sigma,const eigs_opts opts=eigs_opts ())351 eigs_gen
352 (
353 Col< std::complex<typename T1::pod_type> >& eigval,
354 Mat< std::complex<typename T1::pod_type> >& eigvec,
355 const SpBase<typename T1::elem_type, T1>& X,
356 const uword n_eigvals,
357 const std::complex<typename T1::pod_type> sigma,
358 const eigs_opts opts = eigs_opts()
359 )
360 {
361 arma_extra_debug_sigprint();
362
363 typedef typename T1::pod_type T;
364
365 arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" );
366
367 bool status = false;
368
369 // If X is real and sigma is truly complex, treat X as complex.
370 // The reason is that we are still not able to apply truly complex shifts to real matrices
371 if( (is_real<typename T1::elem_type>::yes) && (std::imag(sigma) != T(0)) )
372 {
373 status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex<T> > >::from(X), n_eigvals, sigma, opts);
374 }
375 else
376 {
377 status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts);
378 }
379
380 if(status == false)
381 {
382 eigval.soft_reset();
383 eigvec.soft_reset();
384 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
385 }
386
387 return status;
388 }
389
390
391
392 template<typename T1>
393 inline
394 typename enable_if2< is_real<typename T1::pod_type>::value, bool >::result
eigs_gen(Col<std::complex<typename T1::pod_type>> & eigval,Mat<std::complex<typename T1::pod_type>> & eigvec,const SpBase<typename T1::elem_type,T1> & X,const uword n_eigvals,const double sigma,const eigs_opts opts=eigs_opts ())395 eigs_gen
396 (
397 Col< std::complex<typename T1::pod_type> >& eigval,
398 Mat< std::complex<typename T1::pod_type> >& eigvec,
399 const SpBase<typename T1::elem_type, T1>& X,
400 const uword n_eigvals,
401 const double sigma,
402 const eigs_opts opts = eigs_opts()
403 )
404 {
405 arma_extra_debug_sigprint();
406
407 typedef typename T1::pod_type T;
408
409 arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" );
410
411 const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex<T>(T(sigma)), opts);
412
413 if(status == false)
414 {
415 eigval.soft_reset();
416 eigvec.soft_reset();
417 arma_debug_warn_level(3, "eigs_gen(): decomposition failed");
418 }
419
420 return status;
421 }
422
423
424
425 //! @}
426