--- trunk/src/math/SquareMatrix.hpp 2004/10/13 23:53:40 74 +++ trunk/src/math/SquareMatrix.hpp 2004/10/20 18:07:08 123 @@ -29,7 +29,7 @@ * @date 10/11/2004 * @version 1.0 */ -#ifndef MATH_SQUAREMATRIX_HPP + #ifndef MATH_SQUAREMATRIX_HPP #define MATH_SQUAREMATRIX_HPP #include "math/RectMatrix.hpp" @@ -78,24 +78,28 @@ namespace oopse { return m; } - /** Retunrs the inversion of this matrix. */ + /** + * Retunrs the inversion of this matrix. + * @todo need implementation + */ SquareMatrix inverse() { SquareMatrix result; return result; - } + } - - - /** Returns the determinant of this matrix. */ - double determinant() const { - double det; + /** + * Returns the determinant of this matrix. + * @todo need implementation + */ + Real determinant() const { + Real det; return det; } /** Returns the trace of this matrix. */ - double trace() const { - double tmp = 0; + Real trace() const { + Real tmp = 0; for (unsigned int i = 0; i < Dim ; i++) tmp += data_[i][i]; @@ -113,13 +117,13 @@ namespace oopse { return true; } - /** Tests if this matrix is orthogona. */ + /** Tests if this matrix is orthogonal. */ bool isOrthogonal() { SquareMatrix tmp; tmp = *this * transpose(); - return tmp.isUnitMatrix(); + return tmp.isDiagonal(); } /** Tests if this matrix is diagonal. */ @@ -144,7 +148,244 @@ namespace oopse { return true; } + /** @todo need implementation */ + void diagonalize() { + //jacobi(m, eigenValues, ortMat); + } + + /** + * Jacobi iteration routines for computing eigenvalues/eigenvectors of + * real symmetric matrix + * + * @return true if success, otherwise return false + * @param a symmetric matrix whose eigenvectors are to be computed. On return, the matrix is + * overwritten + * @param w will contain the eigenvalues of the matrix On return of this function + * @param v the columns of this matrix will contain the eigenvectors. The eigenvectors are + * normalized and mutually orthogonal. + */ + + static int jacobi(SquareMatrix& a, Vector& d, + SquareMatrix& v); };//end SquareMatrix + +/*========================================================================= + + Program: Visualization Toolkit + Module: $RCSfile: SquareMatrix.hpp,v $ + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ + +#define VTK_ROTATE(a,i,j,k,l) g=a(i, j);h=a(k, l);a(i, j)=g-s*(h+g*tau);\ + a(k, l)=h+s*(g-h*tau) + +#define VTK_MAX_ROTATIONS 20 + + // Jacobi iteration for the solution of eigenvectors/eigenvalues of a nxn + // real symmetric matrix. Square nxn matrix a; size of matrix in n; + // output eigenvalues in w; and output eigenvectors in v. Resulting + // eigenvalues/vectors are sorted in decreasing order; eigenvectors are + // normalized. + template + int SquareMatrix::jacobi(SquareMatrix& a, Vector& w, + SquareMatrix& v) { + const int n = Dim; + int i, j, k, iq, ip, numPos; + Real tresh, theta, tau, t, sm, s, h, g, c, tmp; + Real bspace[4], zspace[4]; + Real *b = bspace; + Real *z = zspace; + + // only allocate memory if the matrix is large + if (n > 4) + { + b = new Real[n]; + z = new Real[n]; + } + + // initialize + for (ip=0; ip 3 && (fabs(w[ip])+g) == fabs(w[ip]) + && (fabs(w[iq])+g) == fabs(w[iq])) + { + a(ip, iq) = 0.0; + } + else if (fabs(a(ip, iq)) > tresh) + { + h = w[iq] - w[ip]; + if ( (fabs(h)+g) == fabs(h)) + { + t = (a(ip, iq)) / h; + } + else + { + theta = 0.5*h / (a(ip, iq)); + t = 1.0 / (fabs(theta)+sqrt(1.0+theta*theta)); + if (theta < 0.0) + { + t = -t; + } + } + c = 1.0 / sqrt(1+t*t); + s = t*c; + tau = s/(1.0+c); + h = t*a(ip, iq); + z[ip] -= h; + z[iq] += h; + w[ip] -= h; + w[iq] += h; + a(ip, iq)=0.0; + + // ip already shifted left by 1 unit + for (j = 0;j <= ip-1;j++) + { + VTK_ROTATE(a,j,ip,j,iq); + } + // ip and iq already shifted left by 1 unit + for (j = ip+1;j <= iq-1;j++) + { + VTK_ROTATE(a,ip,j,j,iq); + } + // iq already shifted left by 1 unit + for (j=iq+1; j= VTK_MAX_ROTATIONS ) + { + std::cout << "vtkMath::Jacobi: Error extracting eigenfunctions" << std::endl; + return 0; + } + + // sort eigenfunctions these changes do not affect accuracy + for (j=0; j= tmp) // why exchage if same? + { + k = i; + tmp = w[k]; + } + } + if (k != j) + { + w[k] = w[j]; + w[j] = tmp; + for (i=0; i> 1) + (n & 1); + for (j=0; j= 0.0 ) + { + numPos++; + } + } + // if ( numPos < ceil(double(n)/double(2.0)) ) + if ( numPos < ceil_half_n) + { + for(i=0; i 4) + { + delete [] b; + delete [] z; + } + return 1; + } + + } #endif //MATH_SQUAREMATRIX_HPP +