OscProb
zheevc3.cxx
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// Numerical diagonalization of 3x3 matrcies
3// Copyright (C) 2006 Joachim Kopp
4// ----------------------------------------------------------------------------
5// This library is free software; you can redistribute it and/or
6// modify it under the terms of the GNU Lesser General Public
7// License as published by the Free Software Foundation; either
8// version 2.1 of the License, or (at your option) any later version.
9//
10// This library is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public
16// License along with this library; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18// ----------------------------------------------------------------------------
19#include <stdio.h>
20#include <cmath>
21#include <complex>
22#include "zheevc3.h"
23
24// Constants
25#define M_SQRT3 1.73205080756887729352744634151 // sqrt(3)
26
27// Macros
28#define SQR(x) ((x)*(x)) // x^2
29#define SQR_ABS(x) (SQR(real(x)) + SQR(imag(x))) // |x|^2
30
31
32// ----------------------------------------------------------------------------
33int zheevc3(std::complex<double> A[3][3], double w[3])
34// ----------------------------------------------------------------------------
35// Calculates the eigenvalues of a hermitian 3x3 matrix A using Cardano's
36// analytical algorithm.
37// Only the diagonal and upper triangular parts of A are accessed. The access
38// is read-only.
39// ----------------------------------------------------------------------------
40// Parameters:
41// A: The hermitian input matrix
42// w: Storage buffer for eigenvalues
43// ----------------------------------------------------------------------------
44// Return value:
45// 0: Success
46// -1: Error
47// ----------------------------------------------------------------------------
48{
49 double m, c1, c0;
50
51 // Determine coefficients of characteristic poynomial. We write
52 // | a d f |
53 // A = | d* b e |
54 // | f* e* c |
55 std::complex<double> de = A[0][1] * A[1][2]; // d * e
56 double dd = SQR_ABS(A[0][1]); // d * conj(d)
57 double ee = SQR_ABS(A[1][2]); // e * conj(e)
58 double ff = SQR_ABS(A[0][2]); // f * conj(f)
59 m = real(A[0][0]) + real(A[1][1]) + real(A[2][2]);
60 c1 = (real(A[0][0])*real(A[1][1]) // a*b + a*c + b*c - d*conj(d) - e*conj(e) - f*conj(f)
61 + real(A[0][0])*real(A[2][2])
62 + real(A[1][1])*real(A[2][2]))
63 - (dd + ee + ff);
64 c0 = real(A[2][2])*dd + real(A[0][0])*ee + real(A[1][1])*ff
65 - real(A[0][0])*real(A[1][1])*real(A[2][2])
66 - 2.0 * (real(A[0][2])*real(de) + imag(A[0][2])*imag(de));
67 // c*d*conj(d) + a*e*conj(e) + b*f*conj(f) - a*b*c - 2*Re(conj(f)*d*e)
68
69 double p, sqrt_p, q, c, s, phi;
70 p = SQR(m) - 3.0*c1;
71 q = m*(p - (3.0/2.0)*c1) - (27.0/2.0)*c0;
72 sqrt_p = sqrt(fabs(p));
73
74 phi = 27.0 * ( 0.25*SQR(c1)*(p - c1) + c0*(q + 27.0/4.0*c0));
75 phi = (1.0/3.0) * atan2(sqrt(fabs(phi)), q);
76
77 c = sqrt_p*cos(phi);
78 s = (1.0/M_SQRT3)*sqrt_p*sin(phi);
79
80 w[1] = (1.0/3.0)*(m - c);
81 w[2] = w[1] + s;
82 w[0] = w[1] + c;
83 w[1] -= s;
84
85 return 0;
86}
87
#define M_SQRT3
Definition: zheevc3.cxx:25
#define SQR_ABS(x)
Definition: zheevc3.cxx:29
int zheevc3(std::complex< double > A[3][3], double w[3])
Definition: zheevc3.cxx:33
#define SQR(x)
Definition: zheevc3.cxx:28