HΦ  3.2.0
matrixlapack.c
Go to the documentation of this file.
1 /* HPhi - Quantum Lattice Model Simulator */
2 /* Copyright (C) 2015 The University of Tokyo */
3 
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 /*-------------------------------------------------------------
17  *[ver.2009.05.25]
18  *-------------------------------------------------------------
19  * Copyright (C) 2007-2009 Daisuke Tahara. All rights reserved.
20  * Copyright (C) 2009- Takahiro Misawa. All rights reserved.
21  * Some functions are added by TM.
22  *-------------------------------------------------------------*/
23 /*=================================================================================================*/
24 
25 #include "matrixlapack.h"
26 #include <stdlib.h>
38 int dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
39 int dgetri_(int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info);
40 
41 #ifdef SR
42 int dsyevd_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *iwork, int *liwork, int *info);
43 int M_DSYEV(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *iwork, int *liwork, int *info);
44 int zheevd_(char *jobz, char *uplo, int *n, double complex *a, int *lda, double *w, double complex *work, int *lwork, double *rwork, int *iwork, int *liwork, int *info);
45 #else
46 int dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info);
47 int M_DSYEV(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info);
48 double dlamch_(char *cmach);
49 int zheev_(char *jobz, char *uplo, int *n, double complex *a, int *lda, double *w, double complex *work, int *lwork, double *rwork, int *info);
50 #endif
51 
52 int dsyevx_(char *jobz, char *range, char *uplo, int *n, double *a, int *lda, double *vl, double *vu,
53  int *il, int *iu, double *abstol, int *m, double *w, double *z__, int *ldz,
54  double *work, int *lwork, int *iwork, int *ifail, int *info);
55 
56 
66 void to_f(
67 int N,
68 int M,
69 double **A,
70 double *a
71 ){
72  int i,j,k;
73  k=0;
74  for(j=0;j<M;j++){
75  for(i=0;i<N;i++){
76  a[k] = A[i][j];
77  k++;
78  }
79  }
80 }
81 
93 int DSEVvalue(int xNsize, double **A, double *r){
94 
95  int k;
96  char jobz, uplo;
97  int n, lda, lwork, info;
98  double *a, *w, *work;
99 #ifdef SR
100  int *iwork, liwork;
101  liwork = 5 * xNsize + 3;
102  iwork = (int*)malloc(liwork * sizeof(double));
103 #endif
104 
105  n = lda = xNsize;
106  lwork = 4*xNsize; /* 3*xNsize OK?*/
107 
108  a = (double*)malloc(xNsize*xNsize*sizeof(double));
109  w = (double*)malloc(xNsize*sizeof(double));
110  work = (double*)malloc(lwork*sizeof(double));
111 
112  to_f(xNsize, xNsize, A, a);
113 
114  jobz = 'N';
115  uplo = 'U';
116 
117 #ifdef SR
118  M_DSYEV(&jobz, &uplo, &n, a, &lda, w, work, &lwork, &iwork, &liwork, &info);
119  free(iwork);
120 #else
121  M_DSYEV(&jobz, &uplo, &n, a, &lda, w, work, &lwork, &info);
122 #endif
123 
124  if(info != 0){
125  free(a);
126  free(w);
127  free(work);
128  return 0;
129  }
130 
131  for(k=0;k<xNsize;k++){
132  r[k] = w[k];
133  }
134 
135  free(a);
136  free(w);
137  free(work);
138 
139  return 1;
140 }
141 
153 int DInv(int xNsize, double **xM, double **xIM){
154 
155  int i,j,k;
156  int m,n,lda,info,*piv,lwork;
157  double *work;
158  double *a;
159 
160  m=n=lda=lwork=xNsize;
161 
162  a = (double*)malloc(xNsize*xNsize*sizeof(double));
163  work = (double*)malloc(xNsize*sizeof(double));
164  piv = (int*)malloc(xNsize*sizeof(int));
165 
166  k=0;
167  for(j=0;j<xNsize;j++){
168  for(i=0;i<xNsize;i++){
169  a[k] = xM[i][j];
170  k++;
171  }
172  }
173 
174  dgetrf_(&m, &n, a, &lda, piv, &info);
175  dgetri_(&n, a, &lda, piv, work, &lwork, &info);
176 
177  if(info != 0){
178  free(a);
179  free(work);
180  free(piv);
181  return 0;
182  }
183 
184  for(k=0;k<xNsize*xNsize;k++){
185  xIM[k%xNsize][k/xNsize] = a[k];
186  }
187  free(a);
188  free(work);
189  free(piv);
190 
191  return 1;
192 }
193 
194 // added by Misawa 20090309
195 // obtain eigen vectors
209 int DSEVvector(int xNsize, double **A, double *r, double **vec ){
210 
211  int i,j,k;
212  char jobz, uplo;
213  int n, lda, lwork, info;
214  double *a, *w, *work;
215 #ifdef SR
216  int *iwork, liwork;
217  liwork = 5 * xNsize + 3;
218  iwork = (int*)malloc(liwork * sizeof(double));
219  lwork = 2 * xNsize * xNsize + 6 * xNsize + 1; /* 3*xNsize OK?*/
220 #else
221  lwork = 4 * xNsize; /* 3*xNsize OK?*/
222 #endif
223 
224  n = lda = xNsize;
225 
226  a = (double*)malloc(xNsize*xNsize*sizeof(double));
227  w = (double*)malloc(xNsize*sizeof(double));
228  work = (double*)malloc(lwork*sizeof(double));
229 
230  k=0;
231  for(j=0;j<xNsize;j++){
232  for(i=0;i<xNsize;i++){
233  a[k] = A[i][j];
234  k++;
235  }
236  }
237 
238  jobz = 'V';
239  uplo = 'U';
240 
241 #ifdef SR
242  M_DSYEV(&jobz, &uplo, &n, a, &lda, w, work, &lwork, iwork, &liwork, &info);
243  free(iwork);
244 #else
245  dsyev_(&jobz, &uplo, &n, a, &lda, w, work, &lwork, &info);
246 #endif
247 
248  k=0;
249  for(i=0;i<xNsize;i++){
250  for(j=0;j<xNsize;j++){
251  vec[i][j]=a[k];
252  k++;
253  }
254  }
255 
256  if(info != 0){
257  free(a);
258  free(w);
259  free(work);
260  return 0;
261  }
262 
263  for(k=0;k<xNsize;k++){
264  r[k] = w[k];
265  }
266 
267  free(a);
268  free(w);
269  free(work);
270 
271  return 1;
272 }
273 
274 
275 /* SX=rXとなるr,X (上からxNev個だけ求める 結果の格納箇所と書き換え箇所に注意)*/
290 int DSEVXU(int xNsize, double **A, double *r, double **X, int xNev){
291 
292  int i,j,k;
293  char jobz, range, uplo;
294  int n, lda, il, iu, m, ldz, lwork, *iwork, *ifail, info;
295  double *a, *w, *work, vl, vu, abstol, *z;
296 
297  n = lda = ldz = xNsize;
298  lwork = 8*xNsize;
299 
300  a = (double*)malloc(xNsize*xNsize*sizeof(double));
301  w = (double*)malloc(xNsize*sizeof(double));
302  z = (double*)malloc(xNsize*xNsize*sizeof(double));
303  work = (double*)malloc(lwork*sizeof(double));
304  iwork = (int*)malloc(5*xNsize*sizeof(int));
305  ifail = (int*)malloc(xNsize*sizeof(int));
306 
307 #ifdef SR
308  abstol = 0.0;
309 #else
310  abstol = 2.0*dlamch_("S");
311 #endif
312  vl = vu = 0.0;
313 
314  k=0;
315  for(j=0;j<xNsize;j++){
316  for(i=0;i<xNsize;i++){
317  a[k] = A[i][j];
318  k++;
319  }
320  }
321 
322  jobz = 'V';
323  range = 'I';
324  uplo = 'U';
325 
326  il = xNsize-xNev+1;
327  iu = xNsize;
328  m = iu-il+1;
329 
330  dsyevx_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol,
331  &m, w, z, &ldz, work, &lwork, iwork, ifail, &info);
332 
333  if(info != 0){
334  free(a);
335  free(w);
336  free(z);
337  free(work);
338  free(iwork);
339  free(ifail);
340  return 0;
341  }
342 
343  for(k=0;k<xNev;k++){
344  r[k+xNsize-xNev] = w[k];
345  }
346 
347  for(k=0;k<xNsize*xNev;k++){
348  X[k%xNsize][k/xNsize+xNsize-xNev] = z[k];
349  }
350  free(a);
351  free(w);
352  free(z);
353  free(work);
354  free(iwork);
355  free(ifail);
356 
357  return 1;
358 }
359 
360 //added by Misawa 130121
361 //For complex Hermite matrix
374 int ZHEEVall(int xNsize, double complex **A, double complex *r,double complex **vec){
375 
376  int i,j,k;
377  char jobz, uplo;
378  int n, lda, lwork, info, lrwork;
379  double *rwork;
380  double *w;
381  double complex *a, *work;
382 #ifdef SR
383  int *iwork, liwork;
384  liwork = 5 * xNsize + 3;
385  iwork = (int*)malloc(liwork * sizeof(double));
386 #endif
387 
388  n = lda = xNsize;
389 #ifdef SR
390  lwork = xNsize*xNsize + 2 * xNsize; /* 3*xNsize OK?*/
391  lrwork = 2 * xNsize*xNsize + 5*xNsize + 1;
392 #else
393  lwork = 4*xNsize; /* 3*xNsize OK?*/
394  lrwork = lwork;
395 #endif
396 
397  a = (double complex*)malloc(xNsize*xNsize*sizeof(double complex));
398  w = (double*)malloc(xNsize*sizeof(double));
399  work = (double complex*)malloc(lwork*sizeof(double complex));
400  rwork = (double*)malloc(lrwork*sizeof(double));
401 
402  k=0;
403  for(j=0;j<xNsize;j++){
404  for(i=0;i<xNsize;i++){
405  a[k] = A[i][j];
406  k++;
407  }
408  }
409 
410  jobz = 'V';
411  uplo = 'U';
412 
413 #ifdef SR
414  int zheevd_(char *jobz, char *uplo, int *n, double complex *a, int *lda, double *w, double complex *work, int *lwork, double *rwork, int *iwork, int *liwork, int *info);
415  free(iwork);
416 #else
417  zheev_(&jobz, &uplo, &n, a, &lda, w, work, &lwork, rwork, &info);
418 #endif
419 
420  if(info != 0){
421  free(a);
422  free(w);
423  free(work);
424  free(rwork);
425  return 0;
426  }
427 
428  k=0;
429  for(i=0;i<xNsize;i++){
430  for(j=0;j<xNsize;j++){
431  vec[i][j]=a[k];
432  k++;
433  }
434  }
435 
436 
437  for(k=0;k<xNsize;k++){
438  r[k] = w[k];
439  }
440 
441  free(a);
442  free(w);
443  free(work);
444  free(rwork);
445 
446  return 1;
447 }
int dgetri_(int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info)
int M_DSYEV(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info)
double complex ** vec
Definition: global.h:45
int ZHEEVall(int xNsize, double complex **A, double complex *r, double complex **vec)
obtain eigenvalues and eigenvectors of Hermite matrix A
Definition: matrixlapack.c:374
int DSEVvalue(int xNsize, double **A, double *r)
obtain eigenvalues of real symmetric A
Definition: matrixlapack.c:93
double dlamch_(char *cmach)
void zheevd_(char *jobz, char *uplo, int *n, double complex *a, int *lda, double *w, double complex *work, int *lwork, double *rwork, int *lrwork, int *iwork, int *liwork, int *info)
int dsyevx_(char *jobz, char *range, char *uplo, int *n, double *a, int *lda, double *vl, double *vu, int *il, int *iu, double *abstol, int *m, double *w, double *z__, int *ldz, double *work, int *lwork, int *iwork, int *ifail, int *info)
int DSEVXU(int xNsize, double **A, double *r, double **X, int xNev)
obtain eigenvalues A
Definition: matrixlapack.c:290
int DInv(int xNsize, double **xM, double **xIM)
obtain eigenvalues of inverse of real matrix xM
Definition: matrixlapack.c:153
int zheev_(char *jobz, char *uplo, int *n, double complex *a, int *lda, double *w, double complex *work, int *lwork, double *rwork, int *info)
int DSEVvector(int xNsize, double **A, double *r, double **vec)
obtain eigenvalues and eigenvectors of real symmetric A
Definition: matrixlapack.c:209
void to_f(int N, int M, double **A, double *a)
function for transforming Row-major matrix (C) to Column-major matrix (Fortran)
Definition: matrixlapack.c:66
struct EDMainCalStruct X
Definition: struct.h:432
int dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info)
int dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info)