From a8dcc5d297bccf3ec4f5f676c8a1f9bab24f8581 Mon Sep 17 00:00:00 2001 From: jiri Date: Fri, 25 Feb 2005 16:26:47 +0000 Subject: [PATCH] *** empty log message *** --- nonclass.cc | 140 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 9 deletions(-) diff --git a/nonclass.cc b/nonclass.cc index 7829e14..4fa04f5 100644 --- a/nonclass.cc +++ b/nonclass.cc @@ -6,6 +6,7 @@ extern "C" { #include "smat.h" #include "mat.h" #include "nonclass.h" +#include "qsort.h" #ifdef FORTRAN_ @@ -228,8 +229,8 @@ void diagonalize(NRMat &a, NRVec &w, const bool eivec, int ldb=0; if(b) ldb=b->ncols(); // First call is to determine size of workspace - if(b) FORNAME(dsygv)(&itype,&vectors, &U, &n, a, &m, *b, &ldb, w, (double *)&WORKX, &LWORK, &r ); - else FORNAME(dsyev)(&vectors, &U, &n, a, &m, w, (double *)&WORKX, &LWORK, &r ); + if(b) FORNAME(dsygv)(&itype,&vectors, &U, &n, a, &m, *b, &ldb, w, &WORKX, &LWORK, &r ); + else FORNAME(dsyev)(&vectors, &U, &n, a, &m, w, &WORKX, &LWORK, &r ); LWORK = (int)WORKX; double *WORK = new double[LWORK]; if(b) FORNAME(dsygv)(&itype,&vectors, &U, &n, a, &m, *b,&ldb, w, WORK, &LWORK, &r ); @@ -318,7 +319,7 @@ void singular_decomposition(NRMat &a, NRMat *u, NRVec &s lwork = (int) work0; double *work = new double[lwork]; FORNAME(dgesvd)(&jobv, &jobu, &n, &m, a, &n0, s, v?(*v)[0]:0, &n0, - u?(*u)[0]:0, &m0, &work0, &lwork, &r); + u?(*u)[0]:0, &m0, work, &lwork, &r); delete[] work; if (v && corder) v->transposeme(n); @@ -336,8 +337,45 @@ extern "C" void FORNAME(dggev)(const char *JOBVL, const char *JOBVR, const int * double *VL, const int *LDVL, double *VR, const int *LDVR, double *WORK, const int *LWORK, int *INFO ); + +//statics for sorting +static int *gdperm; +static double *gdwr, *gdwi; + +//compare methods +static double realonly(const int i, const int j) +{ +double tmp = gdwr[i]-gdwr[j]; +if(tmp) return tmp; +return gdwi[j]-gdwi[i]; +} + +static double realfirst(const int i, const int j) +{ +if(gdwi[i] && ! gdwi[j]) return 1.; +if(!gdwi[i] && gdwi[j]) return -1.; +double tmp = gdwr[i]-gdwr[j]; +if(tmp) return tmp; +return gdwi[j]-gdwi[i]; +} + +static double (* gdcompar[2])(const int, const int) = {&realonly, &realfirst}; + +//swap method +static void gdswap(const int i, const int j) +{ +double tmp; +int itmp; +itmp=gdperm[i]; gdperm[i]=gdperm[j]; gdperm[j]=itmp; +tmp=gdwr[i]; gdwr[i]=gdwr[j]; gdwr[j]=tmp; +tmp=gdwi[i]; gdwi[i]=gdwi[j]; gdwi[j]=tmp; +} + + + void gdiagonalize(NRMat &a, NRVec &wr, NRVec &wi, NRMat *vl, NRMat *vr, const bool corder, int n, + const int sorttype, const bool biorthonormalize, NRMat *b, NRVec *beta) { if(n<=0) n = a.nrows(); @@ -378,23 +416,107 @@ void gdiagonalize(NRMat &a, NRVec &wr, NRVec &wi, lwork = (int) work0; double *work = new double[lwork]; if(b) FORNAME(dggev)(&jobvr, &jobvl, &n, a, &lda, *b, &ldb, wr, wi, *beta, vr?vr[0]:(double *)0, - &ldvr, vl?vl[0]:(double *)0, &ldvl, &work0, &lwork, &r); + &ldvr, vl?vl[0]:(double *)0, &ldvl, work, &lwork, &r); else FORNAME(dgeev)(&jobvr, &jobvl, &n, a, &lda, wr, wi, vr?vr[0]:(double *)0, - &ldvr, vl?vl[0]:(double *)0, &ldvl, &work0, &lwork, &r); + &ldvr, vl?vl[0]:(double *)0, &ldvl, work, &lwork, &r); delete[] work; + if (r < 0) laerror("illegal argument in ggev/geev in gdiagonalize()"); + if (r > 0) laerror("convergence problem in ggev/geev in gdiagonalize()"); + + if(biorthonormalize && vl && vr) + { + if(b || beta) laerror("biorthonormalize not implemented yet for generalized non-symmetric eiugenproblem");//metric b would be needed + int i=0; + while(i0) + { + if(b || beta) laerror("sort not implemented yet for generalized non-symmetric eiugenproblem"); + NRVec perm(n); + for(int i=0; itransposeme(n); if (vr) vr->transposeme(n); } - if (r < 0) laerror("illegal argument in ggev/geev in gdiagonalize()"); - if (r > 0) laerror("convergence problem in ggev/geev in gdiagonalize()"); } + void gdiagonalize(NRMat &a, NRVec< complex > &w, NRMat< complex >*vl, NRMat< complex > *vr, - const bool corder, int n,NRMat *b, NRVec *beta) + const bool corder, int n, const int sorttype, const bool biorthonormalize, + NRMat *b, NRVec *beta) { if(!corder) laerror("gdiagonalize() corder 0 not implemented"); if(n<=0) n = a.nrows(); @@ -405,7 +527,7 @@ void gdiagonalize(NRMat &a, NRVec< complex > &w, NRMat *rvr = 0; if (vl) rvl = new NRMat(n, n); if (vr) rvr = new NRMat(n, n); - gdiagonalize(a, wr, wi, rvl, rvr, 0, n, b, beta); + gdiagonalize(a, wr, wi, rvl, rvr, 0, n, sorttype, biorthonormalize, b, beta); //process the results into complex matrices int i;