diff --git a/Numeric/EigenSolve3x3.cpp b/Numeric/EigenSolve3x3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94c3ad34b685cc8f98238ecacadc046d5e0a48cf --- /dev/null +++ b/Numeric/EigenSolve3x3.cpp @@ -0,0 +1,879 @@ +// $Id: EigenSolve3x3.cpp,v 1.1 2004-12-08 03:09:03 geuzaine Exp $ +// +// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +// This file contains a routine that numerically finds the eigenvalues +// and eigenvectors of a N X N Real Matrix. It is a C++ translation of +// a Javascript translation of a routine from EISPACK. The Javascript +// implementation comes from http://www.akiti.ca/Eig3Solv.html. +// +// References: +// +// Smith, B.T.; J.M. Boyle; J.J. Dongarra; B.S. Garbow; Y. Ikebe; +// V.C. Klema; and C.B. Moler. +// "Matrix Eigensystem Routines--(EISPACK) Guide" +// Springer-Verlag, Berlin. +// 1976 +// +// Garbow, B.S.; J.M. Boyle; J.J. Dongarra; and C.B. Moler. +// "Matrix Eigensystem Routines--(EISPACK) Guide Extension" +// Springer-Verlag, Berlin. +// 1977 +// +// The original sub-routines were written in FORTRAN and have been +// translated to Javascript here. Although all care has been taken to +// ensure that the sub-routines were translated accurately, some +// errors may have crept into the translation. These errors are mine; +// the original FORTRAN routines have been thoroughly tested and work +// properly. Please report any errors to the webmaster. +// +// IMPORTANT! How to use the output: +// +// If the i-th eigenvalue is real, the i-th COLUMN of the eigenvector +// Matrix contains the corresponding eigenvector. +// +// If the i-th eigenvalue is complex with positive imaginary part, +// COLUMNS i and (i + 1) contain the real and imaginary parts of the +// corresponding eigenvector. The conjugate of this vector is the +// eigenvector for the conjugate eigenvalue. +// +// Note the Error Code. If it does not equal -1, some eigenvalues and +// all eigenvectors are meaningless. + +#include "Gmsh.h" +#include "Numeric.h" + +#define N 3 //Global variable, dimension of matrix. + +static void cdivA(double ar, double ai, double br, double bi, + double A[N][N], int in1, int in2, int in3) +{ + // Division routine for dividing one complex number into another: + // This routine does (ar + ai)/(br + bi) and returns the results in + // the specified elements of the A matrix. + + double s, ars, ais, brs, bis; + + s = fabs(br) + fabs(bi); + ars = ar/s; + ais = ai/s; + brs = br/s; + bis = bi/s; + s = brs*brs + bis*bis; + A[in1][in2] = (ars*brs + ais*bis)/s; + A[in1][in3] = (-(ars*bis) + ais*brs)/s; + return; +} // End cdivA + +static void hqr2(double A[N][N], double B[N][N], int low, int igh, + double wi[N], double wr[N], int ierr) +{ + // Computes the eigenvalues and eigenvectors of a real + // upper-Hessenberg Matrix using the QR method. + + double norm = 0.0, p = 0.0, q = 0.0, ra, s = 0.0, sa, t = 0.0; + double tst1, tst2, vi, vr, w, x, y, zz = 0.0, r = 0.0; + int k = 0, l = 0, m, mp2, en = igh, incrFlag = 1, its = 0; + int itn = 30*N, enm2 = 0, na = 0, notlas; + + for (int i = 0; i < N; i++){ // Store eigenvalues already isolated + // and compute matrix norm. + for (int j = k; j < N; j++) + norm += fabs(A[i][j]); + k = i; + if ((i < low) || (i > igh)){ + wi[i] = 0.0; + wr[i] = A[i][i]; + } //End if (i < low or i > igh) + } // End for i + + // Search next eigenvalues + while (en >= low){ + + if (incrFlag) { // Skip this part if incrFlag is set to 0 at very + // end of while loop + its = 0; + na = en - 1; + enm2 = na - 1; + } //End if (incrFlag) + else + incrFlag = 1; + + // Look for single small sub-diagonal element for l = en step -1 + // until low + + for (int i = low; i <= en; i++){ + l = en + low - i; + if (l == low) + break; + s = fabs(A[l - 1][l - 1]) + fabs(A[l][l]); + if (s == 0.0) + s = norm; + tst1 = s; + tst2 = tst1 + fabs(A[l][l - 1]); + if (tst2 == tst1) + break; + } //End for i + + x = A[en][en]; + + if (l == en){ //One root found + wr[en] = A[en][en] = x + t; + wi[en] = 0.0; + en--; + continue; + } //End if (l == en) + + y = A[na][na]; + w = A[en][na]*A[na][en]; + + if (l == na){ //Two roots found + p = (-x + y)/2; + q = p*p + w; + zz = sqrt(fabs(q)); + x = A[en][en] = x + t; + A[na][na] = y + t; + if (q >= 0.0){//Real Pair + zz = ((p < 0.0) ? (-zz + p) : (p + zz)); + wr[en] = wr[na] = x + zz; + if (zz != 0.0) + wr[en] = -(w/zz) + x; + wi[en] = wi[na] = 0.0; + x = A[en][na]; + s = fabs(x) + fabs(zz); + p = x/s; + q = zz/s; + r = sqrt(p*p + q*q); + p /= r; + q /= r; + for (int j = na; j < N; j++){ //Row modification + zz = A[na][j]; + A[na][j] = q*zz + p*A[en][j]; + A[en][j] = -(p*zz) + q*A[en][j]; + }//End for j + for (int j = 0; j <= en; j++){ // Column modification + zz = A[j][na]; + A[j][na] = q*zz + p*A[j][en]; + A[j][en] = -(p*zz) + q*A[j][en] ; + }//End for j + for (int j = low; j <= igh; j++){//Accumulate transformations + zz = B[j][na]; + B[j][na] = q*zz + p*B[j][en]; + B[j][en] = -(p*zz) + q*B[j][en]; + }//End for j + } //End if (q >= 0.0) + else {//else q < 0.0 + wr[en] = wr[na] = x + p; + wi[na] = zz; + wi[en] = -zz; + } //End else + en--; + en--; + continue; + }//End if (l == na) + + if (itn == 0){ //Set error; all eigenvalues have not converged + //after 30 iterations. + ierr = en + 1; + return; + }//End if (itn == 0) + + if ((its == 10) || (its == 20)){ //Form exceptional shift + t += x; + for (int i = low; i <= en; i++) + A[i][i] += -x; + s = fabs(A[en][na]) + fabs(A[na][enm2]); + y = x = 0.75*s; + w = -(0.4375*s*s); + } //End if (its equals 10 or 20) + + its++; + itn--; + + // Look for two consecutive small sub-diagonal elements. Do m = en + // - 2 to l in increments of -1 + + for (m = enm2; m >= l; m--){ + zz = A[m][m]; + r = -zz + x; + s = -zz + y; + p = (-w + r*s)/A[m + 1][m] + A[m][m + 1]; + q = -(zz + r + s) + A[m + 1][m + 1]; + r = A[m + 2][m + 1]; + s = fabs(p) + fabs(q) + fabs(r); + p /= s; + q /= s; + r /= s; + if (m == l) + break; + tst1 = fabs(p) * (fabs(A[m - 1][m - 1]) + fabs(zz) + fabs(A[m + 1][m + 1])); + tst2 = tst1 + fabs(A[m][m - 1]) * (fabs(q) + fabs(r)); + if (tst1 == tst2) + break; + }//End for m + + mp2 = m + 2; + + for (int i = mp2; i <= en; i++){ + A[i][i - 2] = 0.0; + if (i == mp2) + continue; + A[i][i - 3] = 0.0; + }//End for i + + // Double qr step involving rows l to en and columns m to en. + + for (int i = m; i <= na; i++){ + notlas = ((i != na) ? 1 : 0); + if (i != m){ + p = A[i][i - 1]; + q = A[i + 1][i - 1]; + r = ((notlas) ? A[i + 2][i - 1] : 0.0); + x = fabs(p) + fabs(q) + fabs(r); + if (x == 0.0) //Drop through rest of for i loop + continue; + p /= x; + q /= x; + r /= x; + } //End if (i != m) + + s = sqrt(p*p + q*q + r*r); + if (p < 0.0) + s = -s; + + if (i != m) + A[i][i - 1] = -(s*x); + else { + if (l != m) + A[i][i - 1] = -A[i][i - 1]; + } + + p += s; + x = p/s; + y = q/s; + zz = r/s; + q /= p; + r /= p; + k = ((i + 3 < en) ? i + 3 : en); + + if (notlas){ //Do row modification + for (int j = i; j < N; j++) { + p = A[i][j] + q*A[i + 1][j] + r*A[i + 2][j]; + A[i][j] += -(p*x); + A[i + 1][j] += -(p*y); + A[i + 2][j] += -(p*zz); + }//End for j + + for (int j = 0; j <= k; j++) {//Do column modification + p = x*A[j][i] + y*A[j][i + 1] + zz*A[j][i + 2]; + A[j][i] += -p; + A[j][i + 1] += -(p*q); + A[j][i + 2] += -(p*r); + }//End for j + + for (int j = low; j <= igh; j++) {//Accumulate transformations + p = x*B[j][i] + y*B[j][i + 1] + zz*B[j][i + 2]; + B[j][i] += -p; + B[j][i + 1] += -(p*q); + B[j][i + 2] += -(p*r); + } // End for j + }//End if notlas + + else { + for (int j = i; j < N; j++) {//Row modification + p = A[i][j] + q*A[i + 1][j]; + A[i][j] += -(p*x); + A[i + 1][j] += -(p*y); + }//End for j + + for (int j = 0; j <= k; j++){//Column modification + p = x*A[j][i] + y*A[j][i +1]; + A[j][i] += -p; + A[j][i + 1] += -(p*q); + }//End for j + + for (int j = low; j <= igh; j++){//Accumulate transformations + p = x*B[j][i] + y*B[j][i +1]; + B[j][i] += -p; + B[j][i + 1] += -(p*q); + }//End for j + + } //End else if notlas + }//End for i + incrFlag = 0; + }//End while (en >= low) + + if (norm == 0.0) + return; + + //Step from (N - 1) to 0 in steps of -1 + + for (en = (N - 1); en >= 0; en--){ + p = wr[en]; + q = wi[en]; + na = en - 1; + + if (q > 0.0) + continue; + + if (q == 0.0){//Real vector + m = en; + A[en][en] = 1.0; + + for (int j = na; j >= 0; j--){ + w = -p + A[j][j]; + r = 0.0; + for (int ii = m; ii <= en; ii++) + r += A[j][ii]*A[ii][en]; + + if (wi[j] < 0.0){ + zz = w; + s = r; + }//End wi[j] < 0.0 + else {//wi[j] >= 0.0 + m = j; + if (wi[j] == 0.0){ + t = w; + if (t == 0.0){ + t = tst1 = norm; + do { + t *= 0.01; + tst2 = norm + t; + } while (tst2 > tst1); + } //End if t == 0.0 + A[j][en] = -(r/t); + }//End if wi[j] == 0.0 + else { //wi[j] > 0.0; Solve real equations + x = A[j][j + 1]; + y = A[j + 1][j]; + q = (-p + wr[j])*(-p + wr[j]) + wi[j]*wi[j]; + A[j][en] = t = (-(zz*r) + x*s)/q; + A[j + 1][en] = ((fabs(x) > fabs(zz)) ? -(r + w*t)/x : -(s + y*t)/zz); + }//End else wi[j] > 0.0 + + // Overflow control + t = fabs(A[j][en]); + if (t == 0.0) + continue; //go up to top of for j loop + tst1 = t; + tst2 = tst1 + 1.0/tst1; + if (tst2 > tst1) + continue; //go up to top of for j loop + for (int ii = j; ii <= en; ii++) + A[ii][en] /= t; + + }//End else wi[j] >= 0.0 + + }//End for j + + } //End q == 0.0 + + else {//else q < 0.0, complex vector + //Last vector component chosen imaginary so that eigenvector + //matrix is triangular + m = na; + + if (fabs(A[en][na]) <= fabs(A[na][en])) + cdivA(0.0, -A[na][en], -p + A[na][na], q, A, na, na, en); + else { + A[na][na] = q/A[en][na]; + A[na][en] = -(-p + A[en][en])/A[en][na]; + } //End else (fabs(A[en][na] > fabs(A[na][en]) + + A[en][na] = 0.0; + A[en][en] = 1.0; + + for (int j = (na - 1); j >= 0; j--) { + w = -p + A[j][j]; + sa = ra = 0.0; + + for (int ii = m; ii <= en; ii++) { + ra += A[j][ii]*A[ii][na]; + sa += A[j][ii]*A[ii][en]; + } //End for ii + + if (wi[j] < 0.0){ + zz = w; + r = ra; + s = sa; + continue; + } //End if (wi[j] < 0.0) + + //else wi[j] >= 0.0 + m = j; + if (wi[j] == 0.0) + cdivA(-ra, -sa, w, q, A, j, na, en); + else {//wi[j] > 0.0; solve complex equations + x = A[j][j + 1]; + y = A[j + 1][j]; + vr = -(q*q) + (-p + wr[j])*(-p + wr[j]) + wi[j]*wi[j]; + vi = (-p + wr[j])*2.0*q; + if ((vr == 0.0) && (vi == 0.0)){ + tst1 = norm*(fabs(w) + fabs(q) + fabs(x) + fabs(y) + fabs(zz)); + vr = tst1; + do { + vr *= 0.01; + tst2 = tst1 + vr; + } while (tst2 > tst1); + } //End if vr and vi == 0.0 + cdivA(-(zz*ra) + x*r + q*sa, -(zz*sa + q*ra) + x*s, vr, vi, A, j, na, en); + + if (fabs(x) > (fabs(zz) + fabs(q))){ + A[j + 1][na] = (-(ra + w*A[j][na]) + q*A[j][en])/x; + A[j + 1][en] = -(sa + w*A[j][en] + q*A[j][na])/x; + }//End if + else + cdivA(-(r + y*A[j][na]), -(s + y*A[j][en]), zz, q, A, j + 1, na, en); + + }//End else wi[j] > 0.0 + + t = ((fabs(A[j][na]) >= fabs(A[j][en])) ? fabs(A[j][na]) : fabs(A[j][en])); + + if (t == 0.0) continue; // go to top of for j loop + + tst1 = t; + tst2 = tst1 + 1.0/tst1; + if (tst2 > tst1) continue; //go to top of for j loop + + for (int ii = j; ii <= en; ii++){ + A[ii][na] /= t; + A[ii][en] /= t; + } //End for ii loop + + } // End for j + + }//End else q < 0.0 + + }//End for en + + //End back substitution. Vectors of isolated roots. + + for (int i = 0; i < N; i++){ + if ((i < low) || (i > igh)) { + for (int j = i; j < N; j++) + B[i][j] = A[i][j]; + }//End if i + }//End for i + + // Multiply by transformation matrix to give vectors of original + // full matrix. + + //Step from (N - 1) to low in steps of -1. + + for (int i = (N - 1); i >= low; i--){ + + m = ((i < igh) ? i : igh); + + for (int ii = low; ii <= igh; ii++){ + zz = 0.0; + for (int jj = low; jj <= m; jj++) + zz += B[ii][jj]*A[jj][i]; + B[ii][i] = zz; + }//End for ii + }//End of for i loop + + return; +} //End of function hqr2 + +static void norVecC(double Z[N][N], double wi[N]) +{ + // Normalizes the eigenvectors + + // This subroutine is based on the LINPACK routine SNRM2, written 25 + // October 1982, modified on 14 October 1993 by Sven Hammarling of + // Nag Ltd. I have further modified it for use in this Javascript + // routine, for use with a column of an array rather than a column + // vector. + // + // Z - eigenvector Matrix + // wi - eigenvalue vector + + double scale, ssq, absxi, dummy, norm; + + for (int j = 0; j < N; j++){ //Go through the columns of the vector + //array + scale = 0.0; + ssq = 1.0; + + for (int i = 0; i < N; i++){ + if (Z[i][j] != 0){ + absxi = fabs(Z[i][j]); + dummy = scale/absxi; + if (scale < absxi){ + ssq = 1.0 + ssq*dummy*dummy; + scale = absxi; + }//End if (scale < absxi) + else + ssq += 1.0/dummy/dummy; + }//End if (Z[i][j] != 0) + } //End for i + + if (wi[j] != 0){// If complex eigenvalue, take into account + // imaginary part of eigenvector + for (int i = 0; i < N; i++){ + if (Z[i][j + 1] != 0){ + absxi = fabs(Z[i][j + 1]); + dummy = scale/absxi; + if (scale < absxi){ + ssq = 1.0 + ssq*dummy*dummy; + scale = absxi; + }//End if (scale < absxi) + else + ssq += 1.0/dummy/dummy; + }//End if (Z[i][j + 1] != 0) + } //End for i + }//End if (wi[j] != 0) + + norm = scale*sqrt(ssq); //This is the norm of the (possibly + //complex) vector + + for (int i = 0; i < N; i++) + Z[i][j] /= norm; + + if (wi[j] != 0){// If complex eigenvalue, also scale imaginary + // part of eigenvector + j++; + for (int i = 0; i < N; i++) + Z[i][j] /= norm; + }//End if (wi[j] != 0) + + }// End for j + + return; +} // End norVecC + +static void swap_elements(double v[N], int i, int k) +{ + double tmp = v[k]; + v[k] = v[i]; + v[i] = tmp; +} + +static void swap_columns(double v[N][N], int i, int k) +{ + for(int n = 0; n < N; n++){ + double tmp = v[n][k]; + v[n][k] = v[n][i]; + v[n][i] = tmp; + } +} + +void EigenSort3x3(double wr[N], double wi[N], double B[N][N]) +{ + for (int i = 0; i < N - 1; i++){ + int k = i; + double ek = wr[i]; + // search for something to swap + for (int j = i + 1; j < N; j++){ + const double ej = wr[j]; + if(ej < ek){ + k = j; + ek = ej; + } + } + if (k != i){ + swap_elements (wr, i, k); + swap_elements (wi, i, k); + swap_columns (B, i, k); + } + } +} + +int EigenSolve3x3(double A[N][N], double wr[N], double wi[N], double B[N][N]) +{ + // Balance the matrix to improve accuracy of eigenvalues. Introduces + // no rounding errors, since it scales A by powers of the radix. + + double scale[N]; //Contains information about transformations. + int trace[N]; //Records row and column interchanges + double radix = 2; //Base of machine floating point representation. + double c, f, g, r, s, b2 = radix*radix; + int ierr = -1, igh, low, k = 0, l = N - 1, noconv; + + //Search through rows, isolating eigenvalues and pushing them down. + + noconv = l; + + while (noconv >= 0){ + r = 0; + + for (int j = 0; j <= l; j++) { + if (j == noconv) continue; + if (A[noconv][j] != 0.0){ + r = 1; + break; + } + } //End for j + + if (r == 0){ + scale[l] = noconv; + + if (noconv != l){ + for (int i = 0; i <= l; i++){ + f = A[i][noconv]; + A[i][noconv] = A[i][l]; + A[i][l] = f; + }//End for i + for (int i = 0; i < N; i++){ + f = A[noconv][i]; + A[noconv][i] = A[l][i]; + A[l][i] = f; + }//End for i + }//End if (noconv != l) + + if (l == 0) + break; //break out of while loop + + noconv = --l; + + }//End if (r == 0) + + else //else (r != 0) + noconv--; + + }//End while noconv + + if (l > 0) { //Search through columns, isolating eigenvalues and + //pushing them left. + + noconv = 0; + + while (noconv <= l){ + c = 0; + + for (int i = k; i <= l; i++){ + if (i == noconv) continue; + if (A[i][noconv] != 0.0){ + c = 1; + break; + } + }//End for i + + if (c == 0){ + scale[k] = noconv; + + if (noconv != k){ + for (int i = 0; i <= l; i++){ + f = A[i][noconv]; + A[i][noconv] = A[i][k]; + A[i][k] = f; + }//End for i + for (int i = k; i < N; i++){ + f = A[noconv][i]; + A[noconv][i] = A[k][i]; + A[k][i] = f; + }//End for i + + }//End if (noconv != k) + + noconv = ++k; + }//End if (c == 0) + + else //else (c != 0) + noconv++; + + }//End while noconv + + //Balance the submatrix in rows k through l. + + for (int i = k; i <= l; i++) + scale[i] = 1.0; + + //Iterative loop for norm reduction + do { + noconv = 0; + for (int i = k; i <= l; i++) { + c = r = 0.0; + for (int j = k; j <= l; j++){ + if (j == i) continue; + c += fabs(A[j][i]); + r += fabs(A[i][j]); + } // End for j + //guard against zero c or r due to underflow: + if ((c == 0.0) || (r == 0.0)) continue; + g = r/radix; + f = 1.0; + s = c + r; + while (c < g) { + f *= radix; + c *= b2; + } // End while (c < g) + g = r*radix; + while (c >= g) { + f /= radix; + c /= b2; + } // End while (c >= g) + + //Now balance + if ((c + r)/f < 0.95*s) { + g = 1.0/f; + scale[i] *= f; + noconv = 1; + for (int j = k; j < N; j++) + A[i][j] *= g; + for (int j = 0; j <= l; j++) + A[j][i] *= f; + } //End if ((c + r)/f < 0.95*s) + } // End for i + } while (noconv); // End of do-while loop. + + } //End if (l > 0) + + low = k; + igh = l; + + //End of balanc + + // Now reduce the real general Matrix to upper-Hessenberg form using + // stabilized elementary similarity transformations. + + for (int i = (low + 1); i < igh; i++){ + k = i; + c = 0.0; + + for (int j = i; j <= igh; j++){ + if (fabs(A[j][i - 1]) > fabs(c)){ + c = A[j][i - 1]; + k = j; + }//End if + }//End for j + + trace[i] = k; + + if (k != i){ + for (int j = (i - 1); j < N; j++){ + r = A[k][j]; + A[k][j] = A[i][j]; + A[i][j] = r; + }//End for j + + for (int j = 0; j <= igh; j++){ + r = A[j][k]; + A[j][k] = A[j][i]; + A[j][i] = r; + }//End for j + }//End if (k != i) + + if (c != 0.0){ + for (int m = (i + 1); m <= igh; m++){ + r = A[m][i - 1]; + + if (r != 0.0){ + r = A[m][i - 1] = r/c; + for (int j = i; j < N; j++) + A[m][j] += -(r*A[i][j]); + for (int j = 0; j <= igh; j++) + A[j][i] += r*A[j][m]; + }//End if (r != 0.0) + }//End for m + }//End if (c != 0) + } //End for i. + + // Accumulate the stabilized elementary similarity transformations + // used in the reduction of A to upper-Hessenberg form. Introduces + // no rounding errors since it only transfers the multipliers used + // in the reduction process into the eigenvector matrix. + + for (int i = 0; i < N; i++){ //Initialize B to the identity Matrix. + for (int j = 0; j < N; j++) + B[i][j] = 0.0; + B[i][i] = 1.0; + } //End for i + + for (int i = (igh - 1); i >= (low + 1); i--){ + k = trace[i]; + for (int j = (i + 1); j <= igh; j++) + B[j][i] = A[j][i - 1]; + + if (i == k) + continue; + + for (int j = i; j <= igh; j++){ + B[i][j] = B[k][j]; + B[k][j] = 0.0; + } //End for j + + B[k][i] = 1.0; + + } // End for i + + hqr2(A, B, low, igh, wi, wr, ierr); + + if (ierr == -1){ + + if (low != igh){ + for (int i = low; i <= igh; i++){ + s = scale[i]; + for (int j = 0; j < N; j++) + B[i][j] *= s; + }//End for i + }//End if (low != igh) + + for (int i = (low - 1); i >= 0; i--){ + k = (int)scale[i];//FIXME: I added the cast + if (k != i){ + for (int j = 0; j < N; j++){ + s = B[i][j]; + B[i][j] = B[k][j]; + B[k][j] = s; + }//End for j + }//End if k != i + }//End for i + + for (int i = (igh + 1); i < N; i++){ + k = (int)scale[i];//FIXME: Iadded the casr + if (k != i){ + for (int j = 0; j < N; j++){ + s = B[i][j]; + B[i][j] = B[k][j]; + B[k][j] = s; + }//End for j + }//End if k != i + }//End for i + + norVecC(B, wi); //Normalize the eigenvectors + + }//End if ierr = -1 + + EigenSort3x3(wr, wi, B); + + return ierr; +} //End of Eig3Solve + +# if 0 +int main() +{ + double wr[3], wi[3], B[3][3]; + for(int i = 0; i < 1000000; i++){ // perf test + double A[3][3] = { {1.,2.,3.}, {2.,4.,5.}, {3.,5.,6.} }; + EigenSolve3x3(A, wr, wi, B); + } + /* + printf("%g %g %g\n", A[0][0], A[0][1], A[0][2]); + printf("%g %g %g\n", A[1][0], A[1][1], A[1][2]); + printf("%g %g %g\n", A[2][0], A[2][1], A[2][2]); + */ + printf("real= %g %g %g \n", wr[0], wr[1], wr[2]); + printf("imag= %g %g %g \n", wi[0], wi[1], wi[2]); + printf("eigvec1 = %g %g %g \n", B[0][0], B[1][0], B[2][0]); + printf("eigvec2 = %g %g %g \n", B[0][1], B[1][1], B[2][1]); + printf("eigvec3 = %g %g %g \n", B[0][2], B[1][2], B[2][2]); +} +#endif diff --git a/Numeric/Makefile b/Numeric/Makefile index 7d0d435914903a27adcd2d19565ab2717e9b2b1a..216ffd20f9a6cc32459db3dc930477aa8172fe4c 100644 --- a/Numeric/Makefile +++ b/Numeric/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.14 2004-11-09 19:53:47 geuzaine Exp $ +# $Id: Makefile,v 1.15 2004-12-08 03:09:03 geuzaine Exp $ # # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle # @@ -26,6 +26,7 @@ INCLUDE = -I../Common -I../DataStr CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} SRC = Numeric.cpp\ + EigenSolve3x3.cpp\ gsl_newt.cpp\ gsl_brent.cpp @@ -55,6 +56,9 @@ depend: Numeric.o: Numeric.cpp ../Common/Gmsh.h ../Common/Message.h \ ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ ../DataStr/avl.h ../DataStr/Tools.h Numeric.h +EigenSolve3x3.o: EigenSolve3x3.cpp ../Common/Gmsh.h ../Common/Message.h \ + ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ + ../DataStr/avl.h ../DataStr/Tools.h Numeric.h gsl_newt.o: gsl_newt.cpp ../Common/Gmsh.h ../Common/Message.h \ ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ ../DataStr/avl.h ../DataStr/Tools.h Numeric.h