HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
tetlapack_func_doubleonly.c
Go to the documentation of this file.
1 
7 #include "decs.h"
8 
13 extern int dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda,
14  double *w, double *work, int *lwork, int *info);
15 extern int dsyevr_(char *jobz, char *range, char *uplo, int *n, double *a, int *lda,
16  double *vl, double *vu, int *il, int *iu, double *abstol, int *M,
17  double *w,
18  double *z, int *ldz, int *isuppz,
19  double *work, int *lwork, int *iwork,
20  int *liwork, int *info);
21 //extern double dlamch_(char *);
22 
23 
24 #define LWORKSIZE MAX(NDIM*NDIM*NDIM,26*NDIM)
25 #define LIWORKSIZE MAX(NDIM*NDIM*NDIM,10*NDIM)
26 
27 
28 int tetlapack_func(double (*metr)[NDIM], double (*tetr)[NDIM], double eigenvalues[])
29 {
30  char jobz,uplo ;
31  int n,lda,lwork,info=0 ;
32  double a[NDIM][NDIM],w[NDIM]={0},work[LWORKSIZE]={0};
33  int chk;
34  int j,k ;
35 
36 
37  jobz = 'V' ;
38  uplo = 'U' ;
39  n = NDIM ;
40  lda = NDIM ;
41  lwork = LWORKSIZE ;
42 
43 
44 #if(USINGLAPACK)
45  DLOOP(j,k) a[j][k] = (double)metr[j][k] ;
46 
47  chk = dsyev_(
48  &jobz, /* job: 'V' -> compute eigenvectors too */
49  &uplo, /* which part of a is stored, 'U' -> upper */
50  &n, /* order of matrix a */
51  (double *)a, /* matrix (row major order) */
52  &lda, /* leading dimension of a */
53  w, /* eigenvalues, ascending order */
54  work, /* workspace */
55  &lwork, /* size of workspace */
56  &info /* successful? */
57  ) ;
58 
59 
60  if(info>0 && 0){
61 
62  dualfprintf(fail_file,"issue with dsyev: info=%d\n",info);
63 
64  // doesn't seem to work (gives wrong results)
65  // gives right eigenvalues but not right eigenvectors
66  int liwork,iwork[LIWORKSIZE] ;
67 
68  liwork = LIWORKSIZE ;
69  // then dsyev failed for some reason, try another algorithm
70 
71  // try dsyevr:
72  // http://www.gfd-dennou.org/arch/ruby/products/ruby-lapack/doc/dsy.html
73  // http://www.netlib.org/lapack/double/dsyevr.f
74  DLOOP(j,k) a[j][k] = (double)metr[j][k] ;
75 
76  char range = 'A';
77  double vl=0;
78  double vu=1E30; // a big double
79  int il=1;
80  int iu=NDIM;
81  char cmach='s';
82  //double abstol=_dlamch(&cmach);
83 #define NUMEPSILONDBL ((double)(2.2204460492503131e-16))
84  double abstol=(double)(100.0*NUMEPSILONDBL); // has to stay as double precision
85  int M; // output
86  double z[NDIM][NDIM]; // output
87  int ldz=NDIM;
88  int isuppz[2*NDIM]; // output
89  chk = dsyevr_(
90  &jobz, /* job: 'V' -> compute eigenvectors too */
91  &range,
92  &uplo, /* which part of a is stored, 'U' -> upper */
93  &n, /* order of matrix a */
94  (double *)a, /* matrix (row major order) */
95  &lda, /* leading dimension of a */
96  &vl,&vu,&il,&iu,&abstol,&M,
97  w, /* eigenvalues, ascending order */
98  (double *)z,&ldz,isuppz,
99  work, /* workspace */
100  &lwork, /* size of workspace */
101  iwork, /* size of iwork */
102  &liwork, /* working array for optimal liwork */
103  &info /* successful? */
104  ) ;
105 
106  if(info!=0) dualfprintf(fail_file,"issue with dsyevr: info=%d\n",info);
107 
108  }
109 
110 
111 
112 
113 
114 #else
115  info=-1;
116  dualfprintf(fail_file,"No LAPACK!\n");
117  myexit(873483746);
118 #endif
119 
120  // note a[j][k] corresponds to a[j=which eigenvector][k=which component]
121  // however order of j is that of order of eigenvalues that is ascending
122 
123  // sign of eigenvalue is necessary to get signature of eigenvector correct so that basis has same handedness as original basis
124  // the below fixes the time-component in test, but not r-component where r-r term was negative what it should be
125  DLOOP(j,k) tetr[j][k] = (double)(a[j][k]/sqrt(fabs(w[j])+SMALL)*sign(w[j]));
126 
127  // still, sign isn't right
128  // ensure signature same as minkowski
129  DLOOPA(j){
130  if(sign(tetr[j][j])!=sign(mink(j,j))){
131  // no, in simplest case tetr is Kronecker delta, not Minkowski, so that nothing happens to vector if already in Minkowski
132  // if(sign(tetr[j][j])!=sign(1.0)){
133  // well, maybe still so
134  DLOOPA(k) tetr[j][k]*=-1.0;
135  }
136  }
137 
138  /*
139  DLOOP(j,k) stderrfprintf("chk3 %d %d %g %g\n",j,k,a[j][k],w[j]) ;
140  */
141 
143  //
144  // copy over eigenvalues
145  //
147  DLOOPA(j){
148  eigenvalues[j]=(double)w[j];
149  }
150 
151 
152  return(info);
153 
154 }