"MarlinReco"  1.32.0
jama_eig.h
1 #ifndef JAMA_EIG_H
2 #define JAMA_EIG_H
3 
4 
5 #include "tnt_math_utils.h"
6 
7 #include <algorithm>
8 // for min(), max() below
9 
10 
11 
12 using namespace std;
13 
14 namespace JAMMA
15 {
17 {
18  private:
19 
21  int n{};
22  int issymmetric{}; /* boolean*/
23  float d[3]{};
24  float e[3]{};
25  float V[3][3]{};
26  float H[3][3]{};
27  float ort[3]{};
28 
29  void tred2() {
30 
31  // This is derived from the Algol procedures tred2 by
32  // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
33  // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
34  // Fortran subroutine in EISPACK.
35 
36  for (int j = 0; j < n; j++) {
37  d[j] = V[n-1][j];
38  }
39 
40  // Householder reduction to tridiagonal form.
41 
42  for (int i = n-1; i > 0; i--) {
43 
44  // Scale to avoid under/overflow.
45 
46  float scale = 0.0;
47  float h = 0.0;
48  for (int k = 0; k < i; k++) {
49  scale = scale + abs(d[k]);
50  }
51  if (scale == 0.0) {
52  e[i] = d[i-1];
53  for (int j = 0; j < i; j++) {
54  d[j] = V[i-1][j];
55  V[i][j] = 0.0;
56  V[j][i] = 0.0;
57  }
58  } else {
59 
60  // Generate Householder vector.
61 
62  for (int k = 0; k < i; k++) {
63  d[k] /= scale;
64  h += d[k] * d[k];
65  }
66  float f = d[i-1];
67  float g = sqrt(h);
68  if (f > 0) {
69  g = -g;
70  }
71  e[i] = scale * g;
72  h = h - f * g;
73  d[i-1] = f - g;
74  for (int j = 0; j < i; j++) {
75  e[j] = 0.0;
76  }
77 
78  // Apply similarity transformation to remaining columns.
79 
80  for (int j = 0; j < i; j++) {
81  f = d[j];
82  V[j][i] = f;
83  g = e[j] + V[j][j] * f;
84  for (int k = j+1; k <= i-1; k++) {
85  g += V[k][j] * d[k];
86  e[k] += V[k][j] * f;
87  }
88  e[j] = g;
89  }
90  f = 0.0;
91  for (int j = 0; j < i; j++) {
92  e[j] /= h;
93  f += e[j] * d[j];
94  }
95  float hh = f / (h + h);
96  for (int j = 0; j < i; j++) {
97  e[j] -= hh * d[j];
98  }
99  for (int j = 0; j < i; j++) {
100  f = d[j];
101  g = e[j];
102  for (int k = j; k <= i-1; k++) {
103  V[k][j] -= (f * e[k] + g * d[k]);
104  }
105  d[j] = V[i-1][j];
106  V[i][j] = 0.0;
107  }
108  }
109  d[i] = h;
110  }
111 
112  // Accumulate transformations.
113 
114  for (int i = 0; i < n-1; i++) {
115  V[n-1][i] = V[i][i];
116  V[i][i] = 1.0;
117  float h = d[i+1];
118  if (h != 0.0) {
119  for (int k = 0; k <= i; k++) {
120  d[k] = V[k][i+1] / h;
121  }
122  for (int j = 0; j <= i; j++) {
123  float g = 0.0;
124  for (int k = 0; k <= i; k++) {
125  g += V[k][i+1] * V[k][j];
126  }
127  for (int k = 0; k <= i; k++) {
128  V[k][j] -= g * d[k];
129  }
130  }
131  }
132  for (int k = 0; k <= i; k++) {
133  V[k][i+1] = 0.0;
134  }
135  }
136  for (int j = 0; j < n; j++) {
137  d[j] = V[n-1][j];
138  V[n-1][j] = 0.0;
139  }
140  V[n-1][n-1] = 1.0;
141  e[0] = 0.0;
142  }
143 
144  // Symmetric tridiagonal QL algorithm.
145 
146  void tql2 () {
147 
148  // This is derived from the Algol procedures tql2, by
149  // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
150  // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
151  // Fortran subroutine in EISPACK.
152 
153  for (int i = 1; i < n; i++) {
154  e[i-1] = e[i];
155  }
156  e[n-1] = 0.0;
157 
158  float f = 0.0;
159  float tst1 = 0.0;
160  float eps = pow(2.0,-52.0);
161  for (int l = 0; l < n; l++) {
162 
163  // Find small subdiagonal element
164 
165  tst1 = max(tst1,abs(d[l]) + abs(e[l]));
166  int m = l;
167 
168  // Original while-loop from Java code
169  while (m < n) {
170  if (abs(e[m]) <= eps*tst1) {
171  break;
172  }
173  m++;
174  }
175 
176 
177  // If m == l, d[l] is an eigenvalue,
178  // otherwise, iterate.
179 
180  if (m > l) {
181  int iter = 0;
182  do {
183  iter = iter + 1; // (Could check iteration count here.)
184 
185  // Compute implicit shift
186 
187  float g = d[l];
188  float p = (d[l+1] - g) / (2.0 * e[l]);
189  float r = sqrt( p*p + 1 ); //hypot(p,1.0);
190  if (p < 0) {
191  r = -r;
192  }
193  d[l] = e[l] / (p + r);
194  d[l+1] = e[l] * (p + r);
195  float dl1 = d[l+1];
196  float h = g - d[l];
197  for (int i = l+2; i < n; i++) {
198  d[i] -= h;
199  }
200  f = f + h;
201 
202  // Implicit QL transformation.
203 
204  p = d[m];
205  float c = 1.0;
206  float c2 = c;
207  float c3 = c;
208  float el1 = e[l+1];
209  float s = 0.0;
210  float s2 = 0.0;
211  for (int i = m-1; i >= l; i--) {
212  c3 = c2;
213  c2 = c;
214  s2 = s;
215  g = c * e[i];
216  h = c * p;
217  r = sqrt( p*p + e[i]*e[i] ); //hypot(p,e[i]);
218  e[i+1] = s * r;
219  s = e[i] / r;
220  c = p / r;
221  p = c * d[i] - s * g;
222  d[i+1] = h + s * (c * g + s * d[i]);
223 
224  // Accumulate transformation.
225 
226  for (int k = 0; k < n; k++) {
227  h = V[k][i+1];
228  V[k][i+1] = s * V[k][i] + c * h;
229  V[k][i] = c * V[k][i] - s * h;
230  }
231  }
232  p = -s * s2 * c3 * el1 * e[l] / dl1;
233  e[l] = s * p;
234  d[l] = c * p;
235 
236  // Check for convergence.
237 
238  } while (abs(e[l]) > eps*tst1);
239  }
240  d[l] = d[l] + f;
241  e[l] = 0.0;
242  }
243 
244  // Sort eigenvalues and corresponding vectors.
245 
246  for (int i = 0; i < n-1; i++) {
247  int k = i;
248  float p = d[i];
249  for (int j = i+1; j < n; j++) {
250  if (d[j] < p) {
251  k = j;
252  p = d[j];
253  }
254  }
255  if (k != i) {
256  d[k] = d[i];
257  d[i] = p;
258  for (int j = 0; j < n; j++) {
259  p = V[j][i];
260  V[j][i] = V[j][k];
261  V[j][k] = p;
262  }
263  }
264  }
265  }
266 
267  // Nonsymmetric reduction to Hessenberg form.
268 
269  void orthes () {
270 
271  // This is derived from the Algol procedures orthes and ortran,
272  // by Martin and Wilkinson, Handbook for Auto. Comp.,
273  // Vol.ii-Linear Algebra, and the corresponding
274  // Fortran subroutines in EISPACK.
275 
276  int low = 0;
277  int high = n-1;
278 
279  for (int m = low+1; m <= high-1; m++) {
280 
281  // Scale column.
282 
283  float scale = 0.0;
284  for (int i = m; i <= high; i++) {
285  scale = scale + abs(H[i][m-1]);
286  }
287  if (scale != 0.0) {
288 
289  // Compute Householder transformation.
290 
291  float h = 0.0;
292  for (int i = high; i >= m; i--) {
293  ort[i] = H[i][m-1]/scale;
294  h += ort[i] * ort[i];
295  }
296  float g = sqrt(h);
297  if (ort[m] > 0) {
298  g = -g;
299  }
300  h = h - ort[m] * g;
301  ort[m] = ort[m] - g;
302 
303  // Apply Householder similarity transformation
304  // H = (I-u*u'/h)*H*(I-u*u')/h)
305 
306  for (int j = m; j < n; j++) {
307  float f = 0.0;
308  for (int i = high; i >= m; i--) {
309  f += ort[i]*H[i][j];
310  }
311  f = f/h;
312  for (int i = m; i <= high; i++) {
313  H[i][j] -= f*ort[i];
314  }
315  }
316 
317  for (int i = 0; i <= high; i++) {
318  float f = 0.0;
319  for (int j = high; j >= m; j--) {
320  f += ort[j]*H[i][j];
321  }
322  f = f/h;
323  for (int j = m; j <= high; j++) {
324  H[i][j] -= f*ort[j];
325  }
326  }
327  ort[m] = scale*ort[m];
328  H[m][m-1] = scale*g;
329  }
330  }
331 
332  // Accumulate transformations (Algol's ortran).
333 
334  for (int i = 0; i < n; i++) {
335  for (int j = 0; j < n; j++) {
336  V[i][j] = (i == j ? 1.0 : 0.0);
337  }
338  }
339 
340  for (int m = high-1; m >= low+1; m--) {
341  if (H[m][m-1] != 0.0) {
342  for (int i = m+1; i <= high; i++) {
343  ort[i] = H[i][m-1];
344  }
345  for (int j = m; j <= high; j++) {
346  float g = 0.0;
347  for (int i = m; i <= high; i++) {
348  g += ort[i] * V[i][j];
349  }
350  // Float division avoids possible underflow
351  g = (g / ort[m]) / H[m][m-1];
352  for (int i = m; i <= high; i++) {
353  V[i][j] += g * ort[i];
354  }
355  }
356  }
357  }
358  }
359 
360 
361  // Complex scalar division.
362 
363  float cdivr{}, cdivi{};
364  void cdiv(float xr, float xi, float yr, float yi) {
365  float r,d;
366  if (abs(yr) > abs(yi)) {
367  r = yi/yr;
368  d = yr + r*yi;
369  cdivr = (xr + r*xi)/d;
370  cdivi = (xi - r*xr)/d;
371  } else {
372  r = yr/yi;
373  d = yi + r*yr;
374  cdivr = (r*xr + xi)/d;
375  cdivi = (r*xi - xr)/d;
376  }
377  }
378 
379 
380  // Nonsymmetric reduction from Hessenberg to real Schur form.
381 
382  void hqr2 () {
383 
384  // This is derived from the Algol procedure hqr2,
385  // by Martin and Wilkinson, Handbook for Auto. Comp.,
386  // Vol.ii-Linear Algebra, and the corresponding
387  // Fortran subroutine in EISPACK.
388 
389  // Initialize
390 
391  int nn = 3;
392  int n = nn-1;
393  int low = 0;
394  int high = nn-1;
395  float eps = pow(2.0,-52.0);
396  float exshift = 0.0;
397  float p=0,q=0,r=0,s=0,z=0,t,w,x,y;
398 
399  // Store roots isolated by balanc and compute matrix norm
400 
401  float norm = 0.0;
402  for (int i = 0; i < nn; i++) {
403  if ((i < low) || (i > high)) {
404  d[i] = H[i][i];
405  e[i] = 0.0;
406  }
407  for (int j = max(i-1,0); j < nn; j++) {
408  norm = norm + abs(H[i][j]);
409  }
410  }
411 
412  // Outer loop over eigenvalue index
413 
414  int iter = 0;
415  while (n >= low) {
416 
417  // Look for single small sub-diagonal element
418 
419  int l = n;
420  while (l > low) {
421  s = abs(H[l-1][l-1]) + abs(H[l][l]);
422  if (s == 0.0) {
423  s = norm;
424  }
425  if (abs(H[l][l-1]) < eps * s) {
426  break;
427  }
428  l--;
429  }
430 
431  // Check for convergence
432  // One root found
433 
434  if (l == n) {
435  H[n][n] = H[n][n] + exshift;
436  d[n] = H[n][n];
437  e[n] = 0.0;
438  n--;
439  iter = 0;
440 
441  // Two roots found
442 
443  } else if (l == n-1) {
444  w = H[n][n-1] * H[n-1][n];
445  p = (H[n-1][n-1] - H[n][n]) / 2.0;
446  q = p * p + w;
447  z = sqrt(abs(q));
448  H[n][n] = H[n][n] + exshift;
449  H[n-1][n-1] = H[n-1][n-1] + exshift;
450  x = H[n][n];
451 
452  // float pair
453 
454  if (q >= 0) {
455  if (p >= 0) {
456  z = p + z;
457  } else {
458  z = p - z;
459  }
460  d[n-1] = x + z;
461  d[n] = d[n-1];
462  if (z != 0.0) {
463  d[n] = x - w / z;
464  }
465  e[n-1] = 0.0;
466  e[n] = 0.0;
467  x = H[n][n-1];
468  s = abs(x) + abs(z);
469  p = x / s;
470  q = z / s;
471  r = sqrt(p * p+q * q);
472  p = p / r;
473  q = q / r;
474 
475  // Row modification
476 
477  for (int j = n-1; j < nn; j++) {
478  z = H[n-1][j];
479  H[n-1][j] = q * z + p * H[n][j];
480  H[n][j] = q * H[n][j] - p * z;
481  }
482 
483  // Column modification
484 
485  for (int i = 0; i <= n; i++) {
486  z = H[i][n-1];
487  H[i][n-1] = q * z + p * H[i][n];
488  H[i][n] = q * H[i][n] - p * z;
489  }
490 
491  // Accumulate transformations
492 
493  for (int i = low; i <= high; i++) {
494  z = V[i][n-1];
495  V[i][n-1] = q * z + p * V[i][n];
496  V[i][n] = q * V[i][n] - p * z;
497  }
498 
499  // Complex pair
500 
501  } else {
502  d[n-1] = x + p;
503  d[n] = x + p;
504  e[n-1] = z;
505  e[n] = -z;
506  }
507  n = n - 2;
508  iter = 0;
509 
510  // No convergence yet
511 
512  } else {
513 
514  // Form shift
515 
516  x = H[n][n];
517  y = 0.0;
518  w = 0.0;
519  if (l < n) {
520  y = H[n-1][n-1];
521  w = H[n][n-1] * H[n-1][n];
522  }
523 
524  // Wilkinson's original ad hoc shift
525 
526  if (iter == 10) {
527  exshift += x;
528  for (int i = low; i <= n; i++) {
529  H[i][i] -= x;
530  }
531  s = abs(H[n][n-1]) + abs(H[n-1][n-2]);
532  x = y = 0.75 * s;
533  w = -0.4375 * s * s;
534  }
535 
536  // MATLAB's new ad hoc shift
537 
538  if (iter == 30) {
539  s = (y - x) / 2.0;
540  s = s * s + w;
541  if (s > 0) {
542  s = sqrt(s);
543  if (y < x) {
544  s = -s;
545  }
546  s = x - w / ((y - x) / 2.0 + s);
547  for (int i = low; i <= n; i++) {
548  H[i][i] -= s;
549  }
550  exshift += s;
551  x = y = w = 0.964;
552  }
553  }
554 
555  iter = iter + 1; // (Could check iteration count here.)
556 
557 
558 // for abs() below
559  // Look for two consecutive small sub-diagonal elements
560 
561  int m = n-2;
562  while (m >= l) {
563  z = H[m][m];
564  r = x - z;
565  s = y - z;
566  p = (r * s - w) / H[m+1][m] + H[m][m+1];
567  q = H[m+1][m+1] - z - r - s;
568  r = H[m+2][m+1];
569  s = abs(p) + abs(q) + abs(r);
570  p = p / s;
571  q = q / s;
572 
573 // for abs() below
574  r = r / s;
575  if (m == l) {
576  break;
577  }
578  if (abs(H[m][m-1]) * (abs(q) + abs(r)) <
579  eps * (abs(p) * (abs(H[m-1][m-1]) + abs(z) +
580  abs(H[m+1][m+1])))) {
581  break;
582  }
583  m--;
584  }
585 
586  for (int i = m+2; i <= n; i++) {
587  H[i][i-2] = 0.0;
588  if (i > m+2) {
589  H[i][i-3] = 0.0;
590  }
591  }
592 
593  // Float QR step involving rows l:n and columns m:n
594 
595  for (int k = m; k <= n-1; k++) {
596  int notlast = (k != n-1);
597  if (k != m) {
598  p = H[k][k-1];
599  q = H[k+1][k-1];
600  r = (notlast ? H[k+2][k-1] : 0.0);
601  x = abs(p) + abs(q) + abs(r);
602  if (x != 0.0) {
603  p = p / x;
604  q = q / x;
605  r = r / x;
606  }
607  }
608  if (x == 0.0) {
609  break;
610  }
611  s = sqrt(p * p + q * q + r * r);
612  if (p < 0) {
613  s = -s;
614  }
615  if (s != 0) {
616  if (k != m) {
617  H[k][k-1] = -s * x;
618  } else if (l != m) {
619  H[k][k-1] = -H[k][k-1];
620  }
621  p = p + s;
622  x = p / s;
623  y = q / s;
624  z = r / s;
625  q = q / p;
626  r = r / p;
627 
628  // Row modification
629 
630  for (int j = k; j < nn; j++) {
631  p = H[k][j] + q * H[k+1][j];
632  if (notlast) {
633  p = p + r * H[k+2][j];
634  H[k+2][j] = H[k+2][j] - p * z;
635  }
636  H[k][j] = H[k][j] - p * x;
637  H[k+1][j] = H[k+1][j] - p * y;
638  }
639 
640  // Column modification
641 
642  for (int i = 0; i <= min(n,k+3); i++) {
643  p = x * H[i][k] + y * H[i][k+1];
644  if (notlast) {
645  p = p + z * H[i][k+2];
646  H[i][k+2] = H[i][k+2] - p * r;
647  }
648  H[i][k] = H[i][k] - p;
649  H[i][k+1] = H[i][k+1] - p * q;
650  }
651 
652  // Accumulate transformations
653 
654  for (int i = low; i <= high; i++) {
655  p = x * V[i][k] + y * V[i][k+1];
656  if (notlast) {
657  p = p + z * V[i][k+2];
658  V[i][k+2] = V[i][k+2] - p * r;
659  }
660  V[i][k] = V[i][k] - p;
661  V[i][k+1] = V[i][k+1] - p * q;
662  }
663  } // (s != 0)
664  } // k loop
665  } // check convergence
666  } // while (n >= low)
667 
668  // Backsubstitute to find vectors of upper triangular form
669 
670  if (norm == 0.0) {
671  return;
672  }
673 
674  for (n = nn-1; n >= 0; n--) {
675  p = d[n];
676  q = e[n];
677 
678  // float vector
679 
680  if (q == 0) {
681  int l = n;
682  H[n][n] = 1.0;
683  for (int i = n-1; i >= 0; i--) {
684  w = H[i][i] - p;
685  r = 0.0;
686  for (int j = l; j <= n; j++) {
687  r = r + H[i][j] * H[j][n];
688  }
689  if (e[i] < 0.0) {
690  z = w;
691  s = r;
692  } else {
693  l = i;
694  if (e[i] == 0.0) {
695  if (w != 0.0) {
696  H[i][n] = -r / w;
697  } else {
698  H[i][n] = -r / (eps * norm);
699  }
700 
701  // Solve real equations
702 
703  } else {
704  x = H[i][i+1];
705  y = H[i+1][i];
706  q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
707  t = (x * s - z * r) / q;
708  H[i][n] = t;
709  if (abs(x) > abs(z)) {
710  H[i+1][n] = (-r - w * t) / x;
711  } else {
712  H[i+1][n] = (-s - y * t) / z;
713  }
714  }
715 
716  // Overflow control
717 
718  t = abs(H[i][n]);
719  if ((eps * t) * t > 1) {
720  for (int j = i; j <= n; j++) {
721  H[j][n] = H[j][n] / t;
722  }
723  }
724  }
725  }
726 
727  // Complex vector
728 
729  } else if (q < 0) {
730  int l = n-1;
731 
732  // Last vector component imaginary so matrix is triangular
733 
734  if (abs(H[n][n-1]) > abs(H[n-1][n])) {
735  H[n-1][n-1] = q / H[n][n-1];
736  H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
737  } else {
738  cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q);
739  H[n-1][n-1] = cdivr;
740  H[n-1][n] = cdivi;
741  }
742  H[n][n-1] = 0.0;
743  H[n][n] = 1.0;
744  for (int i = n-2; i >= 0; i--) {
745  float ra,sa,vr,vi;
746  ra = 0.0;
747  sa = 0.0;
748  for (int j = l; j <= n; j++) {
749  ra = ra + H[i][j] * H[j][n-1];
750  sa = sa + H[i][j] * H[j][n];
751  }
752  w = H[i][i] - p;
753 
754  if (e[i] < 0.0) {
755  z = w;
756  r = ra;
757  s = sa;
758  } else {
759  l = i;
760  if (e[i] == 0) {
761  cdiv(-ra,-sa,w,q);
762  H[i][n-1] = cdivr;
763  H[i][n] = cdivi;
764  } else {
765 
766  // Solve complex equations
767 
768  x = H[i][i+1];
769  y = H[i+1][i];
770  vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
771  vi = (d[i] - p) * 2.0 * q;
772  if ((vr == 0.0) && (vi == 0.0)) {
773  vr = eps * norm * (abs(w) + abs(q) +
774  abs(x) + abs(y) + abs(z));
775  }
776  cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
777  H[i][n-1] = cdivr;
778  H[i][n] = cdivi;
779  if (abs(x) > (abs(z) + abs(q))) {
780  H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
781  H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
782  } else {
783  cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
784  H[i+1][n-1] = cdivr;
785  H[i+1][n] = cdivi;
786  }
787  }
788 
789  // Overflow control
790 
791  t = max(abs(H[i][n-1]),abs(H[i][n]));
792  if ((eps * t) * t > 1) {
793  for (int j = i; j <= n; j++) {
794  H[j][n-1] = H[j][n-1] / t;
795  H[j][n] = H[j][n] / t;
796  }
797  }
798  }
799  }
800  }
801  }
802 
803  // Vectors of isolated roots
804 
805  for (int i = 0; i < nn; i++) {
806 
807 // for abs() below
808  if (i < low || i > high) {
809  for (int j = i; j < nn; j++) {
810  V[i][j] = H[i][j];
811  }
812  }
813  }
814 
815  // Back transformation to get eigenvectors of original matrix
816 
817  for (int j = nn-1; j >= low; j--) {
818  for (int i = low; i <= high; i++) {
819  z = 0.0;
820  for (int k = low; k <= min(j,high); k++) {
821  z = z + V[i][k] * H[k][j];
822  }
823  V[i][j] = z;
824  }
825  }
826  }
827 
828 public:
829 
830  ~Eigenvalue(){
831 
832  }
837  Eigenvalue( float A[3][3]) {
838  n = 3;
839  issymmetric = 1;
840 
841  for (int j = 0; (j < n) && issymmetric; j++) {
842  d[j]=0.0;
843  e[j]=0.0;
844  for (int i = 0; (i < n) && issymmetric; i++) {
845  issymmetric = (A[i][j] == A[j][i]);
846 
847  }
848  }
849 
850  if (issymmetric) {
851  for (int i = 0; i < n; i++) {
852  for (int j = 0; j < n; j++) {
853  V[i][j] = A[i][j];
854  }
855  }
856 
857  // Tridiagonalize.
858  tred2();
859 
860  // Diagonalize.
861  tql2();
862 
863  } else {
864 
865 
866  for (int j = 0; j < n; j++) {
867  for (int i = 0; i < n; i++) {
868  H[i][j] = A[i][j];
869  }
870  }
871 
872  // Reduce to Hessenberg form.
873  orthes();
874 
875  // Reduce Hessenberg to real Schur form.
876  hqr2();
877  }
878  }
879 
880 
885  void getV (float V_[3][3]) {
886  for (int i=0;i<3;i++)
887  {
888  for (int j=0;j<3;j++)
889  { V_[i][j] = V[i][j];}}
890  return;
891  }
892 
897  void getRealEigenvalues (float d_[3]) {
898  for (int i=0;i<3;i++)
899  { d_[i] = d[i];};
900  return ;
901  }
902 
908  void getImagEigenvalues (float e_[3]) {
909  for (int i=0;i<3;i++)
910  { e_[i] = e[i];}
911  return;
912  }
913 
914 
948  void getD (float D[3][3]) {
949  for (int i = 0; i < n; i++) {
950  for (int j = 0; j < n; j++) {
951  D[i][j] = 0.0;
952  }
953  D[i][i] = d[i];
954  if (e[i] > 0) {
955  D[i][i+1] = e[i];
956  } else if (e[i] < 0) {
957  D[i][i-1] = e[i];
958  }
959  }
960  }
961 };
962 
963 
964 }
965 
966 #endif
967 // JAMA_EIG_H
Eigenvalue(float A[3][3])
Check for symmetry, then construct the eigenvalue decomposition.
Definition: jama_eig.h:837
void getRealEigenvalues(float d_[3])
Return the real parts of the eigenvalues.
Definition: jama_eig.h:897
void getImagEigenvalues(float e_[3])
Return the imaginary parts of the eigenvalues in parameter e_.
Definition: jama_eig.h:908
void getV(float V_[3][3])
Return the eigenvector matrix.
Definition: jama_eig.h:885
void getD(float D[3][3])
Computes the block diagonal eigenvalue matrix.
Definition: jama_eig.h:948
Definition: jama_eig.h:16