/* dtkMatrixSquared.tpp --- * * Author: Thibaud Kloczko * Copyright (C) 2008 - Thibaud Kloczko, Inria. * Created: Mon Jul 12 15:58:19 2010 (+0200) * Version: $Id: f43ad5141b744efad7fb2267edafcfbff71f7e56 $ * Last-Updated: jeu. mars 26 11:13:04 2015 (+0100) * By: Thibaud Kloczko * Update #: 22 */ /* Commentary: * */ /* Change log: * */ #ifndef DTKMATRIXSQUARED_TPP #define DTKMATRIXSQUARED_TPP #include "dtkMatrix.h" namespace dtkDeprecated { // ///////////////////////////////////////////////////////////////// // dtkMatrixSquared implementation // ///////////////////////////////////////////////////////////////// template inline dtkMatrixSquared::dtkMatrixSquared(const dtkMatrix& mat, unsigned irowStart, unsigned icolStart, unsigned irowEnd) : dtkMatrix(mat, irowStart, icolStart, irowEnd, icolStart + irowEnd - irowStart) { } template inline dtkMatrixSquared::dtkMatrixSquared(const dtkMatrixSquared& matSquared, unsigned irowStart, unsigned icolStart, unsigned irowEnd) : dtkMatrix(matSquared, irowStart, icolStart, irowEnd, icolStart + irowEnd - irowStart) { } template QString dtkMatrixSquared::identifier(void) const { return QString("dtkMatrixSquared<%1>").arg(typeid(T).name()); } template inline void dtkMatrixSquared::mapInto(const dtkMatrixSquared& matSquared, unsigned irowStart, unsigned icolStart, unsigned irowEnd) { dtkMatrix::mapInto(matSquared, irowStart, icolStart, irowEnd, icolStart + irowEnd - irowStart); } template inline dtkMatrixSquared& dtkMatrixSquared::operator =(const dtkMatrixSquared& matSquared) { return static_cast &>(dtkMatrix::operator=(matSquared)); } template inline dtkMatrixSquared& dtkMatrixSquared::operator +=(const dtkMatrixSquared& matSquared) { return static_cast &>(dtkMatrix::operator+=(matSquared)); } template inline dtkMatrixSquared& dtkMatrixSquared::operator -=(const dtkMatrixSquared& matSquared) { return static_cast &>(dtkMatrix::operator-=(matSquared)); } template inline dtkMatrixSquared& dtkMatrixSquared::operator *=(const T& value) { return static_cast &>(dtkMatrix::operator*=(value)); } template inline dtkMatrixSquared& dtkMatrixSquared::operator *=(const dtkMatrixSquared& matSquared) { return (*this) = (*this) * matSquared; } template inline dtkMatrixSquared& dtkMatrixSquared::operator /=(const T& value) { T tTmp = dtkUnity(); tTmp /= value; return (*this) *= tTmp; } template inline dtkMatrixSquared& dtkMatrixSquared::operator /=(const dtkMatrixSquared& matSquared) { return (*this) = (*this) / matSquared; } template dtkMatrixSquared dtkMatrixSquared::operator +(const dtkMatrixSquared& matSquared) const { return dtkMatrixSquared(*this) += matSquared; } template dtkMatrixSquared dtkMatrixSquared::operator -(const dtkMatrixSquared& matSquared) const { return dtkMatrixSquared(*this) -= matSquared; } template dtkMatrixSquared dtkMatrixSquared::operator -(void) const { T tTmp = dtkZero(); tTmp -= dtkUnity(); return (*this) * tTmp; } template dtkMatrixSquared dtkMatrixSquared::operator *(const T& value) const { return dtkMatrixSquared(*this) *= value; } template dtkMatrixSquared dtkMatrixSquared::operator *(const dtkMatrixSquared& matSquared) const { dtkMatrixSquared matSquaredResult(this->size()); matSquaredResult.storeProduct(*this, matSquared); return matSquaredResult; } template dtkMatrixSquared dtkMatrixSquared::operator /(const dtkMatrixSquared& matSquared) const { return (*this) * inv(matSquared); } template void dtkMatrixSquared::storeInverse(const dtkMatrixSquared& matSquared) { (*this) = matSquared; makeInverse(); } template void dtkMatrixSquared::makeUnity(void) { unsigned crow(this->numberOfRows()), ccol(this->numberOfColumns()); for (unsigned irow = 0; irow < crow; ++irow) { for (unsigned icol = 0; icol < ccol; ++icol) { if (irow == icol) (*this)[irow][icol] = dtkUnity(); else (*this)[irow][icol] = dtkZero(); } } } template void dtkMatrixSquared::makeAdjoint(void) { // we need a copy of this dtkMatrixSquared matSquaredCopy(*this); // for easier access to crows unsigned crowCopy = matSquaredCopy.numberOfRows(); T elemTmp; // will eventually contain det(matSquaredCopy) T elemDet = dtkUnity(); // make this a unity matrix makeUnity(); // start row reduction for (unsigned irow = 0; irow < crowCopy; ++irow) { // if element [irow][irow] is zero, add a row with non-zero // element at column irow if (matSquaredCopy[irow][irow] == dtkZero()) { for (unsigned irowTmp = irow; irowTmp < crowCopy; ++irowTmp) { if (matSquaredCopy[irowTmp][irow] != dtkZero()) { // has no effect on adj(matSquared) matSquaredCopy.addRowToRow(irowTmp, irow); // repeat action on this this->addRowToRow(irowTmp, irow); break; }; }; }; elemTmp = matSquaredCopy[irow][irow]; T tTmp = dtkUnity(); tTmp /= elemTmp; matSquaredCopy.multiplyRow(irow, tTmp); // repeat action on this multiplyRow(irow, tTmp); elemDet *= elemTmp; for (unsigned irowToAddTo = 0; irowToAddTo < crowCopy; ++irowToAddTo) { if (irowToAddTo != irow) { elemTmp = -matSquaredCopy[irowToAddTo][irow]; matSquaredCopy.addRowToRow(irow, irowToAddTo, elemTmp); // repeat action on this addRowToRow(irow, irowToAddTo, elemTmp); }; }; }; // this now contains its adjoint (*this) *= elemDet; } template void dtkMatrixSquared::storeAdjoint(const dtkMatrixSquared& matSquared) { (*this) = matSquared; makeAdjoint(); } template void dtkMatrixSquared::makeInverse(void) { // we need a copy of this dtkMatrixSquared matSquaredCopy(*this); // for easier access to crows unsigned crowCopy = matSquaredCopy.numberOfRows(); T elemTmp; // make this a unity matrix makeUnity(); // start row reduction for (unsigned irow = 0; irow < crowCopy; ++irow) { // if element [irow][irow] is zero, add a row with non-zero // element at column irow if (matSquaredCopy[irow][irow] == dtkZero()) { for (unsigned irowTmp = irow; irowTmp < crowCopy; ++irowTmp) { // has no effect on inv(matSquared) if (matSquaredCopy[irowTmp][irow] != dtkZero()) { matSquaredCopy.addRowToRow(irowTmp, irow); // repeat action on this this->addRowToRow(irowTmp, irow); break; }; }; }; elemTmp = matSquaredCopy[irow][irow]; // NOTE: This used to work with g++ <= 3.2. // matSquaredCopy.multiplyRow(irow, // static_cast(dtkUnity()/elemTmp)); // multiplyRow(irow, static_cast(dtkUnity()/elemTmp)); T tTmp = dtkUnity(); tTmp /= elemTmp; matSquaredCopy.multiplyRow(irow, tTmp); this->multiplyRow(irow, tTmp); for (unsigned irowToAddTo = 0; irowToAddTo < crowCopy; ++irowToAddTo) { if (irowToAddTo != irow) { elemTmp = -matSquaredCopy[irowToAddTo][irow]; matSquaredCopy.addRowToRow(irow, irowToAddTo, elemTmp); // repeat action on this this->addRowToRow(irow, irowToAddTo, elemTmp); }; }; }; // this now contains its inverse } template inline dtkMatrixSquared operator *(const T& value, const dtkMatrixSquared& matSquared) { return matSquared * value; } template dtkMatrixSquared dtkTranspose(const dtkMatrixSquared& matSquared) { dtkMatrixSquared matSquaredResult(matSquared.size()); matSquaredResult.storeTranspose(matSquared); return matSquaredResult; } template dtkMatrixSquared dtkAdjoint(const dtkMatrixSquared& matSquared) { dtkMatrixSquared matSquaredResult(matSquared); matSquaredResult.makeAdjoint(); return matSquaredResult; } template dtkMatrixSquared dtkInverse(const dtkMatrixSquared& matSquared) { dtkMatrixSquared matSquaredResult(matSquared); matSquaredResult.makeInverse(); return matSquaredResult; } template T dtkDeterminant(const dtkMatrixSquared& matSquared) { // a copy of the input matrix dtkMatrixSquared matSquaredCopy(matSquared); unsigned crowCopy = matSquaredCopy.numberOfRows(); // start row reduction T elemTmp; // will eventually contain det(matSquaredCopy) T elemDet = dtkUnity(); for (unsigned irow = 0; irow < crowCopy; ++irow) { // if element [irow][irow] is zero, add a row with non-zero // element at column irow if (matSquaredCopy[irow][irow] == dtkZero()) { for (unsigned irowTmp = irow; irowTmp < crowCopy; ++irowTmp) { // has no effect on inv(matSquared) if (matSquaredCopy[irowTmp][irow] != dtkZero()) { matSquaredCopy.addRowToRow(irowTmp, irow); break; }; }; }; elemTmp = matSquaredCopy[irow][irow]; elemDet *= elemTmp; if (elemDet == dtkZero()) { // once elemDet is zero it will stay zero return elemDet; } matSquaredCopy.multiplyRow(irow, dtkUnity() / elemTmp); for (unsigned irowToAddTo = 0; irowToAddTo < crowCopy; ++irowToAddTo) { if (irowToAddTo != irow) { matSquaredCopy.addRowToRow(irow, irowToAddTo, -matSquaredCopy[irowToAddTo][irow]); }; }; }; return elemDet; } template T dtkMatrixSquaredTrace(const dtkMatrixSquared& matSquared) { T elemTmp = dtkZero(); for (uint i = 0; i < matSquared.size(); i++) elemTmp += matSquared[i][i]; return elemTmp; } } // end of namespace #endif