20#ifndef __B2_EIGEN_DECOMPOSITION_H__
21#define __B2_EIGEN_DECOMPOSITION_H__
28static double hypot2(
double x,
double y) {
return std::sqrt(x * x + y * y); }
32static void tred2(
double V[n][n],
double d[n],
double e[n]) {
38 for (
int j = 0; j < n; ++j) { d[j] = V[n - 1][j]; }
42 for (
int i = n - 1; i > 0; --i) {
47 for (
int k = 0; k < i; ++k) { scale = scale + std::abs(d[k]); }
50 for (
int j = 0; j < i; ++j) {
58 for (
int k = 0; k < i; ++k) {
63 double g = std::sqrt(h);
64 if (f > 0) { g = -g; }
68 for (
int j = 0; j < i; ++j) { e[j] = 0.0; }
72 for (
int j = 0; j < i; ++j) {
75 g = e[j] + V[j][j] * f;
76 for (
int k = j + 1; k <= i - 1; ++k) {
83 for (
int j = 0; j < i; ++j) {
87 double hh = f / (h + h);
88 for (
int j = 0; j < i; ++j) { e[j] -= hh * d[j]; }
89 for (
int j = 0; j < i; ++j) {
92 for (
int k = j; k <= i - 1; ++k) { V[k][j] -= (f * e[k] + g * d[k]); }
102 for (
int i = 0; i < n - 1; ++i) {
103 V[n - 1][i] = V[i][i];
107 for (
int k = 0; k <= i; ++k) { d[k] = V[k][i + 1] / h; }
108 for (
int j = 0; j <= i; ++j) {
110 for (
int k = 0; k <= i; ++k) { g += V[k][i + 1] * V[k][j]; }
111 for (
int k = 0; k <= i; ++k) { V[k][j] -= g * d[k]; }
114 for (
int k = 0; k <= i; ++k) { V[k][i + 1] = 0.0; }
116 for (
int j = 0; j < n; ++j) {
120 V[n - 1][n - 1] = 1.0;
126static void tql2(
double V[n][n],
double d[n],
double e[n]) {
132 for (
int i = 1; i < n; ++i) { e[i - 1] = e[i]; }
137 double eps =
pow(2.0, -52.0);
138 for (
int l = 0; l < n; l++) {
141 tst1 = std::max(tst1, std::abs(d[l]) + std::abs(e[l]));
144 if (std::abs(e[m]) <= eps * tst1) {
break; }
159 double p = (d[l + 1] - g) / (2.0 * e[l]);
160 double r = hypot2(p, 1.0);
161 if (p < 0) { r = -r; }
162 d[l] = e[l] / (p + r);
163 d[l + 1] = e[l] * (p + r);
164 double dl1 = d[l + 1];
166 for (
int i = l + 2; i < n; ++i) { d[i] -= h; }
175 double el1 = e[l + 1];
178 for (
int i = m - 1; i >= l; i--) {
188 p = c * d[i] - s * g;
189 d[i + 1] = h + s * (c * g + s * d[i]);
193 for (
int k = 0; k < n; ++k) {
195 V[k][i + 1] = s * V[k][i] + c * h;
196 V[k][i] = c * V[k][i] - s * h;
199 p = -s * s2 * c3 * el1 * e[l] / dl1;
205 }
while (std::abs(e[l]) > eps * tst1);
213 for (
int i = 0; i < n - 1; ++i) {
216 for (
int j = i + 1; j < n; ++j) {
225 for (
int j = 0; j < n; ++j) {
241void eigen_decomposition(
const double A[n][n],
double V[n][n],
double d[n]) {
243 std::copy(A[0], A[n], V[0]);
252void eigen_decomposition(
double A_and_V[n][n],
double d[n]) {
254 tred2(A_and_V, d, e);
csda< T > pow(const csda< T > &a, const csda< T > &b)
Power from two csda numbers.
Definition b2csda.H:378
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32