26 #if defined (HAVE_CONFIG_H)
38 FloatEIG::init (
const FloatMatrix& a,
bool calc_rev,
bool calc_lev,
42 (*current_liboctave_error_handler)
43 (
"EIG: matrix contains Inf or NaN values");
46 return symmetric_init (a, calc_rev, calc_lev);
52 (*current_liboctave_error_handler) (
"EIG requires square matrix");
60 float *pwr = wr.fortran_vec ();
63 float *pwi = wi.fortran_vec ();
65 volatile F77_INT nvr = (calc_rev ?
n : 0);
67 float *pvr = vr.fortran_vec ();
69 volatile F77_INT nvl = (calc_lev ?
n : 0);
71 float *pvl = vl.fortran_vec ();
80 float *pscale =
scale.fortran_vec ();
85 float *prconde = rconde.fortran_vec ();
88 float *prcondv = rcondv.fortran_vec ();
92 F77_XFCN (sgeevx, SGEEVX, (F77_CONST_CHAR_ARG2 (balance ?
"B" :
"N", 1),
93 F77_CONST_CHAR_ARG2 (
"N", 1),
94 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
95 F77_CONST_CHAR_ARG2 (
"N", 1),
96 n, tmp_data,
n, pwr, pwi,
98 ilo, ihi, pscale, abnrm, prconde, prcondv,
99 &dummy_work, lwork, &dummy_iwork, info
103 F77_CHAR_ARG_LEN (1)));
106 (*current_liboctave_error_handler) (
"sgeevx workspace query failed");
108 lwork =
static_cast<F77_INT> (dummy_work);
110 float *pwork = work.fortran_vec ();
112 F77_XFCN (sgeevx, SGEEVX, (F77_CONST_CHAR_ARG2 (balance ?
"B" :
"N", 1),
113 F77_CONST_CHAR_ARG2 (
"N", 1),
114 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
115 F77_CONST_CHAR_ARG2 (
"N", 1),
116 n, tmp_data,
n, pwr, pwi,
118 ilo, ihi, pscale, abnrm, prconde, prcondv,
119 pwork, lwork, &dummy_iwork, info
123 F77_CHAR_ARG_LEN (1)));
126 (*current_liboctave_error_handler) (
"unrecoverable error in sgeevx");
129 (*current_liboctave_error_handler) (
"sgeevx failed to converge");
137 if (wi.elem (j) == 0.0)
141 m_v.
elem (i, j) = vr.elem (i, j);
143 for (
F77_INT i = 0; i < nvl; i++)
144 m_w.
elem (i, j) = vl.elem (i, j);
149 (*current_liboctave_error_handler) (
"EIG: internal error");
154 for (
F77_INT i = 0; i < nvr; i++)
156 float real_part = vr.elem (i, j);
157 float imag_part = vr.elem (i, j+1);
161 for (
F77_INT i = 0; i < nvl; i++)
163 float real_part = vl.elem (i, j);
164 float imag_part = vl.elem (i, j+1);
176 FloatEIG::symmetric_init (
const FloatMatrix& a,
bool calc_rev,
bool calc_lev)
182 (*current_liboctave_error_handler) (
"EIG requires square matrix");
190 float *pwr = wr.fortran_vec ();
195 F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
196 F77_CONST_CHAR_ARG2 (
"U", 1),
197 n, tmp_data,
n, pwr, &dummy_work, lwork, info
199 F77_CHAR_ARG_LEN (1)));
202 (*current_liboctave_error_handler) (
"ssyev workspace query failed");
204 lwork =
static_cast<F77_INT> (dummy_work);
206 float *pwork = work.fortran_vec ();
208 F77_XFCN (ssyev, SSYEV, (F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
209 F77_CONST_CHAR_ARG2 (
"U", 1),
210 n, tmp_data,
n, pwr, pwork, lwork, info
212 F77_CHAR_ARG_LEN (1)));
215 (*current_liboctave_error_handler) (
"unrecoverable error in ssyev");
218 (*current_liboctave_error_handler) (
"ssyev failed to converge");
232 (*current_liboctave_error_handler)
233 (
"EIG: matrix contains Inf or NaN values");
236 return hermitian_init (a, calc_rev, calc_lev);
242 (*current_liboctave_error_handler) (
"EIG requires square matrix");
265 float *prwork = rwork.fortran_vec ();
271 float *pscale =
scale.fortran_vec ();
276 float *prconde = rconde.fortran_vec ();
279 float *prcondv = rcondv.fortran_vec ();
281 F77_XFCN (cgeevx, CGEEVX, (F77_CONST_CHAR_ARG2 (balance ?
"B" :
"N", 1),
282 F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
283 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
284 F77_CONST_CHAR_ARG2 (
"N", 1),
287 ilo, ihi, pscale, abnrm, prconde, prcondv,
292 F77_CHAR_ARG_LEN (1)));
295 (*current_liboctave_error_handler) (
"cgeevx workspace query failed");
297 lwork =
static_cast<F77_INT> (dummy_work.real ());
301 F77_XFCN (cgeevx, CGEEVX, (F77_CONST_CHAR_ARG2 (balance ?
"B" :
"N", 1),
302 F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
303 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
304 F77_CONST_CHAR_ARG2 (
"N", 1),
307 ilo, ihi, pscale, abnrm, prconde, prcondv,
312 F77_CHAR_ARG_LEN (1)));
315 (*current_liboctave_error_handler) (
"unrecoverable error in cgeevx");
318 (*current_liboctave_error_handler) (
"cgeevx failed to converge");
335 (*current_liboctave_error_handler) (
"EIG requires square matrix");
343 float *pwr = wr.fortran_vec ();
350 float *prwork = rwork.fortran_vec ();
352 F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
353 F77_CONST_CHAR_ARG2 (
"U", 1),
358 F77_CHAR_ARG_LEN (1)));
361 (*current_liboctave_error_handler) (
"cheev workspace query failed");
363 lwork =
static_cast<F77_INT> (dummy_work.real ());
367 F77_XFCN (cheev, CHEEV, (F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
368 F77_CONST_CHAR_ARG2 (
"U", 1),
372 F77_CHAR_ARG_LEN (1)));
375 (*current_liboctave_error_handler) (
"unrecoverable error in cheev");
378 (*current_liboctave_error_handler) (
"cheev failed to converge");
389 bool calc_lev,
bool force_qz)
392 (*current_liboctave_error_handler)
393 (
"EIG: matrix contains Inf or NaN values");
401 if (
n != a_nc || nb != b_nc)
402 (*current_liboctave_error_handler) (
"EIG requires square matrix");
405 (*current_liboctave_error_handler) (
"EIG requires same size matrices");
413 F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (
"L", 1),
416 F77_CHAR_ARG_LEN (1)));
419 return symmetric_init (a, b, calc_rev, calc_lev);
429 float *par = ar.fortran_vec ();
432 float *pai = ai.fortran_vec ();
435 float *pbeta = beta.fortran_vec ();
437 volatile F77_INT nvr = (calc_rev ?
n : 0);
439 float *pvr = vr.fortran_vec ();
441 volatile F77_INT nvl = (calc_lev ?
n : 0);
443 float *pvl = vl.fortran_vec ();
448 F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
449 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
450 n, atmp_data,
n, btmp_data,
n,
453 &dummy_work, lwork, info
455 F77_CHAR_ARG_LEN (1)));
458 (*current_liboctave_error_handler) (
"sggev workspace query failed");
460 lwork =
static_cast<F77_INT> (dummy_work);
462 float *pwork = work.fortran_vec ();
464 F77_XFCN (sggev, SGGEV, (F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
465 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
466 n, atmp_data,
n, btmp_data,
n,
471 F77_CHAR_ARG_LEN (1)));
474 (*current_liboctave_error_handler) (
"unrecoverable error in sggev");
477 (*current_liboctave_error_handler) (
"sggev failed to converge");
486 if (ai.elem (j) == 0.0)
488 m_lambda.elem (j) =
FloatComplex (ar.elem (j) / beta.elem (j));
489 for (
F77_INT i = 0; i < nvr; i++)
490 m_v.
elem (i, j) = vr.elem (i, j);
492 for (
F77_INT i = 0; i < nvl; i++)
493 m_w.
elem (i, j) = vl.elem (i, j);
498 (*current_liboctave_error_handler) (
"EIG: internal error");
500 m_lambda.elem (j) =
FloatComplex (ar.elem (j) / beta.elem (j),
501 ai.elem (j) / beta.elem (j));
502 m_lambda.elem (j+1) =
FloatComplex (ar.elem (j+1) / beta.elem (j+1),
503 ai.elem (j+1) / beta.elem (j+1));
505 for (
F77_INT i = 0; i < nvr; i++)
507 float real_part = vr.elem (i, j);
508 float imag_part = vr.elem (i, j+1);
512 for (
F77_INT i = 0; i < nvl; i++)
514 float real_part = vl.elem (i, j);
515 float imag_part = vl.elem (i, j+1);
528 bool calc_rev,
bool calc_lev)
536 if (
n != a_nc || nb != b_nc)
537 (*current_liboctave_error_handler) (
"EIG requires square matrix");
540 (*current_liboctave_error_handler) (
"EIG requires same size matrices");
551 float *pwr = wr.fortran_vec ();
556 F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
557 F77_CONST_CHAR_ARG2 (
"U", 1),
560 pwr, &dummy_work, lwork, info
562 F77_CHAR_ARG_LEN (1)));
565 (*current_liboctave_error_handler) (
"ssygv workspace query failed");
567 lwork =
static_cast<F77_INT> (dummy_work);
569 float *pwork = work.fortran_vec ();
571 F77_XFCN (ssygv, SSYGV, (1, F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
572 F77_CONST_CHAR_ARG2 (
"U", 1),
575 pwr, pwork, lwork, info
577 F77_CHAR_ARG_LEN (1)));
580 (*current_liboctave_error_handler) (
"unrecoverable error in ssygv");
583 (*current_liboctave_error_handler) (
"ssygv failed to converge");
594 bool calc_rev,
bool calc_lev,
bool force_qz)
597 (*current_liboctave_error_handler)
598 (
"EIG: matrix contains Inf or NaN values");
606 if (
n != a_nc || nb != b_nc)
607 (*current_liboctave_error_handler) (
"EIG requires square matrix");
610 (*current_liboctave_error_handler) (
"EIG requires same size matrices");
619 F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (
"L", 1),
622 F77_CHAR_ARG_LEN (1)));
625 return hermitian_init (a, b, calc_rev, calc_lev);
653 float *prwork = rwork.fortran_vec ();
655 F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
656 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
663 F77_CHAR_ARG_LEN (1)));
666 (*current_liboctave_error_handler) (
"cggev workspace query failed");
668 lwork =
static_cast<F77_INT> (dummy_work.real ());
672 F77_XFCN (cggev, CGGEV, (F77_CONST_CHAR_ARG2 (calc_lev ?
"V" :
"N", 1),
673 F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
680 F77_CHAR_ARG_LEN (1)));
683 (*current_liboctave_error_handler) (
"unrecoverable error in cggev");
686 (*current_liboctave_error_handler) (
"cggev failed to converge");
691 m_lambda.elem (j) = alpha.elem (j) / beta.elem (j);
702 bool calc_rev,
bool calc_lev)
710 if (
n != a_nc || nb != b_nc)
711 (*current_liboctave_error_handler) (
"EIG requires square matrix");
714 (*current_liboctave_error_handler) (
"EIG requires same size matrices");
725 float *pwr = wr.fortran_vec ();
732 float *prwork = rwork.fortran_vec ();
734 F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
735 F77_CONST_CHAR_ARG2 (
"U", 1),
741 F77_CHAR_ARG_LEN (1)));
744 (*current_liboctave_error_handler) (
"zhegv workspace query failed");
746 lwork =
static_cast<F77_INT> (dummy_work.real ());
750 F77_XFCN (chegv, CHEGV, (1, F77_CONST_CHAR_ARG2 (calc_rev ?
"V" :
"N", 1),
751 F77_CONST_CHAR_ARG2 (
"U", 1),
756 F77_CHAR_ARG_LEN (1)));
759 (*current_liboctave_error_handler) (
"unrecoverable error in zhegv");
762 (*current_liboctave_error_handler) (
"zhegv failed to converge");
N Dimensional Array with copy-on-write semantics.
T & elem(octave_idx_type n)
Size of the specified dimension.
T * fortran_vec()
Size of the specified dimension.
octave_idx_type rows() const
octave_idx_type cols() const
void resize(octave_idx_type n, const FloatComplex &rfv=FloatComplex(0))
void resize(octave_idx_type nr, octave_idx_type nc, const FloatComplex &rfv=FloatComplex(0))
bool any_element_is_inf_or_nan() const
friend class FloatComplexMatrix
bool any_element_is_inf_or_nan() const
Vector representing the dimensions (size) of an Array.
#define F77_XFCN(f, F, args)
octave_f77_int_type F77_INT
void scale(Matrix &m, double x, double y, double z)
std::complex< float > FloatComplex