--- trunk/OOPSE-2.0/src/math/SquareMatrix.hpp 2005/03/01 20:10:14 2069 +++ trunk/OOPSE-2.0/src/math/SquareMatrix.hpp 2005/04/15 22:04:00 2204 @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved. * * The University of Notre Dame grants you ("Licensee") a @@ -45,170 +45,170 @@ * @date 10/11/2004 * @version 1.0 */ - #ifndef MATH_SQUAREMATRIX_HPP +#ifndef MATH_SQUAREMATRIX_HPP #define MATH_SQUAREMATRIX_HPP #include "math/RectMatrix.hpp" namespace oopse { - /** - * @class SquareMatrix SquareMatrix.hpp "math/SquareMatrix.hpp" - * @brief A square matrix class - * @template Real the element type - * @template Dim the dimension of the square matrix - */ - template - class SquareMatrix : public RectMatrix { - public: - typedef Real ElemType; - typedef Real* ElemPoinerType; + /** + * @class SquareMatrix SquareMatrix.hpp "math/SquareMatrix.hpp" + * @brief A square matrix class + * @template Real the element type + * @template Dim the dimension of the square matrix + */ + template + class SquareMatrix : public RectMatrix { + public: + typedef Real ElemType; + typedef Real* ElemPoinerType; - /** default constructor */ - SquareMatrix() { - for (unsigned int i = 0; i < Dim; i++) - for (unsigned int j = 0; j < Dim; j++) - this->data_[i][j] = 0.0; - } + /** default constructor */ + SquareMatrix() { + for (unsigned int i = 0; i < Dim; i++) + for (unsigned int j = 0; j < Dim; j++) + this->data_[i][j] = 0.0; + } - /** Constructs and initializes every element of this matrix to a scalar */ - SquareMatrix(Real s) : RectMatrix(s){ - } + /** Constructs and initializes every element of this matrix to a scalar */ + SquareMatrix(Real s) : RectMatrix(s){ + } - /** Constructs and initializes from an array */ - SquareMatrix(Real* array) : RectMatrix(array){ - } + /** Constructs and initializes from an array */ + SquareMatrix(Real* array) : RectMatrix(array){ + } - /** copy constructor */ - SquareMatrix(const RectMatrix& m) : RectMatrix(m) { - } + /** copy constructor */ + SquareMatrix(const RectMatrix& m) : RectMatrix(m) { + } - /** copy assignment operator */ - SquareMatrix& operator =(const RectMatrix& m) { - RectMatrix::operator=(m); - return *this; - } + /** copy assignment operator */ + SquareMatrix& operator =(const RectMatrix& m) { + RectMatrix::operator=(m); + return *this; + } - /** Retunrs an identity matrix*/ + /** Retunrs an identity matrix*/ - static SquareMatrix identity() { - SquareMatrix m; + static SquareMatrix identity() { + SquareMatrix m; - for (unsigned int i = 0; i < Dim; i++) - for (unsigned int j = 0; j < Dim; j++) - if (i == j) - m(i, j) = 1.0; - else - m(i, j) = 0.0; + for (unsigned int i = 0; i < Dim; i++) + for (unsigned int j = 0; j < Dim; j++) + if (i == j) + m(i, j) = 1.0; + else + m(i, j) = 0.0; - return m; - } + return m; + } - /** - * Retunrs the inversion of this matrix. - * @todo need implementation - */ - SquareMatrix inverse() { - SquareMatrix result; + /** + * Retunrs the inversion of this matrix. + * @todo need implementation + */ + SquareMatrix inverse() { + SquareMatrix result; - return result; - } + return result; + } - /** - * Returns the determinant of this matrix. - * @todo need implementation - */ - Real determinant() const { - Real det; - return det; - } + /** + * Returns the determinant of this matrix. + * @todo need implementation + */ + Real determinant() const { + Real det; + return det; + } - /** Returns the trace of this matrix. */ - Real trace() const { - Real tmp = 0; + /** Returns the trace of this matrix. */ + Real trace() const { + Real tmp = 0; - for (unsigned int i = 0; i < Dim ; i++) - tmp += this->data_[i][i]; + for (unsigned int i = 0; i < Dim ; i++) + tmp += this->data_[i][i]; - return tmp; - } + return tmp; + } - /** Tests if this matrix is symmetrix. */ - bool isSymmetric() const { - for (unsigned int i = 0; i < Dim - 1; i++) - for (unsigned int j = i; j < Dim; j++) - if (fabs(this->data_[i][j] - this->data_[j][i]) > oopse::epsilon) - return false; + /** Tests if this matrix is symmetrix. */ + bool isSymmetric() const { + for (unsigned int i = 0; i < Dim - 1; i++) + for (unsigned int j = i; j < Dim; j++) + if (fabs(this->data_[i][j] - this->data_[j][i]) > oopse::epsilon) + return false; - return true; - } + return true; + } - /** Tests if this matrix is orthogonal. */ - bool isOrthogonal() { - SquareMatrix tmp; + /** Tests if this matrix is orthogonal. */ + bool isOrthogonal() { + SquareMatrix tmp; - tmp = *this * transpose(); + tmp = *this * transpose(); - return tmp.isDiagonal(); - } + return tmp.isDiagonal(); + } - /** Tests if this matrix is diagonal. */ - bool isDiagonal() const { - for (unsigned int i = 0; i < Dim ; i++) - for (unsigned int j = 0; j < Dim; j++) - if (i !=j && fabs(this->data_[i][j]) > oopse::epsilon) - return false; + /** Tests if this matrix is diagonal. */ + bool isDiagonal() const { + for (unsigned int i = 0; i < Dim ; i++) + for (unsigned int j = 0; j < Dim; j++) + if (i !=j && fabs(this->data_[i][j]) > oopse::epsilon) + return false; - return true; - } + return true; + } - /** Tests if this matrix is the unit matrix. */ - bool isUnitMatrix() const { - if (!isDiagonal()) - return false; + /** Tests if this matrix is the unit matrix. */ + bool isUnitMatrix() const { + if (!isDiagonal()) + return false; - for (unsigned int i = 0; i < Dim ; i++) - if (fabs(this->data_[i][i] - 1) > oopse::epsilon) - return false; + for (unsigned int i = 0; i < Dim ; i++) + if (fabs(this->data_[i][i] - 1) > oopse::epsilon) + return false; - return true; - } + return true; + } - /** Return the transpose of this matrix */ - SquareMatrix transpose() const{ - SquareMatrix result; + /** Return the transpose of this matrix */ + SquareMatrix transpose() const{ + SquareMatrix result; - for (unsigned int i = 0; i < Dim; i++) - for (unsigned int j = 0; j < Dim; j++) - result(j, i) = this->data_[i][j]; + for (unsigned int i = 0; i < Dim; i++) + for (unsigned int j = 0; j < Dim; j++) + result(j, i) = this->data_[i][j]; - return result; - } + return result; + } - /** @todo need implementation */ - void diagonalize() { - //jacobi(m, eigenValues, ortMat); - } + /** @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. - */ + /** + * 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 + static int jacobi(SquareMatrix& a, Vector& d, + SquareMatrix& v); + };//end SquareMatrix -/*========================================================================= + /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: SquareMatrix.hpp,v $ @@ -217,176 +217,176 @@ namespace oopse { 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. + 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_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]; - } + // 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; - // initialize - for (ip=0; ip 4) { + b = new Real[n]; + z = new Real[n]; + } - // begin rotation sequence - for (i=0; i 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; + 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; - for (ip=0; ip= VTK_MAX_ROTATIONS ) { - std::cout << "vtkMath::Jacobi: Error extracting eigenfunctions" << std::endl; - return 0; - } + for (ip=0; ip= 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= VTK_MAX_ROTATIONS ) { + std::cout << "vtkMath::Jacobi: Error extracting eigenfunctions" << std::endl; + return 0; + } - if (n > 4) { - delete [] b; - delete [] z; - } - return 1; + // 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