18 #define GRT_DLL_EXPORTS 19 #include "EigenvalueDecomposition.h" 23 EigenvalueDecomposition::EigenvalueDecomposition(){
24 warningLog.setKey(
"[WARNING EigenvalueDecomposition]");
27 EigenvalueDecomposition::~EigenvalueDecomposition(){
31 bool EigenvalueDecomposition::decompose(
const MatrixFloat &a){
36 complexEigenvalues.
resize(n);
39 for(
int j = 0; (j < n) & issymmetric; j++) {
40 for(
int i = 0; (i < n) & issymmetric; i++) {
41 issymmetric = (a[i][j] == a[j][i]);
46 for(
int i = 0; i < n; i++) {
47 for(
int j = 0; j < n; j++) {
48 eigenvectors[i][j] = a[i][j];
62 for(
int j = 0; j < n; j++) {
63 for(
int i = 0; i < n; i++) {
80 for(
int j = 0; j < n; j++) {
81 realEigenvalues[j] = eigenvectors[n-1][j];
85 for(
int i = n-1; i > 0; i--) {
90 for (
int k = 0; k < i; k++) {
91 scale = scale + fabs(realEigenvalues[k]);
94 complexEigenvalues[i] = realEigenvalues[i-1];
95 for (
int j = 0; j < i; j++) {
96 realEigenvalues[j] = eigenvectors[i-1][j];
97 eigenvectors[i][j] = 0.0;
98 eigenvectors[j][i] = 0.0;
103 for (
int k = 0; k < i; k++) {
104 realEigenvalues[k] /= scale;
105 h += realEigenvalues[k] * realEigenvalues[k];
107 Float f = realEigenvalues[i-1];
112 complexEigenvalues[i] = scale * g;
114 realEigenvalues[i-1] = f - g;
115 for (
int j = 0; j < i; j++) {
116 complexEigenvalues[j] = 0.0;
120 for (
int j = 0; j < i; j++) {
121 f = realEigenvalues[j];
122 eigenvectors[j][i] = f;
123 g = complexEigenvalues[j] + eigenvectors[j][j] * f;
124 for (
int k = j+1; k <= i-1; k++) {
125 g += eigenvectors[k][j] * realEigenvalues[k];
126 complexEigenvalues[k] += eigenvectors[k][j] * f;
128 complexEigenvalues[j] = g;
131 for (
int j = 0; j < i; j++) {
132 complexEigenvalues[j] /= h;
133 f += complexEigenvalues[j] * realEigenvalues[j];
135 Float hh = f / (h + h);
136 for (
int j = 0; j < i; j++) {
137 complexEigenvalues[j] -= hh * realEigenvalues[j];
139 for (
int j = 0; j < i; j++) {
140 f = realEigenvalues[j];
141 g = complexEigenvalues[j];
142 for (
int k = j; k <= i-1; k++) {
143 eigenvectors[k][j] -= (f * complexEigenvalues[k] + g * realEigenvalues[k]);
145 realEigenvalues[j] = eigenvectors[i-1][j];
146 eigenvectors[i][j] = 0.0;
149 realEigenvalues[i] = h;
153 for(
int i = 0; i < n-1; i++) {
154 eigenvectors[n-1][i] = eigenvectors[i][i];
155 eigenvectors[i][i] = 1.0;
156 Float h = realEigenvalues[i+1];
158 for (
int k = 0; k <= i; k++) {
159 realEigenvalues[k] = eigenvectors[k][i+1] / h;
161 for (
int j = 0; j <= i; j++) {
163 for (
int k = 0; k <= i; k++) {
164 g += eigenvectors[k][i+1] * eigenvectors[k][j];
166 for (
int k = 0; k <= i; k++) {
167 eigenvectors[k][j] -= g * realEigenvalues[k];
171 for(
int k = 0; k <= i; k++) {
172 eigenvectors[k][i+1] = 0.0;
175 for(
int j = 0; j < n; j++) {
176 realEigenvalues[j] = eigenvectors[n-1][j];
177 eigenvectors[n-1][j] = 0.0;
179 eigenvectors[n-1][n-1] = 1.0;
180 complexEigenvalues[0] = 0.0;
187 for(
int i = 1; i < n; i++) {
188 complexEigenvalues[i-1] = complexEigenvalues[i];
190 complexEigenvalues[n-1] = 0.0;
194 Float eps = pow(2.0,-52.0);
195 for (
int l = 0; l < n; l++) {
198 tst1 = findMax(tst1,fabs(realEigenvalues[l]) + fabs(complexEigenvalues[l]));
201 if(fabs(complexEigenvalues[m]) <= eps*tst1) {
214 Float g = realEigenvalues[l];
215 Float p = (realEigenvalues[l+1] - g) / (2.0 * complexEigenvalues[l]);
216 Float r = hypot(p,1.0);
220 realEigenvalues[l] = complexEigenvalues[l] / (p + r);
221 realEigenvalues[l+1] = complexEigenvalues[l] * (p + r);
222 Float dl1 = realEigenvalues[l+1];
223 Float h = g - realEigenvalues[l];
224 for (
int i = l+2; i < n; i++) {
225 realEigenvalues[i] -= h;
230 p = realEigenvalues[m];
234 Float el1 = complexEigenvalues[l+1];
237 for (
int i = m-1; i >= l; i--) {
241 g = c * complexEigenvalues[i];
243 r = hypot(p,complexEigenvalues[i]);
244 complexEigenvalues[i+1] = s * r;
245 s = complexEigenvalues[i] / r;
247 p = c * realEigenvalues[i] - s * g;
248 realEigenvalues[i+1] = h + s * (c * g + s * realEigenvalues[i]);
251 for(
int k = 0; k < n; k++) {
252 h = eigenvectors[k][i+1];
253 eigenvectors[k][i+1] = s * eigenvectors[k][i] + c * h;
254 eigenvectors[k][i] = c * eigenvectors[k][i] - s * h;
257 p = -s * s2 * c3 * el1 * complexEigenvalues[l] / dl1;
258 complexEigenvalues[l] = s * p;
259 realEigenvalues[l] = c * p;
262 }
while (fabs(complexEigenvalues[l]) > eps*tst1);
264 realEigenvalues[l] = realEigenvalues[l] + f;
265 complexEigenvalues[l] = 0.0;
269 for(
int i = 0; i < n-1; i++) {
271 Float p = realEigenvalues[i];
272 for (
int j = i+1; j < n; j++) {
273 if(realEigenvalues[j] < p) {
275 p = realEigenvalues[j];
279 realEigenvalues[k] = realEigenvalues[i];
280 realEigenvalues[i] = p;
281 for (
int j = 0; j < n; j++) {
282 p = eigenvectors[j][i];
283 eigenvectors[j][i] = eigenvectors[j][k];
284 eigenvectors[j][k] = p;
296 for(
int m = low+1; m <= high-1; m++) {
300 for (
int i = m; i <= high; i++) {
301 scale = scale + fabs(h[i][m-1]);
307 for(
int i = high; i >= m; i--) {
308 ort[i] = h[i][m-1]/scale;
309 ht += ort[i] * ort[i];
311 Float g = sqrt( ht );
315 ht = ht - ort[m] * g;
320 for (
int j = m; j < n; j++) {
322 for (
int i = high; i >= m; i--) {
326 for (
int i = m; i <= high; i++) {
331 for(
int i = 0; i <= high; i++) {
333 for(
int j = high; j >= m; j--) {
337 for (
int j = m; j <= high; j++) {
341 ort[m] = scale*ort[m];
347 for (
int i = 0; i < n; i++) {
348 for (
int j = 0; j < n; j++) {
349 eigenvectors[i][j] = (i == j ? 1.0 : 0.0);
353 for (
int m = high-1; m >= low+1; m--) {
354 if (h[m][m-1] != 0.0) {
355 for (
int i = m+1; i <= high; i++) {
358 for (
int j = m; j <= high; j++) {
360 for (
int i = m; i <= high; i++) {
361 g += ort[i] * eigenvectors[i][j];
364 g = (g / ort[m]) / h[m][m-1];
365 for (
int i = m; i <= high; i++) {
366 eigenvectors[i][j] += g * ort[i];
381 Float eps = pow(2.0,-52.0);
383 Float p=0,q=0,r=0,s=0,z=0,t,w,x,y;
387 for(
int i = 0; i < nn; i++) {
388 if( (i < low) | (i > high) ){
389 realEigenvalues[i] = h[i][i];
390 complexEigenvalues[i] = 0.0;
392 for (
int j = findMax(i-1,0); j < nn; j++) {
393 norm = norm + fabs(h[i][j]);
404 s = fabs(h[l-1][l-1]) + fabs(h[l][l]);
408 if(fabs(h[l][l-1]) < eps * s) {
417 h[n][n] = h[n][n] + exshift;
418 realEigenvalues[n] = h[n][n];
419 complexEigenvalues[n] = 0.0;
424 }
else if (l == n-1) {
425 w = h[n][n-1] * h[n-1][n];
426 p = (h[n-1][n-1] - h[n][n]) / 2.0;
429 h[n][n] = h[n][n] + exshift;
430 h[n-1][n-1] = h[n-1][n-1] + exshift;
440 realEigenvalues[n-1] = x + z;
441 realEigenvalues[n] = realEigenvalues[n-1];
443 realEigenvalues[n] = x - w / z;
445 complexEigenvalues[n-1] = 0.0;
446 complexEigenvalues[n] = 0.0;
448 s = fabs(x) + fabs(z);
451 r = sqrt(p * p+q * q);
456 for(
int j = n-1; j < nn; j++) {
458 h[n-1][j] = q * z + p * h[n][j];
459 h[n][j] = q * h[n][j] - p * z;
463 for(
int i = 0; i <= n; i++) {
465 h[i][n-1] = q * z + p * h[i][n];
466 h[i][n] = q * h[i][n] - p * z;
470 for(
int i = low; i <= high; i++) {
471 z = eigenvectors[i][n-1];
472 eigenvectors[i][n-1] = q * z + p * eigenvectors[i][n];
473 eigenvectors[i][n] = q * eigenvectors[i][n] - p * z;
478 realEigenvalues[n-1] = x + p;
479 realEigenvalues[n] = x + p;
480 complexEigenvalues[n-1] = z;
481 complexEigenvalues[n] = -z;
495 w = h[n][n-1] * h[n-1][n];
501 for (
int i = low; i <= n; i++) {
504 s = fabs(h[n][n-1]) + fabs(h[n-1][n-2]);
518 s = x - w / ((y - x) / 2.0 + s);
519 for(
int i = low; i <= n; i++) {
535 p = (r * s - w) / h[m+1][m] + h[m][m+1];
536 q = h[m+1][m+1] - z - r - s;
538 s = fabs(p) + fabs(q) + fabs(r);
545 if(fabs(h[m][m-1]) * (fabs(q) +fabs(r)) <
546 eps * (fabs(p) * (fabs(h[m-1][m-1]) + fabs(z) +
547 fabs(h[m+1][m+1])))) {
553 for(
int i = m+2; i <= n; i++) {
561 for(
int k = m; k <= n-1; k++) {
562 bool notlast = (k != n-1);
566 r = (notlast ? h[k+2][k-1] : 0.0);
567 x = fabs(p) + fabs(q) + fabs(r);
577 s = sqrt(p * p + q * q + r * r);
585 h[k][k-1] = -h[k][k-1];
595 for(
int j = k; j < nn; j++) {
596 p = h[k][j] + q * h[k+1][j];
598 p = p + r * h[k+2][j];
599 h[k+2][j] = h[k+2][j] - p * z;
601 h[k][j] = h[k][j] - p * x;
602 h[k+1][j] = h[k+1][j] - p * y;
606 for (
int i = 0; i <= findMin(n,k+3); i++) {
607 p = x * h[i][k] + y * h[i][k+1];
609 p = p + z * h[i][k+2];
610 h[i][k+2] = h[i][k+2] - p * r;
612 h[i][k] = h[i][k] - p;
613 h[i][k+1] = h[i][k+1] - p * q;
617 for(
int i = low; i <= high; i++) {
618 p = x * eigenvectors[i][k] + y * eigenvectors[i][k+1];
620 p = p + z * eigenvectors[i][k+2];
621 eigenvectors[i][k+2] = eigenvectors[i][k+2] - p * r;
623 eigenvectors[i][k] = eigenvectors[i][k] - p;
624 eigenvectors[i][k+1] = eigenvectors[i][k+1] - p * q;
636 for(n = nn-1; n >= 0; n--) {
637 p = realEigenvalues[n];
638 q = complexEigenvalues[n];
644 for(
int i = n-1; i >= 0; i--) {
647 for(
int j = l; j <= n; j++) {
648 r = r + h[i][j] * h[j][n];
650 if(complexEigenvalues[i] < 0.0) {
655 if (complexEigenvalues[i] == 0.0) {
659 h[i][n] = -r / (eps * norm);
666 q = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + complexEigenvalues[i] * complexEigenvalues[i];
667 t = (x * s - z * r) / q;
669 if(fabs(x) > fabs(z)) {
670 h[i+1][n] = (-r - w * t) / x;
672 h[i+1][n] = (-s - y * t) / z;
678 if ((eps * t) * t > 1) {
679 for(
int j = i; j <= n; j++) {
680 h[j][n] = h[j][n] / t;
691 if (fabs(h[n][n-1]) > fabs(h[n-1][n])) {
692 h[n-1][n-1] = q / h[n][n-1];
693 h[n-1][n] = -(h[n][n] - p) / h[n][n-1];
695 cdiv(0.0,-h[n-1][n],h[n-1][n-1]-p,q);
701 for(
int i = n-2; i >= 0; i--) {
705 for (
int j = l; j <= n; j++) {
706 ra = ra + h[i][j] * h[j][n-1];
707 sa = sa + h[i][j] * h[j][n];
711 if(complexEigenvalues[i] < 0.0) {
717 if(complexEigenvalues[i] == 0) {
726 vr = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + complexEigenvalues[i] * complexEigenvalues[i] - q * q;
727 vi = (realEigenvalues[i] - p) * 2.0 * q;
728 if((vr == 0.0) & (vi == 0.0)){
729 vr = eps * norm * (fabs(w) + fabs(q) + fabs(x) + fabs(y) + fabs(z));
731 cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
734 if (fabs(x) > (fabs(z) + fabs(q))) {
735 h[i+1][n-1] = (-ra - w * h[i][n-1] + q * h[i][n]) / x;
736 h[i+1][n] = (-sa - w * h[i][n] - q * h[i][n-1]) / x;
738 cdiv(-r-y*h[i][n-1],-s-y*h[i][n],z,q);
745 t = findMax(fabs(h[i][n-1]),fabs(h[i][n]));
746 if ((eps * t) * t > 1) {
747 for(
int j = i; j <= n; j++) {
748 h[j][n-1] = h[j][n-1] / t;
749 h[j][n] = h[j][n] / t;
758 for (
int i = 0; i < nn; i++) {
759 if((i < low) | (i > high)){
760 for (
int j = i; j < nn; j++) {
761 eigenvectors[i][j] = h[i][j];
767 for (
int j = nn-1; j >= low; j--) {
768 for (
int i = low; i <= high; i++) {
770 for (
int k = low; k <= findMin(j,high); k++) {
771 z = z + eigenvectors[i][k] * h[k][j];
773 eigenvectors[i][j] = z;
782 if(fabs(yr) > fabs(yi)){
785 cdivr = (xr + r*xi)/d;
786 cdivi = (xi - r*xr)/d;
790 cdivr = (r*xr + xi)/d;
791 cdivi = (r*xi - xr)/d;
799 for (
int i = 0; i < n; i++) {
800 for (
int j = 0; j < n; j++) {
803 x[i][i] = realEigenvalues[i];
804 if(complexEigenvalues[i] > 0) {
805 x[i][i+1] = complexEigenvalues[i];
806 }
else if(complexEigenvalues[i] < 0) {
807 x[i][i-1] = complexEigenvalues[i];
814 return realEigenvalues;
818 return complexEigenvalues;
virtual bool resize(const unsigned int size)
void cdiv(Float xr, Float xi, Float yr, Float yi)
unsigned int getNumCols() const
VectorFloat getComplexEigenvalues()
VectorFloat getRealEigenvalues()
virtual bool resize(const unsigned int r, const unsigned int c)
MatrixFloat getDiagonalEigenvalueMatrix()