-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdiag_wrapper.cpp
More file actions
80 lines (67 loc) · 2.07 KB
/
diag_wrapper.cpp
File metadata and controls
80 lines (67 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//
// diag_wrapper.cpp
// SPT
//
// Created by Bin Xu on 9/5/14.
// Copyright (c) 2014 Bin Xu. All rights reserved.
//
#include "diag_wrapper.h"
#include <complex.h>
#include <Accelerate/Accelerate.h>
bool zheevpp(vector<vector<complex<double> > >& matrix, vector<double>& evals, vector<ch_eigenvector>& evecs, int nevecs)
// The interface should be fixed for different implementations.
// nevecs = 0 gives no eigenvectors
// evec[n] gives the nth eigenvector
// This version is the gnu lapacke implementation
{
__CLPK_integer size = matrix.size();
__CLPK_doublecomplex *mat = new __CLPK_doublecomplex[size*size];
for (int row = 0; row < size; row++)
for (int col = 0; col < size; col++)
{
mat[row * size + col].r = real(matrix[row][col]);
mat[row * size + col].i = imag(matrix[row][col]);
}
__CLPK_integer lwork = 2 * size;
double *Evals = new double[lwork];
__CLPK_doublecomplex *work = new __CLPK_doublecomplex[2*size];
double *rwork = new double[3 * size];
int info;
char tempV = 'V';
char tempU = 'U';
zheev_(&tempV, &tempU, &size, mat, &size, Evals, work, &lwork, rwork, &info);
if (info > 0)
{
cout << "Error in Lapack while computing eigenvalues." <<endl;
return false;
}
evecs.resize(nevecs);
evals.resize(nevecs);
for (auto& it : evecs) it.eigenvector.resize(size);
for(int i = 0; i < nevecs; i++)
{
for (int j = 0; j < size; j++)
{
evecs[i].eigenvector[j] = mat[i*size + j].r + complex<double>(0, 1) * mat[j*size + i].i ; //I may have mixed up i and j
}
evals[i] = Evals[i];
}
for (int i = 0; i < nevecs; i++)
{
double Norm = 0;
for(auto it : evecs[i].eigenvector)
{
Norm += norm(it);
}
Norm = sqrt(Norm);
for (int j = 0; j < size; j++)
{
evecs[i].eigenvector[j] /= Norm;
}
}
delete [] Evals;
delete [] mat;
delete [] work;
delete [] rwork;
return true;
}