// // Definitions for class BFMatrix // // Jesper Andersson, FMRIB Image Analysis Group // // Copyright (C) 2007 University of Oxford // #include <iostream> #include <iomanip> #include <fstream> #include <boost/shared_ptr.hpp> #include "newmat.h" #include "newmatio.h" #include "miscmaths.h" #include "bfmatrix.h" namespace MISCMATHS { // // Member functions for FullBFMatrix // void FullBFMatrix::Print(const std::string fname) const { if (!fname.length()) cout << endl << *mp << endl; else write_ascii_matrix(fname,*mp); } boost::shared_ptr<BFMatrix> FullBFMatrix::Transpose() const { boost::shared_ptr<FullBFMatrix> tm(new FullBFMatrix(mp->t())); return(tm); } // // Concatenate two matrices yielding a third // void FullBFMatrix::HorConcat(const BFMatrix& B, BFMatrix& AB) const { if (B.Nrows() && Nrows() != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat: Matrices must have same # of rows");} FullBFMatrix *pAB = dynamic_cast<FullBFMatrix *>(&AB); if (pAB) { // This means output is a full matrix *pAB = *this; pAB->HorConcat2MyRight(B); } else { SparseBFMatrix<double> *psdAB = dynamic_cast<SparseBFMatrix<double> *>(&AB); if (psdAB) { *psdAB = SparseBFMatrix<double>(this->AsMatrix()); psdAB->HorConcat2MyRight(B); } else { SparseBFMatrix<float> *psfAB = dynamic_cast<SparseBFMatrix<float> *>(&AB); if (psfAB) { *psfAB = SparseBFMatrix<float>(this->AsMatrix()); psfAB->HorConcat2MyRight(B); } else throw BFMatrixException("FullBFMatrix::HorConcat: dynamic cast error"); } } } void FullBFMatrix::HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const { if (B.Nrows() && int(Nrows()) != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat: Matrices must have same # of rows");} FullBFMatrix *pAB = dynamic_cast<FullBFMatrix *>(&AB); if (pAB) { // This means output is a full matrix *pAB = *this; pAB->HorConcat2MyRight(B); } else { SparseBFMatrix<double> *psdAB = dynamic_cast<SparseBFMatrix<double> *>(&AB); if (psdAB) { *psdAB = SparseBFMatrix<double>(this->AsMatrix()); psdAB->HorConcat2MyRight(B); } else { SparseBFMatrix<float> *psfAB = dynamic_cast<SparseBFMatrix<float> *>(&AB); if (psfAB) { *psfAB = SparseBFMatrix<float>(this->AsMatrix()); psfAB->HorConcat2MyRight(B); } else throw BFMatrixException("FullBFMatrix::HorConcat: dynamic cast error"); } } } void FullBFMatrix::VertConcat(const BFMatrix& B, BFMatrix& AB) const { if (B.Ncols() && Ncols() != B.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcat: Matrices must have same # of columns");} FullBFMatrix *pAB = dynamic_cast<FullBFMatrix *>(&AB); if (pAB) { // This means output is a full matrix *pAB = *this; pAB->VertConcatBelowMe(B); } else { SparseBFMatrix<double> *psdAB = dynamic_cast<SparseBFMatrix<double> *>(&AB); if (psdAB) { *psdAB = SparseBFMatrix<double>(this->AsMatrix()); psdAB->VertConcatBelowMe(B); } else { SparseBFMatrix<float> *psfAB = dynamic_cast<SparseBFMatrix<float> *>(&AB); if (psfAB) { *psfAB = SparseBFMatrix<float>(this->AsMatrix()); psfAB->VertConcatBelowMe(B); } else throw BFMatrixException("FullBFMatrix::VertConcat: dynamic cast error"); } } } void FullBFMatrix::VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const { if (B.Ncols() && int(Ncols()) != B.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcat: Matrices must have same # of columns");} FullBFMatrix *pAB = dynamic_cast<FullBFMatrix *>(&AB); if (pAB) { // This means output is a full matrix *pAB = *this; pAB->VertConcatBelowMe(B); } else { SparseBFMatrix<double> *psdAB = dynamic_cast<SparseBFMatrix<double> *>(&AB); if (psdAB) { *psdAB = SparseBFMatrix<double>(this->AsMatrix()); psdAB->VertConcatBelowMe(B); } else { SparseBFMatrix<float> *psfAB = dynamic_cast<SparseBFMatrix<float> *>(&AB); if (psfAB) { *psfAB = SparseBFMatrix<float>(this->AsMatrix()); psfAB->VertConcatBelowMe(B); } else throw BFMatrixException("FullBFMatrix::VertConcat: dynamic cast error"); } } } // // Concatenation of another matrix to *this // void FullBFMatrix::HorConcat2MyRight(const BFMatrix& B) { if (!B.Nrows()) return; if (Nrows() != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");} const FullBFMatrix *pB = dynamic_cast<const FullBFMatrix *>(&B); if (pB) { // If B was full *mp |= *(pB->mp); } else { const SparseBFMatrix<double> *psdB = dynamic_cast<const SparseBFMatrix<double> *>(&B); if (psdB) { this->HorConcat2MyRight(psdB->AsMatrix()); } else { const SparseBFMatrix<float> *psfB = dynamic_cast<const SparseBFMatrix<float> *>(&B); if (psfB) { this->HorConcat2MyRight(psfB->AsMatrix()); } else throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: dynamic cast error"); } } } void FullBFMatrix::HorConcat2MyRight(const NEWMAT::Matrix& B) { if (!B.Nrows()) return; if (int(Nrows()) != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");} *mp |= B; } void FullBFMatrix::VertConcatBelowMe(const BFMatrix& B) { if (!B.Ncols()) return; if (Ncols() != B.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcatBelowMe: Matrices must have same # of columns");} const FullBFMatrix *pB = dynamic_cast<const FullBFMatrix *>(&B); if (pB) { // Means B is full *mp &= *(pB->mp); } else { const SparseBFMatrix<double> *psdB = dynamic_cast<const SparseBFMatrix<double> *>(&B); if (psdB) { this->VertConcatBelowMe(psdB->AsMatrix()); } else { const SparseBFMatrix<float> *psfB = dynamic_cast<const SparseBFMatrix<float> *>(&B); if (psfB) { this->VertConcatBelowMe(psfB->AsMatrix()); } else throw BFMatrixException("FullBFMatrix::HorConcatBelowMe: dynamic cast error"); } } } void FullBFMatrix::VertConcatBelowMe(const NEWMAT::Matrix& B) { if (!B.Ncols()) return; if (int(Ncols()) != B.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcatBelowMe: Matrices must have same # of columns");} *mp &= B; } // Multiply this matrix with scalar void FullBFMatrix::MulMeByScalar(double s) { *mp = s*(*mp); } // Multiply by vector NEWMAT::ReturnMatrix FullBFMatrix::MulByVec(const NEWMAT::ColumnVector& invec) const { if (invec.Nrows() != int(Ncols())) {throw BFMatrixException("FullBFMatrix::MulByVec: Matrix-vector size mismatch");} NEWMAT::ColumnVector ret; ret = (*mp)*invec; ret.Release(); return(ret); } // Add another matrix to this one void FullBFMatrix::AddToMe(const BFMatrix& m, double s) { if (Ncols() != m.Ncols() || Nrows() != m.Nrows()) { throw BFMatrixException("FullBFMatrix::AddToMe: Matrix size mismatch"); } const FullBFMatrix *pm = dynamic_cast<const FullBFMatrix *>(&m); if (pm) { // If m is full matrix *mp += s*(*(pm->mp)); } else { const SparseBFMatrix<double> *psdm = dynamic_cast<const SparseBFMatrix<double> *>(&m); if (psdm) *mp += s*psdm->AsMatrix(); else { const SparseBFMatrix<float> *psfm = dynamic_cast<const SparseBFMatrix<float> *>(&m); if (psfm) *mp += s*psfm->AsMatrix(); else throw BFMatrixException("FullBFMatrix::AddToMe: dynamic cast error"); } } } // Given A*x=b, solve for x NEWMAT::ReturnMatrix FullBFMatrix::SolveForx(const NEWMAT::ColumnVector& b, // Ignoring all parameters except b MISCMATHS::MatrixType type, double tol, int miter) const { if (int(Nrows()) != b.Nrows()) {throw BFMatrixException("FullBFMatrix::SolveForx: Matrix-vector size mismatch");} NEWMAT::ColumnVector ret; ret = mp->i()*b; ret.Release(); return(ret); } } // End namespace MISCMATHS