OscProb
zheevh3.cxx File Reference
#include <stdio.h>
#include <cmath>
#include <complex>
#include <float.h>
#include "zheevc3.h"
#include "zheevq3.h"

Go to the source code of this file.

Macros

#define SQR(x)   ((x)*(x))
 
#define SQR_ABS(x)   (SQR(real(x)) + SQR(imag(x)))
 

Functions

int zheevh3 (std::complex< double > A[3][3], std::complex< double > Q[3][3], double w[3])
 

Macro Definition Documentation

◆ SQR

#define SQR (   x)    ((x)*(x))

Definition at line 27 of file zheevh3.cxx.

◆ SQR_ABS

#define SQR_ABS (   x)    (SQR(real(x)) + SQR(imag(x)))

Definition at line 28 of file zheevh3.cxx.

Function Documentation

◆ zheevh3()

int zheevh3 ( std::complex< double >  A[3][3],
std::complex< double >  Q[3][3],
double  w[3] 
)

Definition at line 31 of file zheevh3.cxx.

57{
58#ifndef EVALS_ONLY
59 double norm; // Squared norm or inverse norm of current eigenvector
60// double n0, n1; // Norm of first and second columns of A
61 double error; // Estimated maximum roundoff error
62 double t, u; // Intermediate storage
63 int j; // Loop counter
64#endif
65
66 // Calculate eigenvalues
67 zheevc3(A, w);
68
69#ifndef EVALS_ONLY
70// n0 = SQR(real(A[0][0])) + SQR_ABS(A[0][1]) + SQR_ABS(A[0][2]);
71// n1 = SQR_ABS(A[0][1]) + SQR(real(A[1][1])) + SQR_ABS(A[1][2]);
72
73 t = fabs(w[0]);
74 if ((u=fabs(w[1])) > t)
75 t = u;
76 if ((u=fabs(w[2])) > t)
77 t = u;
78 if (t < 1.0)
79 u = t;
80 else
81 u = SQR(t);
82 error = 256.0 * DBL_EPSILON * SQR(u);
83// error = 256.0 * DBL_EPSILON * (n0 + u) * (n1 + u);
84
85 Q[0][1] = A[0][1]*A[1][2] - A[0][2]*real(A[1][1]);
86 Q[1][1] = A[0][2]*conj(A[0][1]) - A[1][2]*real(A[0][0]);
87 Q[2][1] = SQR_ABS(A[0][1]);
88
89 // Calculate first eigenvector by the formula
90 // v[0] = conj( (A - w[0]).e1 x (A - w[0]).e2 )
91 Q[0][0] = Q[0][1] + A[0][2]*w[0];
92 Q[1][0] = Q[1][1] + A[1][2]*w[0];
93 Q[2][0] = (real(A[0][0]) - w[0]) * (real(A[1][1]) - w[0]) - Q[2][1];
94 norm = SQR_ABS(Q[0][0]) + SQR_ABS(Q[1][0]) + SQR(real(Q[2][0]));
95
96 // If vectors are nearly linearly dependent, or if there might have
97 // been large cancellations in the calculation of A(I,I) - W(1), fall
98 // back to QL algorithm
99 // Note that this simultaneously ensures that multiple eigenvalues do
100 // not cause problems: If W(1) = W(2), then A - W(1) * I has rank 1,
101 // i.e. all columns of A - W(1) * I are linearly dependent.
102 if (norm <= error)
103 return zheevq3(A, Q, w);
104 else // This is the standard branch
105 {
106 norm = sqrt(1.0 / norm);
107 for (j=0; j < 3; j++)
108 Q[j][0] = Q[j][0] * norm;
109 }
110
111 // Calculate second eigenvector by the formula
112 // v[1] = conj( (A - w[1]).e1 x (A - w[1]).e2 )
113 Q[0][1] = Q[0][1] + A[0][2]*w[1];
114 Q[1][1] = Q[1][1] + A[1][2]*w[1];
115 Q[2][1] = (real(A[0][0]) - w[1]) * (real(A[1][1]) - w[1]) - real(Q[2][1]);
116 norm = SQR_ABS(Q[0][1]) + SQR_ABS(Q[1][1]) + SQR(real(Q[2][1]));
117 if (norm <= error)
118 return zheevq3(A, Q, w);
119 else
120 {
121 norm = sqrt(1.0 / norm);
122 for (j=0; j < 3; j++)
123 Q[j][1] = Q[j][1] * norm;
124 }
125
126 // Calculate third eigenvector according to
127 // v[2] = conj(v[0] x v[1])
128 Q[0][2] = conj(Q[1][0]*Q[2][1] - Q[2][0]*Q[1][1]);
129 Q[1][2] = conj(Q[2][0]*Q[0][1] - Q[0][0]*Q[2][1]);
130 Q[2][2] = conj(Q[0][0]*Q[1][1] - Q[1][0]*Q[0][1]);
131#endif
132
133 return 0;
134}
int zheevc3(std::complex< double > A[3][3], double w[3])
Definition: zheevc3.cxx:33
#define SQR_ABS(x)
Definition: zheevh3.cxx:28
#define SQR(x)
Definition: zheevh3.cxx:27
int zheevq3(std::complex< double > A[3][3], std::complex< double > Q[3][3], double w[3])
Definition: zheevq3.cxx:31

References SQR, SQR_ABS, zheevc3(), and zheevq3().

Referenced by OscProb::PMNS_Fast::SolveHam().