int zgeev(char JOBVL, char JOBVR,int N,dcomplex * A,int lda, dcomplex * W, dcomplex* VL, int LDVL,dcomplex * VR, int LDVR, dcomplex * WORK, int LWORK, dcomplex * RWORK) { int INFO; zgeev_(&JOBVL,&JOBVR, &N,A,&lda,W,VL,&LDVL,VR,&LDVR,WORK, &LWORK,RWORK,&INFO); return INFO; }
int Eigen(gsl_matrix_complex *A, gsl_matrix_complex *vec, gsl_vector_complex *val) { gsl_matrix_complex *T; T=gsl_matrix_complex_alloc(A->size1,A->size2); // Matrix_Copy(T,A); Matrix_Transpose(T,A); char jobvl='N'; char jobvr='V'; int n=T->size1; int lda=T->tda; int ldvl=T->tda; int ldvr=T->tda; int info; int lwork=2*n; double *rwork; double _Complex *work; rwork=(double*)malloc(2*n*sizeof(double)); work=(double _Complex*)malloc(sizeof(double _Complex)*lwork); zgeev_(&jobvl,&jobvr,&n, (double _Complex*)T->data, &lda, (double _Complex*)val->data,NULL, &ldvl,(double _Complex*)vec->data, &ldvr, work, &lwork, rwork, &info); Matrix_Transpose(vec); // for(int k=0;k<A->size2;k++){ // double _Complex Scale; // for(int l=0;l<n;l++) // Scale+=cpow(cabs(matrix_get(vec,l,k)),2); // printf("NORM %E %E\n",creal(Scale),cimag(Scale)); // for(int l=0;l<n;l++){ // matrix_div(vec,l,k,csqrt(Scale)); // } // } gsl_matrix_complex_free(T); return info; }
void QuasiNewton<dcomplex>::symmNonHerDiag(int NTrial, ostream &output){ char JOBVL = 'N'; char JOBVR = 'V'; int TwoNTrial = 2*NTrial; int *IPIV = new int[TwoNTrial]; int INFO; ComplexCMMap SSuper(this->SSuperMem, TwoNTrial,TwoNTrial); ComplexCMMap ASuper(this->ASuperMem, TwoNTrial,TwoNTrial); ComplexCMMap SCPY(this->SCPYMem, TwoNTrial,TwoNTrial); ComplexCMMap NHrProd(this->NHrProdMem,TwoNTrial,TwoNTrial); SCPY = SSuper; // Copy of original matrix to use for re-orthogonalization // Invert the metric (maybe not needed?) zgetrf_(&TwoNTrial,&TwoNTrial,this->SSuperMem,&TwoNTrial,IPIV,&INFO); zgetri_(&TwoNTrial,this->SSuperMem,&TwoNTrial,IPIV,this->WORK,&this->LWORK, &INFO); delete [] IPIV; NHrProd = SSuper * ASuper; // cout << "PROD" << endl << NHrProd << endl; zgeev_(&JOBVL,&JOBVR,&TwoNTrial,NHrProd.data(),&TwoNTrial,this->ERMem, this->SSuperMem,&TwoNTrial,this->SSuperMem,&TwoNTrial, this->WORK,&this->LWORK,this->RWORK,&INFO); // Sort eigensystem using Bubble Sort ComplexVecMap E(this->ERMem,TwoNTrial); ComplexCMMap VR(this->SSuperMem,TwoNTrial,TwoNTrial); // cout << endl << ER << endl; this->eigSrt(VR,E); // cout << endl << ER << endl; // Grab the "positive paired" roots (throw away other element of the pair) this->ERMem += NTrial; new (&E ) ComplexVecMap(this->ERMem,NTrial); new (&SSuper) ComplexCMMap(this->SSuperMem+2*NTrial*NTrial,2*NTrial,NTrial); RealVecMap ER(this->RealEMem,NTrial); ER = E.real(); /* * Re-orthogonalize the eigenvectors with respect to the metric S(R) * because DSYGV orthogonalzies the vectors with respect to E(R) * because we solve the opposite problem. * * Gramm-Schmidt */ this->metBiOrth(SSuper,SCPY); // Separate the eigenvectors into gerade and ungerade parts ComplexCMMap XTSigmaR(this->XTSigmaRMem,NTrial,NTrial); ComplexCMMap XTSigmaL(this->XTSigmaLMem,NTrial,NTrial); XTSigmaR = SSuper.block(0, 0,NTrial,NTrial); XTSigmaL = SSuper.block(NTrial,0,NTrial,NTrial); // CErr(); }
int mad_cmat_eigen (const cnum_t x[], cnum_t w[], cnum_t vl[], cnum_t vr[], ssz_t n) { assert( x && w && vl && vr ); int info=0; const int nn=n; cnum_t sz; int lwork=-1; mad_alloc_tmp(num_t, rwk, 2*n); mad_alloc_tmp(cnum_t, ra, n*n); mad_cmat_trans(x, ra, n, n); zgeev_("V", "V", &nn, ra, &nn, w, vl, &nn, vr, &nn, &sz, &lwork, rwk, &info); // query mad_alloc_tmp(cnum_t, wk, lwork=creal(sz)); zgeev_("V", "V", &nn, ra, &nn, w, vl, &nn, vr, &nn, wk, &lwork, rwk, &info); // compute mad_free_tmp(wk); mad_free_tmp(ra); mad_free_tmp(rwk); mad_cmat_trans(vl, vl, n, n); mad_cmat_trans(vr, vr, n, n); if (info < 0) error("invalid input argument"); if (info > 0) warn ("eigen failed to compute all eigenvalues"); return info; }
void matrix::diagonalize(matrix& levecs, std::vector<complex>& eigs, matrix& revecs) const { static StopWatch watch("matrix::diagonalizeNH"); watch.start(); //Prepare inputs and outputs: matrix A = *this; //destructible copy int N = A.nRows(); myassert(N > 0); myassert(A.nCols()==N); eigs.resize(N); levecs.init(N, N); revecs.init(N, N); //Prepare temporaries: char jobz = 'V'; //compute eigenvectors and eigenvalues int lwork = (64+1)*N; std::vector<complex> work(lwork); //Magic number 64 obtained by running ILAENV as suggested in doc of zheevr (and taking the max over all N) std::vector<double> rwork(2*N); //Call LAPACK and check errors: int info=0; zgeev_(&jobz, &jobz, &N, A.data(), &N, eigs.data(), levecs.data(), &N, revecs.data(), &N, work.data(), &lwork, rwork.data(), &info); if(info<0) { logPrintf("Argument# %d to LAPACK eigenvalue routine ZGEEV is invalid.\n", -info); stackTraceExit(1); } if(info>0) { logPrintf("Error code %d in LAPACK eigenvalue routine ZGEEV.\n", info); stackTraceExit(1); } watch.stop(); }
/* * Calculate eigenvectors and eigenvalues for a non-symmetric complex matrix * using the CLAPACK zgeev_ function. * */ int gsl_ext_eigen_zgeev(gsl_matrix_complex *A_gsl, gsl_matrix_complex *evec, gsl_vector_complex *eval) { //integer *pivot; integer n,i,j,info,lwork, ldvl, ldvr, lda; doublecomplex *A,*vr,*vl,*w,*work; doublereal *rwork; char jobvl,jobvr; n = A_gsl->size1; // pivot = (integer *)malloc((size_t)n * sizeof(int)); A = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); w = (doublecomplex *)malloc((size_t)n * sizeof(doublecomplex)); vr = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); vl = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); lwork = 16 * n; work = (doublecomplex *)malloc((size_t)lwork * sizeof(doublecomplex)); rwork = (doublereal *)malloc((size_t)lwork * sizeof(doublereal)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { gsl_complex z; double re,im; z = gsl_matrix_complex_get(A_gsl, i, j); re = GSL_REAL(z); im = GSL_IMAG(z); A[j*n+i] = (doublecomplex){re,im}; } } jobvl='N'; jobvr='V'; lda = n; ldvr = n; ldvl = n; zgeev_(&jobvl, &jobvr, &n, A, &lda, w, vl, &ldvl, vr, &ldvr, work, &lwork, rwork, &info); //ZGEEVX(BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE, RCONDV, WORK, LWORK, RWORK, INFO ) for (i = 0; i < n; i++) { gsl_complex z; GSL_SET_COMPLEX(&z, w[i].r, w[i].i); gsl_vector_complex_set(eval, i, z); } for (j = 0; j < n; j++) { for (i = 0; i < n; i++) { gsl_complex z; GSL_SET_COMPLEX(&z, vr[j*n+i].r, vr[j*n+i].i); gsl_matrix_complex_set(evec, i, j, z); } } if (info != 0) { printf("zgeev_: error: info = %d\n", (int)info); } // free(pivot); free(A); free(w); free(vr); free(vl); free(work); free(rwork); return 0; }
/* Subroutine */ int zerred_(char *path, integer *nunit) { /* Format strings */ static char fmt_9999[] = "(1x,a,\002 passed the tests of the error exits" " (\002,i3,\002 tests done)\002)"; static char fmt_9998[] = "(\002 *** \002,a,\002 failed the tests of the " "error exits ***\002)"; /* System generated locals */ integer i__1; /* Builtin functions */ integer s_wsle(cilist *), e_wsle(void); /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); integer s_wsfe(cilist *), i_len_trim(char *, ftnlen), do_fio(integer *, char *, ftnlen), e_wsfe(void); /* Local variables */ doublecomplex a[16] /* was [4][4] */; logical b[4]; integer i__, j; doublereal s[4]; doublecomplex u[16] /* was [4][4] */, w[16], x[4]; char c2[2]; doublereal r1[4], r2[4]; integer iw[16], nt; doublecomplex vl[16] /* was [4][4] */, vr[16] /* was [4][4] */; doublereal rw[20]; doublecomplex vt[16] /* was [4][4] */; integer ihi, ilo, info, sdim; doublereal abnrm; extern /* Subroutine */ int zgees_(char *, char *, L_fp, integer *, doublecomplex *, integer *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, doublereal *, logical *, integer *), zgeev_(char * , char *, integer *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *, doublereal *, integer *); extern logical lsamen_(integer *, char *, char *); extern /* Subroutine */ int zgesdd_(char *, integer *, integer *, doublecomplex *, integer *, doublereal *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *, doublereal *, integer *, integer *), chkxer_(char *, integer *, integer *, logical *, logical *), zgesvd_(char *, char *, integer *, integer *, doublecomplex *, integer *, doublereal *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *, doublereal *, integer *); extern logical zslect_(); extern /* Subroutine */ int zgeesx_(char *, char *, L_fp, char *, integer *, doublecomplex *, integer *, integer *, doublecomplex *, doublecomplex *, integer *, doublereal *, doublereal *, doublecomplex *, integer *, doublereal *, logical *, integer *), zgeevx_(char *, char *, char *, char *, integer *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, integer *, integer *, doublereal *, doublereal *, doublereal *, doublereal * , doublecomplex *, integer *, doublereal *, integer *); /* Fortran I/O blocks */ static cilist io___1 = { 0, 0, 0, 0, 0 }; static cilist io___23 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___24 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___26 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___27 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___28 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___29 = { 0, 0, 0, fmt_9998, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZERRED tests the error exits for the eigenvalue driver routines for */ /* DOUBLE PRECISION matrices: */ /* PATH driver description */ /* ---- ------ ----------- */ /* ZEV ZGEEV find eigenvalues/eigenvectors for nonsymmetric A */ /* ZES ZGEES find eigenvalues/Schur form for nonsymmetric A */ /* ZVX ZGEEVX ZGEEV + balancing and condition estimation */ /* ZSX ZGEESX ZGEES + balancing and condition estimation */ /* ZBD ZGESVD compute SVD of an M-by-N matrix A */ /* ZGESDD compute SVD of an M-by-N matrix A(by divide and */ /* conquer) */ /* Arguments */ /* ========= */ /* PATH (input) CHARACTER*3 */ /* The LAPACK path name for the routines to be tested. */ /* NUNIT (input) INTEGER */ /* The unit number for output. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Arrays in Common .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Executable Statements .. */ infoc_1.nout = *nunit; io___1.ciunit = infoc_1.nout; s_wsle(&io___1); e_wsle(); s_copy(c2, path + 1, (ftnlen)2, (ftnlen)2); /* Initialize A */ for (j = 1; j <= 4; ++j) { for (i__ = 1; i__ <= 4; ++i__) { i__1 = i__ + (j << 2) - 5; a[i__1].r = 0., a[i__1].i = 0.; /* L10: */ } /* L20: */ } for (i__ = 1; i__ <= 4; ++i__) { i__1 = i__ + (i__ << 2) - 5; a[i__1].r = 1., a[i__1].i = 0.; /* L30: */ } infoc_1.ok = TRUE_; nt = 0; if (lsamen_(&c__2, c2, "EV")) { /* Test ZGEEV */ s_copy(srnamc_1.srnamt, "ZGEEV ", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgeev_("X", "N", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, w, &c__1, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgeev_("N", "X", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, w, &c__1, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 3; zgeev_("N", "N", &c_n1, a, &c__1, x, vl, &c__1, vr, &c__1, w, &c__1, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 5; zgeev_("N", "N", &c__2, a, &c__1, x, vl, &c__1, vr, &c__1, w, &c__4, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 8; zgeev_("V", "N", &c__2, a, &c__2, x, vl, &c__1, vr, &c__1, w, &c__4, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 10; zgeev_("N", "V", &c__2, a, &c__2, x, vl, &c__1, vr, &c__1, w, &c__4, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 12; zgeev_("V", "V", &c__1, a, &c__1, x, vl, &c__1, vr, &c__1, w, &c__1, rw, &info); chkxer_("ZGEEV ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += 7; } else if (lsamen_(&c__2, c2, "ES")) { /* Test ZGEES */ s_copy(srnamc_1.srnamt, "ZGEES ", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgees_("X", "N", (L_fp)zslect_, &c__0, a, &c__1, &sdim, x, vl, &c__1, w, &c__1, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgees_("N", "X", (L_fp)zslect_, &c__0, a, &c__1, &sdim, x, vl, &c__1, w, &c__1, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 4; zgees_("N", "S", (L_fp)zslect_, &c_n1, a, &c__1, &sdim, x, vl, &c__1, w, &c__1, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 6; zgees_("N", "S", (L_fp)zslect_, &c__2, a, &c__1, &sdim, x, vl, &c__1, w, &c__4, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 10; zgees_("V", "S", (L_fp)zslect_, &c__2, a, &c__2, &sdim, x, vl, &c__1, w, &c__4, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 12; zgees_("N", "S", (L_fp)zslect_, &c__1, a, &c__1, &sdim, x, vl, &c__1, w, &c__1, rw, b, &info); chkxer_("ZGEES ", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += 6; } else if (lsamen_(&c__2, c2, "VX")) { /* Test ZGEEVX */ s_copy(srnamc_1.srnamt, "ZGEEVX", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgeevx_("X", "N", "N", "N", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgeevx_("N", "X", "N", "N", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 3; zgeevx_("N", "N", "X", "N", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 4; zgeevx_("N", "N", "N", "X", &c__0, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 5; zgeevx_("N", "N", "N", "N", &c_n1, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 7; zgeevx_("N", "N", "N", "N", &c__2, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__4, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 10; zgeevx_("N", "V", "N", "N", &c__2, a, &c__2, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__4, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 12; zgeevx_("N", "N", "V", "N", &c__2, a, &c__2, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__4, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 20; zgeevx_("N", "N", "N", "N", &c__1, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__1, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 20; zgeevx_("N", "N", "V", "V", &c__1, a, &c__1, x, vl, &c__1, vr, &c__1, &ilo, &ihi, s, &abnrm, r1, r2, w, &c__2, rw, &info); chkxer_("ZGEEVX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += 10; } else if (lsamen_(&c__2, c2, "SX")) { /* Test ZGEESX */ s_copy(srnamc_1.srnamt, "ZGEESX", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgeesx_("X", "N", (L_fp)zslect_, "N", &c__0, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__1, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgeesx_("N", "X", (L_fp)zslect_, "N", &c__0, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__1, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 4; zgeesx_("N", "N", (L_fp)zslect_, "X", &c__0, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__1, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 5; zgeesx_("N", "N", (L_fp)zslect_, "N", &c_n1, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__1, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 7; zgeesx_("N", "N", (L_fp)zslect_, "N", &c__2, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__4, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 11; zgeesx_("V", "N", (L_fp)zslect_, "N", &c__2, a, &c__2, &sdim, x, vl, & c__1, r1, r2, w, &c__4, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 15; zgeesx_("N", "N", (L_fp)zslect_, "N", &c__1, a, &c__1, &sdim, x, vl, & c__1, r1, r2, w, &c__1, rw, b, &info); chkxer_("ZGEESX", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += 7; } else if (lsamen_(&c__2, c2, "BD")) { /* Test ZGESVD */ s_copy(srnamc_1.srnamt, "ZGESVD", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgesvd_("X", "N", &c__0, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__1, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgesvd_("N", "X", &c__0, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__1, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgesvd_("O", "O", &c__0, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__1, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 3; zgesvd_("N", "N", &c_n1, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__1, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 4; zgesvd_("N", "N", &c__0, &c_n1, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__1, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 6; zgesvd_("N", "N", &c__2, &c__1, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__5, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 9; zgesvd_("A", "N", &c__2, &c__1, a, &c__2, s, u, &c__1, vt, &c__1, w, & c__5, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 11; zgesvd_("N", "A", &c__1, &c__2, a, &c__1, s, u, &c__1, vt, &c__1, w, & c__5, rw, &info); chkxer_("ZGESVD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += 8; if (infoc_1.ok) { io___23.ciunit = infoc_1.nout; s_wsfe(&io___23); do_fio(&c__1, srnamc_1.srnamt, i_len_trim(srnamc_1.srnamt, ( ftnlen)32)); do_fio(&c__1, (char *)&nt, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___24.ciunit = infoc_1.nout; s_wsfe(&io___24); e_wsfe(); } /* Test ZGESDD */ s_copy(srnamc_1.srnamt, "ZGESDD", (ftnlen)32, (ftnlen)6); infoc_1.infot = 1; zgesdd_("X", &c__0, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, &c__1, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 2; zgesdd_("N", &c_n1, &c__0, a, &c__1, s, u, &c__1, vt, &c__1, w, &c__1, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 3; zgesdd_("N", &c__0, &c_n1, a, &c__1, s, u, &c__1, vt, &c__1, w, &c__1, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 5; zgesdd_("N", &c__2, &c__1, a, &c__1, s, u, &c__1, vt, &c__1, w, &c__5, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 8; zgesdd_("A", &c__2, &c__1, a, &c__2, s, u, &c__1, vt, &c__1, w, &c__5, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); infoc_1.infot = 10; zgesdd_("A", &c__1, &c__2, a, &c__1, s, u, &c__1, vt, &c__1, w, &c__5, rw, iw, &info); chkxer_("ZGESDD", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, & infoc_1.ok); nt += -2; if (infoc_1.ok) { io___26.ciunit = infoc_1.nout; s_wsfe(&io___26); do_fio(&c__1, srnamc_1.srnamt, i_len_trim(srnamc_1.srnamt, ( ftnlen)32)); do_fio(&c__1, (char *)&nt, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___27.ciunit = infoc_1.nout; s_wsfe(&io___27); e_wsfe(); } } /* Print a summary line. */ if (! lsamen_(&c__2, c2, "BD")) { if (infoc_1.ok) { io___28.ciunit = infoc_1.nout; s_wsfe(&io___28); do_fio(&c__1, srnamc_1.srnamt, i_len_trim(srnamc_1.srnamt, ( ftnlen)32)); do_fio(&c__1, (char *)&nt, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___29.ciunit = infoc_1.nout; s_wsfe(&io___29); e_wsfe(); } } return 0; /* End of ZERRED */ } /* zerred_ */
/* Subroutine */ int zdrvev_(integer *nsizes, integer *nn, integer *ntypes, logical *dotype, integer *iseed, doublereal *thresh, integer *nounit, doublecomplex *a, integer *lda, doublecomplex *h__, doublecomplex *w, doublecomplex *w1, doublecomplex *vl, integer *ldvl, doublecomplex * vr, integer *ldvr, doublecomplex *lre, integer *ldlre, doublereal * result, doublecomplex *work, integer *nwork, doublereal *rwork, integer *iwork, integer *info) { /* Initialized data */ static integer ktype[21] = { 1,2,3,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,9,9,9 }; static integer kmagn[21] = { 1,1,1,1,1,1,2,3,1,1,1,1,1,1,1,1,2,3,1,2,3 }; static integer kmode[21] = { 0,0,0,4,3,1,4,4,4,3,1,5,4,3,1,5,5,5,4,3,1 }; static integer kconds[21] = { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,2,0,0,0 }; /* Format strings */ static char fmt_9993[] = "(\002 ZDRVEV: \002,a,\002 returned INFO=\002,i" "6,\002.\002,/9x,\002N=\002,i6,\002, JTYPE=\002,i6,\002, ISEED=" "(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9999[] = "(/1x,a3,\002 -- Complex Eigenvalue-Eigenvect" "or \002,\002Decomposition Driver\002,/\002 Matrix types (see ZDR" "VEV for details): \002)"; static char fmt_9998[] = "(/\002 Special Matrices:\002,/\002 1=Zero mat" "rix. \002,\002 \002,\002 5=Diagonal: geom" "etr. spaced entries.\002,/\002 2=Identity matrix. " " \002,\002 6=Diagona\002,\002l: clustered entries.\002," "/\002 3=Transposed Jordan block. \002,\002 \002,\002 " " 7=Diagonal: large, evenly spaced.\002,/\002 \002,\0024=Diagona" "l: evenly spaced entries. \002,\002 8=Diagonal: s\002,\002ma" "ll, evenly spaced.\002)"; static char fmt_9997[] = "(\002 Dense, Non-Symmetric Matrices:\002,/\002" " 9=Well-cond., ev\002,\002enly spaced eigenvals.\002,\002 14=Il" "l-cond., geomet. spaced e\002,\002igenals.\002,/\002 10=Well-con" "d., geom. spaced eigenvals. \002,\002 15=Ill-conditioned, cluste" "red e.vals.\002,/\002 11=Well-cond\002,\002itioned, clustered e." "vals. \002,\002 16=Ill-cond., random comp\002,\002lex \002,a6," "/\002 12=Well-cond., random complex \002,a6,\002 \002,\002 17=" "Ill-cond., large rand. complx \002,a4,/\002 13=Ill-condi\002," "\002tioned, evenly spaced. \002,\002 18=Ill-cond., small ran" "d.\002,\002 complx \002,a4)"; static char fmt_9996[] = "(\002 19=Matrix with random O(1) entries. " " \002,\002 21=Matrix \002,\002with small random entries.\002," "/\002 20=Matrix with large ran\002,\002dom entries. \002,/)"; static char fmt_9995[] = "(\002 Tests performed with test threshold =" "\002,f8.2,//\002 1 = | A VR - VR W | / ( n |A| ulp ) \002,/\002 " "2 = | conj-trans(A) VL - VL conj-trans(W) | /\002,\002 ( n |A| u" "lp ) \002,/\002 3 = | |VR(i)| - 1 | / ulp \002,/\002 4 = | |VL(i" ")| - 1 | / ulp \002,/\002 5 = 0 if W same no matter if VR or VL " "computed,\002,\002 1/ulp otherwise\002,/\002 6 = 0 if VR same no" " matter if VL computed,\002,\002 1/ulp otherwise\002,/\002 7 = " "0 if VL same no matter if VR computed,\002,\002 1/ulp otherwis" "e\002,/)"; static char fmt_9994[] = "(\002 N=\002,i5,\002, IWK=\002,i2,\002, seed" "=\002,4(i4,\002,\002),\002 type \002,i2,\002, test(\002,i2,\002)=" "\002,g10.3)"; /* System generated locals */ integer a_dim1, a_offset, h_dim1, h_offset, lre_dim1, lre_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3, i__4, i__5, i__6; doublereal d__1, d__2, d__3, d__4, d__5; doublecomplex z__1; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); double sqrt(doublereal); integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); double z_abs(doublecomplex *), d_imag(doublecomplex *); /* Local variables */ integer j, n, jj; doublecomplex dum[1]; doublereal res[2]; integer iwk; doublereal ulp, vmx, cond; integer jcol; char path[3]; integer nmax; doublereal unfl, ovfl, tnrm, vrmx, vtst; logical badnn; integer nfail, imode, iinfo; doublereal conds, anorm; extern /* Subroutine */ int zget22_(char *, char *, char *, integer *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, doublereal *, doublereal *), zgeev_(char *, char *, integer *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *, doublereal *, integer *); integer jsize, nerrs, itype, jtype, ntest; doublereal rtulp; extern /* Subroutine */ int dlabad_(doublereal *, doublereal *); extern doublereal dznrm2_(integer *, doublecomplex *, integer *), dlamch_( char *); integer idumma[1]; extern /* Subroutine */ int xerbla_(char *, integer *); integer ioldsd[4]; extern /* Subroutine */ int dlasum_(char *, integer *, integer *, integer *), zlatme_(integer *, char *, integer *, doublecomplex *, integer *, doublereal *, doublecomplex *, char *, char *, char *, char *, doublereal *, integer *, doublereal *, integer *, integer *, doublereal *, doublecomplex *, integer *, doublecomplex *, integer *), zlacpy_(char *, integer *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); integer ntestf; extern /* Subroutine */ int zlaset_(char *, integer *, integer *, doublecomplex *, doublecomplex *, doublecomplex *, integer *), zlatmr_(integer *, integer *, char *, integer *, char *, doublecomplex *, integer *, doublereal *, doublecomplex *, char *, char *, doublecomplex *, integer *, doublereal *, doublecomplex * , integer *, doublereal *, char *, integer *, integer *, integer * , doublereal *, doublereal *, char *, doublecomplex *, integer *, integer *, integer *), zlatms_(integer *, integer *, char *, integer *, char *, doublereal *, integer *, doublereal *, doublereal *, integer *, integer *, char *, doublecomplex *, integer *, doublecomplex *, integer *); doublereal ulpinv; integer nnwork, mtypes, ntestt; doublereal rtulpi; /* Fortran I/O blocks */ static cilist io___31 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___34 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___42 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___43 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___44 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___47 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___48 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___49 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___50 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___51 = { 0, 0, 0, fmt_9995, 0 }; static cilist io___52 = { 0, 0, 0, fmt_9994, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZDRVEV checks the nonsymmetric eigenvalue problem driver ZGEEV. */ /* When ZDRVEV is called, a number of matrix "sizes" ("n's") and a */ /* number of matrix "types" are specified. For each size ("n") */ /* and each type of matrix, one matrix will be generated and used */ /* to test the nonsymmetric eigenroutines. For each matrix, 7 */ /* tests will be performed: */ /* (1) | A * VR - VR * W | / ( n |A| ulp ) */ /* Here VR is the matrix of unit right eigenvectors. */ /* W is a diagonal matrix with diagonal entries W(j). */ /* (2) | A**H * VL - VL * W**H | / ( n |A| ulp ) */ /* Here VL is the matrix of unit left eigenvectors, A**H is the */ /* conjugate-transpose of A, and W is as above. */ /* (3) | |VR(i)| - 1 | / ulp and whether largest component real */ /* VR(i) denotes the i-th column of VR. */ /* (4) | |VL(i)| - 1 | / ulp and whether largest component real */ /* VL(i) denotes the i-th column of VL. */ /* (5) W(full) = W(partial) */ /* W(full) denotes the eigenvalues computed when both VR and VL */ /* are also computed, and W(partial) denotes the eigenvalues */ /* computed when only W, only W and VR, or only W and VL are */ /* computed. */ /* (6) VR(full) = VR(partial) */ /* VR(full) denotes the right eigenvectors computed when both VR */ /* and VL are computed, and VR(partial) denotes the result */ /* when only VR is computed. */ /* (7) VL(full) = VL(partial) */ /* VL(full) denotes the left eigenvectors computed when both VR */ /* and VL are also computed, and VL(partial) denotes the result */ /* when only VL is computed. */ /* The "sizes" are specified by an array NN(1:NSIZES); the value of */ /* each element NN(j) specifies one size. */ /* The "types" are specified by a logical array DOTYPE( 1:NTYPES ); */ /* if DOTYPE(j) is .TRUE., then matrix type "j" will be generated. */ /* Currently, the list of possible types is: */ /* (1) The zero matrix. */ /* (2) The identity matrix. */ /* (3) A (transposed) Jordan block, with 1's on the diagonal. */ /* (4) A diagonal matrix with evenly spaced entries */ /* 1, ..., ULP and random complex angles. */ /* (ULP = (first number larger than 1) - 1 ) */ /* (5) A diagonal matrix with geometrically spaced entries */ /* 1, ..., ULP and random complex angles. */ /* (6) A diagonal matrix with "clustered" entries 1, ULP, ..., ULP */ /* and random complex angles. */ /* (7) Same as (4), but multiplied by a constant near */ /* the overflow threshold */ /* (8) Same as (4), but multiplied by a constant near */ /* the underflow threshold */ /* (9) A matrix of the form U' T U, where U is unitary and */ /* T has evenly spaced entries 1, ..., ULP with random complex */ /* angles on the diagonal and random O(1) entries in the upper */ /* triangle. */ /* (10) A matrix of the form U' T U, where U is unitary and */ /* T has geometrically spaced entries 1, ..., ULP with random */ /* complex angles on the diagonal and random O(1) entries in */ /* the upper triangle. */ /* (11) A matrix of the form U' T U, where U is unitary and */ /* T has "clustered" entries 1, ULP,..., ULP with random */ /* complex angles on the diagonal and random O(1) entries in */ /* the upper triangle. */ /* (12) A matrix of the form U' T U, where U is unitary and */ /* T has complex eigenvalues randomly chosen from */ /* ULP < |z| < 1 and random O(1) entries in the upper */ /* triangle. */ /* (13) A matrix of the form X' T X, where X has condition */ /* SQRT( ULP ) and T has evenly spaced entries 1, ..., ULP */ /* with random complex angles on the diagonal and random O(1) */ /* entries in the upper triangle. */ /* (14) A matrix of the form X' T X, where X has condition */ /* SQRT( ULP ) and T has geometrically spaced entries */ /* 1, ..., ULP with random complex angles on the diagonal */ /* and random O(1) entries in the upper triangle. */ /* (15) A matrix of the form X' T X, where X has condition */ /* SQRT( ULP ) and T has "clustered" entries 1, ULP,..., ULP */ /* with random complex angles on the diagonal and random O(1) */ /* entries in the upper triangle. */ /* (16) A matrix of the form X' T X, where X has condition */ /* SQRT( ULP ) and T has complex eigenvalues randomly chosen */ /* from ULP < |z| < 1 and random O(1) entries in the upper */ /* triangle. */ /* (17) Same as (16), but multiplied by a constant */ /* near the overflow threshold */ /* (18) Same as (16), but multiplied by a constant */ /* near the underflow threshold */ /* (19) Nonsymmetric matrix with random entries chosen from |z| < 1 */ /* If N is at least 4, all entries in first two rows and last */ /* row, and first column and last two columns are zero. */ /* (20) Same as (19), but multiplied by a constant */ /* near the overflow threshold */ /* (21) Same as (19), but multiplied by a constant */ /* near the underflow threshold */ /* Arguments */ /* ========== */ /* NSIZES (input) INTEGER */ /* The number of sizes of matrices to use. If it is zero, */ /* ZDRVEV does nothing. It must be at least zero. */ /* NN (input) INTEGER array, dimension (NSIZES) */ /* An array containing the sizes to be used for the matrices. */ /* Zero values will be skipped. The values must be at least */ /* zero. */ /* NTYPES (input) INTEGER */ /* The number of elements in DOTYPE. If it is zero, ZDRVEV */ /* does nothing. It must be at least zero. If it is MAXTYP+1 */ /* and NSIZES is 1, then an additional type, MAXTYP+1 is */ /* defined, which is to use whatever matrix is in A. This */ /* is only useful if DOTYPE(1:MAXTYP) is .FALSE. and */ /* DOTYPE(MAXTYP+1) is .TRUE. . */ /* DOTYPE (input) LOGICAL array, dimension (NTYPES) */ /* If DOTYPE(j) is .TRUE., then for each size in NN a */ /* matrix of that size and of type j will be generated. */ /* If NTYPES is smaller than the maximum number of types */ /* defined (PARAMETER MAXTYP), then types NTYPES+1 through */ /* MAXTYP will not be generated. If NTYPES is larger */ /* than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES) */ /* will be ignored. */ /* ISEED (input/output) INTEGER array, dimension (4) */ /* On entry ISEED specifies the seed of the random number */ /* generator. The array elements should be between 0 and 4095; */ /* if not they will be reduced mod 4096. Also, ISEED(4) must */ /* be odd. The random number generator uses a linear */ /* congruential sequence limited to small integers, and so */ /* should produce machine independent random numbers. The */ /* values of ISEED are changed on exit, and can be used in the */ /* next call to ZDRVEV to continue the same random number */ /* sequence. */ /* THRESH (input) DOUBLE PRECISION */ /* A test will count as "failed" if the "error", computed as */ /* described above, exceeds THRESH. Note that the error */ /* is scaled to be O(1), so THRESH should be a reasonably */ /* small multiple of 1, e.g., 10 or 100. In particular, */ /* it should not depend on the precision (single vs. double) */ /* or the size of the matrix. It must be at least zero. */ /* NOUNIT (input) INTEGER */ /* The FORTRAN unit number for printing out error messages */ /* (e.g., if a routine returns INFO not equal to 0.) */ /* A (workspace) COMPLEX*16 array, dimension (LDA, max(NN)) */ /* Used to hold the matrix whose eigenvalues are to be */ /* computed. On exit, A contains the last matrix actually used. */ /* LDA (input) INTEGER */ /* The leading dimension of A, and H. LDA must be at */ /* least 1 and at least max(NN). */ /* H (workspace) COMPLEX*16 array, dimension (LDA, max(NN)) */ /* Another copy of the test matrix A, modified by ZGEEV. */ /* W (workspace) COMPLEX*16 array, dimension (max(NN)) */ /* The eigenvalues of A. On exit, W are the eigenvalues of */ /* the matrix in A. */ /* W1 (workspace) COMPLEX*16 array, dimension (max(NN)) */ /* Like W, this array contains the eigenvalues of A, */ /* but those computed when ZGEEV only computes a partial */ /* eigendecomposition, i.e. not the eigenvalues and left */ /* and right eigenvectors. */ /* VL (workspace) COMPLEX*16 array, dimension (LDVL, max(NN)) */ /* VL holds the computed left eigenvectors. */ /* LDVL (input) INTEGER */ /* Leading dimension of VL. Must be at least max(1,max(NN)). */ /* VR (workspace) COMPLEX*16 array, dimension (LDVR, max(NN)) */ /* VR holds the computed right eigenvectors. */ /* LDVR (input) INTEGER */ /* Leading dimension of VR. Must be at least max(1,max(NN)). */ /* LRE (workspace) COMPLEX*16 array, dimension (LDLRE, max(NN)) */ /* LRE holds the computed right or left eigenvectors. */ /* LDLRE (input) INTEGER */ /* Leading dimension of LRE. Must be at least max(1,max(NN)). */ /* RESULT (output) DOUBLE PRECISION array, dimension (7) */ /* The values computed by the seven tests described above. */ /* The values are currently limited to 1/ulp, to avoid */ /* overflow. */ /* WORK (workspace) COMPLEX*16 array, dimension (NWORK) */ /* NWORK (input) INTEGER */ /* The number of entries in WORK. This must be at least */ /* 5*NN(j)+2*NN(j)**2 for all j. */ /* RWORK (workspace) DOUBLE PRECISION array, dimension (2*max(NN)) */ /* IWORK (workspace) INTEGER array, dimension (max(NN)) */ /* INFO (output) INTEGER */ /* If 0, then everything ran OK. */ /* -1: NSIZES < 0 */ /* -2: Some NN(j) < 0 */ /* -3: NTYPES < 0 */ /* -6: THRESH < 0 */ /* -9: LDA < 1 or LDA < NMAX, where NMAX is max( NN(j) ). */ /* -14: LDVL < 1 or LDVL < NMAX, where NMAX is max( NN(j) ). */ /* -16: LDVR < 1 or LDVR < NMAX, where NMAX is max( NN(j) ). */ /* -18: LDLRE < 1 or LDLRE < NMAX, where NMAX is max( NN(j) ). */ /* -21: NWORK too small. */ /* If ZLATMR, CLATMS, CLATME or ZGEEV returns an error code, */ /* the absolute value of it is returned. */ /* ----------------------------------------------------------------------- */ /* Some Local Variables and Parameters: */ /* ---- ----- --------- --- ---------- */ /* ZERO, ONE Real 0 and 1. */ /* MAXTYP The number of types defined. */ /* NMAX Largest value in NN. */ /* NERRS The number of tests which have exceeded THRESH */ /* COND, CONDS, */ /* IMODE Values to be passed to the matrix generators. */ /* ANORM Norm of A; passed to matrix generators. */ /* OVFL, UNFL Overflow and underflow thresholds. */ /* ULP, ULPINV Finest relative precision and its inverse. */ /* RTULP, RTULPI Square roots of the previous 4 values. */ /* The following four arrays decode JTYPE: */ /* KTYPE(j) The general type (1-10) for type "j". */ /* KMODE(j) The MODE value to be passed to the matrix */ /* generator for type "j". */ /* KMAGN(j) The order of magnitude ( O(1), */ /* O(overflow^(1/2) ), O(underflow^(1/2) ) */ /* KCONDS(j) Selectw whether CONDS is to be 1 or */ /* 1/sqrt(ulp). (0 means irrelevant.) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nn; --dotype; --iseed; h_dim1 = *lda; h_offset = 1 + h_dim1; h__ -= h_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --w; --w1; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1; vr -= vr_offset; lre_dim1 = *ldlre; lre_offset = 1 + lre_dim1; lre -= lre_offset; --result; --work; --rwork; --iwork; /* Function Body */ /* .. */ /* .. Executable Statements .. */ s_copy(path, "Zomplex precision", (ftnlen)1, (ftnlen)17); s_copy(path + 1, "EV", (ftnlen)2, (ftnlen)2); /* Check for errors */ ntestt = 0; ntestf = 0; *info = 0; /* Important constants */ badnn = FALSE_; nmax = 0; i__1 = *nsizes; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = nmax, i__3 = nn[j]; nmax = max(i__2,i__3); if (nn[j] < 0) { badnn = TRUE_; } /* L10: */ } /* Check for errors */ if (*nsizes < 0) { *info = -1; } else if (badnn) { *info = -2; } else if (*ntypes < 0) { *info = -3; } else if (*thresh < 0.) { *info = -6; } else if (*nounit <= 0) { *info = -7; } else if (*lda < 1 || *lda < nmax) { *info = -9; } else if (*ldvl < 1 || *ldvl < nmax) { *info = -14; } else if (*ldvr < 1 || *ldvr < nmax) { *info = -16; } else if (*ldlre < 1 || *ldlre < nmax) { *info = -28; } else /* if(complicated condition) */ { /* Computing 2nd power */ i__1 = nmax; if (nmax * 5 + (i__1 * i__1 << 1) > *nwork) { *info = -21; } } if (*info != 0) { i__1 = -(*info); xerbla_("ZDRVEV", &i__1); return 0; } /* Quick return if nothing to do */ if (*nsizes == 0 || *ntypes == 0) { return 0; } /* More Important constants */ unfl = dlamch_("Safe minimum"); ovfl = 1. / unfl; dlabad_(&unfl, &ovfl); ulp = dlamch_("Precision"); ulpinv = 1. / ulp; rtulp = sqrt(ulp); rtulpi = 1. / rtulp; /* Loop over sizes, types */ nerrs = 0; i__1 = *nsizes; for (jsize = 1; jsize <= i__1; ++jsize) { n = nn[jsize]; if (*nsizes != 1) { mtypes = min(21,*ntypes); } else { mtypes = min(22,*ntypes); } i__2 = mtypes; for (jtype = 1; jtype <= i__2; ++jtype) { if (! dotype[jtype]) { goto L260; } /* Save ISEED in case of an error. */ for (j = 1; j <= 4; ++j) { ioldsd[j - 1] = iseed[j]; /* L20: */ } /* Compute "A" */ /* Control parameters: */ /* KMAGN KCONDS KMODE KTYPE */ /* =1 O(1) 1 clustered 1 zero */ /* =2 large large clustered 2 identity */ /* =3 small exponential Jordan */ /* =4 arithmetic diagonal, (w/ eigenvalues) */ /* =5 random log symmetric, w/ eigenvalues */ /* =6 random general, w/ eigenvalues */ /* =7 random diagonal */ /* =8 random symmetric */ /* =9 random general */ /* =10 random triangular */ if (mtypes > 21) { goto L90; } itype = ktype[jtype - 1]; imode = kmode[jtype - 1]; /* Compute norm */ switch (kmagn[jtype - 1]) { case 1: goto L30; case 2: goto L40; case 3: goto L50; } L30: anorm = 1.; goto L60; L40: anorm = ovfl * ulp; goto L60; L50: anorm = unfl * ulpinv; goto L60; L60: zlaset_("Full", lda, &n, &c_b1, &c_b1, &a[a_offset], lda); iinfo = 0; cond = ulpinv; /* Special Matrices -- Identity & Jordan block */ /* Zero */ if (itype == 1) { iinfo = 0; } else if (itype == 2) { /* Identity */ i__3 = n; for (jcol = 1; jcol <= i__3; ++jcol) { i__4 = jcol + jcol * a_dim1; z__1.r = anorm, z__1.i = 0.; a[i__4].r = z__1.r, a[i__4].i = z__1.i; /* L70: */ } } else if (itype == 3) { /* Jordan Block */ i__3 = n; for (jcol = 1; jcol <= i__3; ++jcol) { i__4 = jcol + jcol * a_dim1; z__1.r = anorm, z__1.i = 0.; a[i__4].r = z__1.r, a[i__4].i = z__1.i; if (jcol > 1) { i__4 = jcol + (jcol - 1) * a_dim1; a[i__4].r = 1., a[i__4].i = 0.; } /* L80: */ } } else if (itype == 4) { /* Diagonal Matrix, [Eigen]values Specified */ zlatms_(&n, &n, "S", &iseed[1], "H", &rwork[1], &imode, &cond, &anorm, &c__0, &c__0, "N", &a[a_offset], lda, &work[ n + 1], &iinfo); } else if (itype == 5) { /* Hermitian, eigenvalues specified */ zlatms_(&n, &n, "S", &iseed[1], "H", &rwork[1], &imode, &cond, &anorm, &n, &n, "N", &a[a_offset], lda, &work[n + 1], &iinfo); } else if (itype == 6) { /* General, eigenvalues specified */ if (kconds[jtype - 1] == 1) { conds = 1.; } else if (kconds[jtype - 1] == 2) { conds = rtulpi; } else { conds = 0.; } zlatme_(&n, "D", &iseed[1], &work[1], &imode, &cond, &c_b2, " ", "T", "T", "T", &rwork[1], &c__4, &conds, &n, &n, &anorm, &a[a_offset], lda, &work[(n << 1) + 1], & iinfo); } else if (itype == 7) { /* Diagonal, random eigenvalues */ zlatmr_(&n, &n, "D", &iseed[1], "N", &work[1], &c__6, &c_b38, &c_b2, "T", "N", &work[n + 1], &c__1, &c_b38, &work[( n << 1) + 1], &c__1, &c_b38, "N", idumma, &c__0, & c__0, &c_b48, &anorm, "NO", &a[a_offset], lda, &iwork[ 1], &iinfo); } else if (itype == 8) { /* Symmetric, random eigenvalues */ zlatmr_(&n, &n, "D", &iseed[1], "H", &work[1], &c__6, &c_b38, &c_b2, "T", "N", &work[n + 1], &c__1, &c_b38, &work[( n << 1) + 1], &c__1, &c_b38, "N", idumma, &n, &n, & c_b48, &anorm, "NO", &a[a_offset], lda, &iwork[1], & iinfo); } else if (itype == 9) { /* General, random eigenvalues */ zlatmr_(&n, &n, "D", &iseed[1], "N", &work[1], &c__6, &c_b38, &c_b2, "T", "N", &work[n + 1], &c__1, &c_b38, &work[( n << 1) + 1], &c__1, &c_b38, "N", idumma, &n, &n, & c_b48, &anorm, "NO", &a[a_offset], lda, &iwork[1], & iinfo); if (n >= 4) { zlaset_("Full", &c__2, &n, &c_b1, &c_b1, &a[a_offset], lda); i__3 = n - 3; zlaset_("Full", &i__3, &c__1, &c_b1, &c_b1, &a[a_dim1 + 3] , lda); i__3 = n - 3; zlaset_("Full", &i__3, &c__2, &c_b1, &c_b1, &a[(n - 1) * a_dim1 + 3], lda); zlaset_("Full", &c__1, &n, &c_b1, &c_b1, &a[n + a_dim1], lda); } } else if (itype == 10) { /* Triangular, random eigenvalues */ zlatmr_(&n, &n, "D", &iseed[1], "N", &work[1], &c__6, &c_b38, &c_b2, "T", "N", &work[n + 1], &c__1, &c_b38, &work[( n << 1) + 1], &c__1, &c_b38, "N", idumma, &n, &c__0, & c_b48, &anorm, "NO", &a[a_offset], lda, &iwork[1], & iinfo); } else { iinfo = 1; } if (iinfo != 0) { io___31.ciunit = *nounit; s_wsfe(&io___31); do_fio(&c__1, "Generator", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); return 0; } L90: /* Test for minimal and generous workspace */ for (iwk = 1; iwk <= 2; ++iwk) { if (iwk == 1) { nnwork = n << 1; } else { /* Computing 2nd power */ i__3 = n; nnwork = n * 5 + (i__3 * i__3 << 1); } nnwork = max(nnwork,1); /* Initialize RESULT */ for (j = 1; j <= 7; ++j) { result[j] = -1.; /* L100: */ } /* Compute eigenvalues and eigenvectors, and test them */ zlacpy_("F", &n, &n, &a[a_offset], lda, &h__[h_offset], lda); zgeev_("V", "V", &n, &h__[h_offset], lda, &w[1], &vl[ vl_offset], ldvl, &vr[vr_offset], ldvr, &work[1], & nnwork, &rwork[1], &iinfo); if (iinfo != 0) { result[1] = ulpinv; io___34.ciunit = *nounit; s_wsfe(&io___34); do_fio(&c__1, "ZGEEV1", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); goto L220; } /* Do Test (1) */ zget22_("N", "N", "N", &n, &a[a_offset], lda, &vr[vr_offset], ldvr, &w[1], &work[1], &rwork[1], res); result[1] = res[0]; /* Do Test (2) */ zget22_("C", "N", "C", &n, &a[a_offset], lda, &vl[vl_offset], ldvl, &w[1], &work[1], &rwork[1], res); result[2] = res[0]; /* Do Test (3) */ i__3 = n; for (j = 1; j <= i__3; ++j) { tnrm = dznrm2_(&n, &vr[j * vr_dim1 + 1], &c__1); /* Computing MAX */ /* Computing MIN */ d__4 = ulpinv, d__5 = (d__1 = tnrm - 1., abs(d__1)) / ulp; d__2 = result[3], d__3 = min(d__4,d__5); result[3] = max(d__2,d__3); vmx = 0.; vrmx = 0.; i__4 = n; for (jj = 1; jj <= i__4; ++jj) { vtst = z_abs(&vr[jj + j * vr_dim1]); if (vtst > vmx) { vmx = vtst; } i__5 = jj + j * vr_dim1; if (d_imag(&vr[jj + j * vr_dim1]) == 0. && (d__1 = vr[ i__5].r, abs(d__1)) > vrmx) { i__6 = jj + j * vr_dim1; vrmx = (d__2 = vr[i__6].r, abs(d__2)); } /* L110: */ } if (vrmx / vmx < 1. - ulp * 2.) { result[3] = ulpinv; } /* L120: */ } /* Do Test (4) */ i__3 = n; for (j = 1; j <= i__3; ++j) { tnrm = dznrm2_(&n, &vl[j * vl_dim1 + 1], &c__1); /* Computing MAX */ /* Computing MIN */ d__4 = ulpinv, d__5 = (d__1 = tnrm - 1., abs(d__1)) / ulp; d__2 = result[4], d__3 = min(d__4,d__5); result[4] = max(d__2,d__3); vmx = 0.; vrmx = 0.; i__4 = n; for (jj = 1; jj <= i__4; ++jj) { vtst = z_abs(&vl[jj + j * vl_dim1]); if (vtst > vmx) { vmx = vtst; } i__5 = jj + j * vl_dim1; if (d_imag(&vl[jj + j * vl_dim1]) == 0. && (d__1 = vl[ i__5].r, abs(d__1)) > vrmx) { i__6 = jj + j * vl_dim1; vrmx = (d__2 = vl[i__6].r, abs(d__2)); } /* L130: */ } if (vrmx / vmx < 1. - ulp * 2.) { result[4] = ulpinv; } /* L140: */ } /* Compute eigenvalues only, and test them */ zlacpy_("F", &n, &n, &a[a_offset], lda, &h__[h_offset], lda); zgeev_("N", "N", &n, &h__[h_offset], lda, &w1[1], dum, &c__1, dum, &c__1, &work[1], &nnwork, &rwork[1], &iinfo); if (iinfo != 0) { result[1] = ulpinv; io___42.ciunit = *nounit; s_wsfe(&io___42); do_fio(&c__1, "ZGEEV2", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); goto L220; } /* Do Test (5) */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; if (w[i__4].r != w1[i__5].r || w[i__4].i != w1[i__5].i) { result[5] = ulpinv; } /* L150: */ } /* Compute eigenvalues and right eigenvectors, and test them */ zlacpy_("F", &n, &n, &a[a_offset], lda, &h__[h_offset], lda); zgeev_("N", "V", &n, &h__[h_offset], lda, &w1[1], dum, &c__1, &lre[lre_offset], ldlre, &work[1], &nnwork, &rwork[1], &iinfo); if (iinfo != 0) { result[1] = ulpinv; io___43.ciunit = *nounit; s_wsfe(&io___43); do_fio(&c__1, "ZGEEV3", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); goto L220; } /* Do Test (5) again */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; if (w[i__4].r != w1[i__5].r || w[i__4].i != w1[i__5].i) { result[5] = ulpinv; } /* L160: */ } /* Do Test (6) */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (jj = 1; jj <= i__4; ++jj) { i__5 = j + jj * vr_dim1; i__6 = j + jj * lre_dim1; if (vr[i__5].r != lre[i__6].r || vr[i__5].i != lre[ i__6].i) { result[6] = ulpinv; } /* L170: */ } /* L180: */ } /* Compute eigenvalues and left eigenvectors, and test them */ zlacpy_("F", &n, &n, &a[a_offset], lda, &h__[h_offset], lda); zgeev_("V", "N", &n, &h__[h_offset], lda, &w1[1], &lre[ lre_offset], ldlre, dum, &c__1, &work[1], &nnwork, & rwork[1], &iinfo); if (iinfo != 0) { result[1] = ulpinv; io___44.ciunit = *nounit; s_wsfe(&io___44); do_fio(&c__1, "ZGEEV4", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); goto L220; } /* Do Test (5) again */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; if (w[i__4].r != w1[i__5].r || w[i__4].i != w1[i__5].i) { result[5] = ulpinv; } /* L190: */ } /* Do Test (7) */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (jj = 1; jj <= i__4; ++jj) { i__5 = j + jj * vl_dim1; i__6 = j + jj * lre_dim1; if (vl[i__5].r != lre[i__6].r || vl[i__5].i != lre[ i__6].i) { result[7] = ulpinv; } /* L200: */ } /* L210: */ } /* End of Loop -- Check for RESULT(j) > THRESH */ L220: ntest = 0; nfail = 0; for (j = 1; j <= 7; ++j) { if (result[j] >= 0.) { ++ntest; } if (result[j] >= *thresh) { ++nfail; } /* L230: */ } if (nfail > 0) { ++ntestf; } if (ntestf == 1) { io___47.ciunit = *nounit; s_wsfe(&io___47); do_fio(&c__1, path, (ftnlen)3); e_wsfe(); io___48.ciunit = *nounit; s_wsfe(&io___48); e_wsfe(); io___49.ciunit = *nounit; s_wsfe(&io___49); e_wsfe(); io___50.ciunit = *nounit; s_wsfe(&io___50); e_wsfe(); io___51.ciunit = *nounit; s_wsfe(&io___51); do_fio(&c__1, (char *)&(*thresh), (ftnlen)sizeof( doublereal)); e_wsfe(); ntestf = 2; } for (j = 1; j <= 7; ++j) { if (result[j] >= *thresh) { io___52.ciunit = *nounit; s_wsfe(&io___52); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&iwk, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[j], (ftnlen)sizeof( doublereal)); e_wsfe(); } /* L240: */ } nerrs += nfail; ntestt += ntest; /* L250: */ } L260: ; } /* L270: */ } /* Summary */ dlasum_(path, nounit, &nerrs, &ntestt); return 0; /* End of ZDRVEV */ } /* zdrvev_ */
FTMEXT_METHOD_OBJECT(roots, NULL, obj) { roots_t *self = (roots_t *)FTMEXT_GET_EXT(); fts_object_t *obj = FTMEXT_GET_OBJECT(); int type; float * data; int size; int stride; int i; int cols; int rows; double complex * eigvalues; double complex * A; //double complex * AT; double * auxptr; int N; char JOBVL='N'; // Do not compute Right rootsenvectors char JOBVR='N'; // Do not compute Left rootsenvectors double complex DUMMY[1]; int LDVL=1; int LDVR=1; int LWORK; int INFO; double complex * WORK; double complex * RWORK; fmat_t * out_matx; if(obj != NULL){ type=fmat_or_fvec_vector_lock((fts_object_t *)obj,&data,&size,&stride); if((type!=2)||(stride!=1)){ ftmext_error((ftmext_t *)self,"UNSUPPORTED TYPE %d or STRIDE %d",type,stride); fmat_or_fvec_unlock((fts_object_t *)obj); } else{ rows=fmat_get_m((fmat_t *)obj); cols=fmat_get_n((fmat_t *)obj); if(!(((cols == 1)&&(rows > 1))||((cols > 1)&&(rows == 1)))){ ftmext_error((ftmext_t *)self,"INPUT MUST BE A SINGLE ROW OR COLUMN - ROWS %d COLS %d",rows,cols); fmat_or_fvec_unlock((fts_object_t *)obj); } else{ N=(rows*cols)-1; eigvalues=(double complex *)calloc(N,sizeof(double complex)); A=(double complex *)calloc(N*N,sizeof(double complex)); //AT=(double complex *)malloc(N*N*sizeof(double complex)); auxptr=(double *)A; LWORK=4*N; WORK = (double complex *)calloc(LWORK,sizeof(double complex)); RWORK = (double complex *)calloc(2*N,sizeof(double complex)); for(i=0;i<N;i++){ auxptr[(2*i)*N]=(-1.0f)*data[(i+1)]/data[0]; } for(i=0;i<(N-1);i++){ auxptr[((i*N)+1+i)*2]=(double)1.0f; } // for(i=0;i<(N*N);i++){ // maxext_post((ftmext_t *)self,"MATRIX BY ROWS REAL[%d]=%f",i,creal(A[i])); // maxext_post((ftmext_t *)self,"MATRIX BY ROWS IMAG[%d]=%f",i,cimag(A[i])); // } //zgeTranspose(AT,A,N); zgeev_( &JOBVL, &JOBVR, &N, A , &N , eigvalues , DUMMY, &LDVL, DUMMY, &LDVR, WORK, &LWORK, RWORK, &INFO ); //auxptr=(double *)eigvalues; //for(i=0;i<2*N;i++){ // data[i]=auxptr[i]; //} fmat_or_fvec_unlock((fts_object_t *)obj); out_matx=fmat_create(N,2); type=fmat_or_fvec_vector_lock((fts_object_t *)out_matx,&data,&size,&stride); auxptr=(double *)eigvalues; for(i=0;i<2*N;i++){ data[i]=(float)auxptr[i]; } fmat_or_fvec_unlock((fts_object_t *)out_matx); free(WORK); free(RWORK); //free(AT); free(eigvalues); free(A); } } if(self->obj != NULL) fts_object_release(self->obj); self->obj = obj; fts_object_refer(obj); ftmext_outlet_object((ftmext_t *)self, 0, (fts_object_t *)out_matx); } FTMEXT_METHOD_RETURN; }
static int doEig(Tcl_Interp *interp, Tcl_Obj *matrix, Tcl_Obj **ev, Tcl_Obj **V) { /* Compute eigen decomposition of matrix. * Return eigenvalues in ev. If V is not NULL, * also compute the eigenvectors */ /* Convert matrix to VecTcl object */ NumArrayInfo *info = NumArrayGetInfoFromObj(interp, matrix); if (!info) { return TCL_ERROR; } /* Check that it is a square matrix */ if (info->nDim != 2) { /* Could be a scalar. In this case return the trivial * decomposition */ if (ISSCALARINFO(info)) { *ev = Tcl_DuplicateObj(matrix); *V = Tcl_NewDoubleObj(1.0); return TCL_OK; } Tcl_SetResult(interp, "Eigendecomposition is only defined for square matrix", NULL); return TCL_ERROR; } /* get matrix dimensions */ long int m = info->dims[0]; long int n = info->dims[1]; if (m != n) { Tcl_SetResult(interp, "Eigendecomposition is only defined for square matrix", NULL); return TCL_ERROR; } int wantvectors = (V!=NULL); char *jobvr = wantvectors ? "V" : "N"; char *jobvl = "N"; /* Never compute left vectors */ if (info->type != NumArray_Complex128) { /* Real-valued matrix, prepare for dgeev */ /* create a column-major copy of matrix * This also converts an integer matrix to double */ Tcl_Obj *A = NumArrayNewMatrixColMaj(NumArray_Float64, m, n); NumArrayObjCopy(interp, matrix, A); Tcl_Obj *Vr = NULL; /* the right eigenvectors */ if (wantvectors) { /* create a real matrix for the eigenvectors Vr */ Vr = NumArrayNewMatrixColMaj(NumArray_Float64, m, m); } /* Extract the raw pointers from the VecTcl objects */ double *Aptr = NumArrayGetPtrFromObj(interp, A); double *Vrptr=NULL; if (wantvectors) { Vrptr = NumArrayGetPtrFromObj(interp, Vr); } /* Space to store the eigenvalues */ doublereal *wr = ckalloc(sizeof(doublereal)*n); doublereal *wi = ckalloc(sizeof(doublereal)*n); /* setup workspace arrays */ integer lwork = 4*n; doublereal* work=ckalloc(sizeof(doublereal)*lwork); /* Leading dimensions of A and Vr * Don't compute left vectors. */ integer lda = n; integer ldvr = n; integer ldvl = n; integer info; /* Subroutine int dgeev_ (Tcl_Interp *interp, char *jobvl, char *jobvr, * integer *n, doublereal * a, integer *lda, doublereal *wr, doublereal *wi, * doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr, * doublereal *work, integer *lwork, integer *info); */ /* call out to dgeev */ int errcode=dgeev_(interp, jobvl, jobvr, &n, Aptr, &lda, wr, wi, NULL, &ldvl, Vrptr, &ldvr, work, &lwork, &info); /* free workspace */ ckfree(work); /* A is overwritten with junk */ Tcl_DecrRefCount(A); if (errcode != TCL_OK) { /* release temporary storage for result */ if (wantvectors) { Tcl_DecrRefCount(Vr); } ckfree(wr); ckfree(wi); if (errcode > 0) { RESULTPRINTF(("DGEEV failed to converge at eigenvector %d ", info)); } return TCL_ERROR; } /* Now check, if the result is complex or real */ int real = 1; int i; for (i=0; i<n; i++) { if (wi[i]!=0.0) { real = 0; break; } } if (real) { /* create a real vector for the eigenvalues */ *ev = NumArrayNewVector(NumArray_Float64, n); double *evptr = NumArrayGetPtrFromObj(interp, *ev); /* Copy eigenvalues into this vector */ int i; for (i=0; i<n; i++) { evptr[i] = wr[i]; } /* Eigenvectors are contained in Vr */ if (wantvectors) { *V = Vr; } } else { /* create a complex vector for the eigenvalues */ *ev = NumArrayNewVector(NumArray_Complex128, n); NumArray_Complex *evptr = NumArrayGetPtrFromObj(interp, *ev); /* Copy eigenvalues into this vector */ int i, j; for (i=0; i<n; i++) { evptr[i] = NumArray_mkComplex(wr[i], wi[i]); } /* Create a complex matrix for the eigenvectors */ *V = NumArrayNewMatrixColMaj(NumArray_Complex128, n, n); /* Now, for real eigenvectors the columns of V contain * the vector. For complex conjugate pairs, the two columns * contain real and imaginary part of the conjugate pair (grumpf) */ NumArray_Complex *Vptr = NumArrayGetPtrFromObj(NULL, *V); #define V(i,j) Vptr[(i)+(j)*n] #define Vr(i, j) Vrptr[(i)+(j)*n] for (j=0; j<n; j++) { if (wi[j]==0.0) { /* real eigenvalue */ for (i=0; i<n; i++) { V(i,j) = NumArray_mkComplex(Vr(i,j), 0.0); } } else { /* complex conjugate pair */ for (i=0; i<n; i++) { V(i,j) = NumArray_mkComplex(Vr(i,j), Vr(i,j+1)); V(i,j+1) = NumArray_mkComplex(Vr(i,j), -Vr(i,j+1)); } j++; } } #undef V #undef Vr Tcl_DecrRefCount(Vr); } ckfree(wr); ckfree(wi); return TCL_OK; } else { /* Complex matrix, prepare for zgeev */ /* create a column-major copy of matrix */ Tcl_Obj *A = NumArrayNewMatrixColMaj(NumArray_Complex128, m, n); NumArrayObjCopy(interp, matrix, A); if (wantvectors) { /* create a real matrix for the eigenvectors Vr */ *V = NumArrayNewMatrixColMaj(NumArray_Complex128, m, m); } /* Extract the raw pointers from the VecTcl objects */ doublecomplex *Aptr = NumArrayGetPtrFromObj(interp, A); doublecomplex *Vrptr=NULL; if (wantvectors) { Vrptr = NumArrayGetPtrFromObj(interp, *V); } /* Space to store the eigenvalues */ *ev = NumArrayNewVector(NumArray_Complex128, n); doublecomplex *w = NumArrayGetPtrFromObj(NULL, *ev); /* setup workspace arrays */ integer lwork = 2*n; doublecomplex *work=ckalloc(sizeof(doublecomplex)*lwork); doublereal *rwork=ckalloc(sizeof(doublereal)*lwork); /* Leading dimensions of A and Vr * Don't compute left vectors. */ integer lda = n; integer ldvr = n; integer ldvl = n; integer info; /* Subroutine int zgeev_(Tcl_Interp *interp, char *jobvl, char *jobvr, * integer *n, doublecomplex *a, integer *lda, doublecomplex *w, * doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr, * doublecomplex *work, integer *lwork, doublereal *rwork, integer *info) */ /* call out to zgeev */ int errcode=zgeev_(interp, jobvl, jobvr, &n, Aptr, &lda, w, NULL, &ldvl, Vrptr, &ldvr, work, &lwork, rwork, &info); /* free workspace */ ckfree(work); ckfree(rwork); /* A is overwritten with junk */ Tcl_DecrRefCount(A); if (errcode != TCL_OK) { /* release temporary storage for result */ if (wantvectors) { Tcl_DecrRefCount(*V); } Tcl_DecrRefCount(*ev); if (errcode > 0) { RESULTPRINTF(("ZGEEV failed to converge at eigenvector %d ", info)); } return TCL_ERROR; } return TCL_OK; } }