/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2000 Johan Rossouw (jrossouw@alcatel.altech.co.za) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library 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 Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include using namespace std; #include const TReal ZERO = 1E-1000; uint Matrix::counter_ = 0; //--------------------------------------------------------------------------- Matrix::Matrix() : rows_(0), cols_(0), matrix_(0) { counter_++; } //--------------------------------------------------------------------------- Matrix::Matrix(uint size) : rows_(size), cols_(size), matrix_(0) { allocateMemory(); zero(); counter_++; } //--------------------------------------------------------------------------- Matrix::Matrix(uint rows, uint cols) : rows_(rows), cols_(cols), matrix_(0) { allocateMemory(); zero(); counter_++; } //--------------------------------------------------------------------------- Matrix::Matrix(const Matrix& matrix) : rows_(0), cols_(0), matrix_(0) { rows_ = matrix.rows_; cols_ = matrix.cols_; allocateMemory(); //Copy data for (uint r = 0; r < rows_; r++) { for (uint c = 0; c < cols_; c++) { matrix_[r][c] = matrix.matrix_[r][c]; } } counter_++; } //--------------------------------------------------------------------------- Matrix::~Matrix() { clear(); counter_--; } //--------------------------------------------------------------------------- Matrix& Matrix::operator=(const Matrix& matrix) { if ( ( rows_ != matrix.rows_ ) || ( cols_ != matrix.cols_ ) ) { resize( matrix.rows_, matrix.cols_ ); } for (uint r = 0; r < rows_; r++) { for (uint c = 0; c < cols_; c++) { matrix_[r][c] = matrix.matrix_[r][c]; } } return *this; } //--------------------------------------------------------------------------- TComplex& Matrix::operator()(uint row, uint col) { ASSERT((row <= rows_) && (col <= cols_)); return matrix_[row][col]; } //--------------------------------------------------------------------------- Matrix Matrix::operator+(const Matrix& matrix) { if ( (rows_ != matrix.rows_) && (cols_ != matrix.cols_) ) { Logger::error("Matrix::operator+() - throwing ExceptionMatrixSizeMismatch() exception"); throw ExceptionMatrixSizeMismatch(); } Matrix temp( cols_, rows_ ); for (uint r = 0; r < rows_; r++) { for (uint c = 0; c < cols_; c++) { temp.matrix_[r][c] = matrix_[r][c] + matrix.matrix_[r][c]; } } return temp; } //--------------------------------------------------------------------------- Matrix Matrix::operator-(const Matrix& matrix) { if ( (rows_ != matrix.rows_) && (cols_ != matrix.cols_) ) { Logger::error("Matrix::operator-() - throwing ExceptionMatrixSizeMismatch() exception"); throw ExceptionMatrixSizeMismatch(); } Matrix temp( cols_, rows_ ); for (uint r = 0; r < rows_; r++) { for (uint c = 0; c < cols_; c++) { temp.matrix_[r][c] = matrix_[r][c] - matrix.matrix_[r][c]; } } return temp; } //--------------------------------------------------------------------------- Matrix Matrix::operator*(const Matrix& matrix) { unsigned long i, j, k; TComplex t; if ( this->cols_ != matrix.rows_ ) { Logger::error("Matrix::operator*() - throwing ExceptionMatrixSizeMismatch() exception" ); throw ExceptionMatrixSizeMismatch(); } Matrix temp(rows_, matrix.cols_); for (i = 0; i < rows_; i++) for (j = 0; j < matrix.cols_; j++) { t = 0.0; for (k = 0; k < cols_; k++) { t += matrix_[i][k] * matrix.matrix_[k][j]; } temp.matrix_[i][j] = t; } return temp; } //--------------------------------------------------------------------------- Matrix& Matrix::operator~() { uint* indxc = new uint [cols_]; //indxc[i] : the column of the i'th pivot uint* indxr = new uint [rows_]; //indyc[i] : the (orig) row of the i'th pivot uint* ipiv = new uint [cols_]; //bookkeeping of pivot element uint irow = 0; //stores the current pivot row uint icol = 0; //...and pivot column for (uint init=0; init= abs(big) ) { big = abs(matrix_[j][k]); irow=j; icol=k; } } else if (ipiv[k] > 1) { delete [] indxc; delete [] indxr; delete [] ipiv; Logger::error("Matrix::operator~() - throwing ExceptionMatrixSingular() exception"); throw ExceptionMatrixSingular(); } } } } ++(ipiv[icol]); if (irow != icol) { swapRows(irow, icol); } indxr[i] = irow; indxc[i] = icol; if ( abs(matrix_[icol][icol]) <= ZERO ) { delete [] indxc; delete [] indxr; delete [] ipiv; Logger::error("Matrix::operator~() - throwing ExceptionMatrixSingular() exception"); throw ExceptionMatrixSingular(); } TComplex pivinv = 1.0 / matrix_[icol][icol]; matrix_[icol][icol] = TComplex(1.0,0.0); for (uint c=0; c0; cols--) { uint c = cols-1; if (indxr[c] != indxc[c]) { swapColumns(indxr[c], indxc[c]); } } delete [] indxc; delete [] indxr; delete [] ipiv; return *this; } //--------------------------------------------------------------------------- Matrix Matrix::subMatrix(uint startRow, uint startCol, uint noRows, uint noCols) { if ( ((startRow+noRows)>rows_) || ((startCol+noCols)>cols_) ) { Logger::error("Matrix::subMatrix() - throwing ExceptionMatrixBoundsOverrun() exception"); throw ExceptionMatrixBoundsOverrun(); } Matrix temp( noRows, noCols ); for (uint r=0; r=4; k--) { TComplex piv; piv = TComplex(0,0); {//For resolving namespace difference in for scoping for (uint j=1; j