From 5b02f4fbe8586c82b5f12b5a236a5c19e3b9c50a Mon Sep 17 00:00:00 2001
From: Jesper Andersson <jesper@fmrib.ox.ac.uk>
Date: Mon, 4 Jun 2007 14:03:00 +0000
Subject: [PATCH] Implements generic full/sparse matrix for use in nonlin

---
 bfmatrix.cpp | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++
 bfmatrix.h   | 270 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 591 insertions(+)
 create mode 100644 bfmatrix.cpp
 create mode 100644 bfmatrix.h

diff --git a/bfmatrix.cpp b/bfmatrix.cpp
new file mode 100644
index 0000000..480d351
--- /dev/null
+++ b/bfmatrix.cpp
@@ -0,0 +1,321 @@
+//
+// Definitions for class BFMatrix
+//
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include "newmat.h"
+#include "newmatio.h"
+#include "bfmatrix.h"
+
+namespace MISCMATHS {
+
+//
+// Member functions for BFMatrix
+//
+
+void BFMatrix::print(const NEWMAT::Matrix&  m,
+                     const std::string&     fname) const
+{
+  if (!fname.length()) {
+    cout << endl << m << endl;
+  }
+  else {
+    try {
+      ofstream  fout(fname.c_str());
+      fout << setprecision(10) << m;
+    }
+    catch(...) {
+      std::string  errmsg("BFMatrix::print: Failed to write to file " + fname);
+      throw BFMatrixException(errmsg);
+    }
+  }
+}
+
+//
+// Member functions for SparseBFMatrix
+//
+
+//
+// Concatenation of two matrices returning a third
+//
+void SparseBFMatrix::HorConcat(const BFMatrix& B, BFMatrix& AB) const
+{
+  try {
+    const SparseBFMatrix& lB = dynamic_cast<const SparseBFMatrix&>(B);
+    SparseBFMatrix& lAB = dynamic_cast<SparseBFMatrix&>(AB);
+    if (Nrows() != lB.Nrows()) {throw BFMatrixException("SparseBFMatrix::HorConcat: Matrices must have same # of rows");}
+    *(lAB.mp) = *mp | *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::HorConcat: dynamic cast error"); 
+  }
+}
+
+void SparseBFMatrix::HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const
+{
+  try {
+    SparseBFMatrix& lAB = dynamic_cast<SparseBFMatrix&>(AB);
+    if (int(Nrows()) != B.Nrows()) {throw BFMatrixException("SparseBFMatrix::HorConcat: Matrices must have same # of rows");}
+    *(lAB.mp) = *mp | B;
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::HorConcat: dynamic cast error"); 
+  }
+}
+
+void SparseBFMatrix::VertConcat(const BFMatrix& B, BFMatrix& AB) const
+{
+  try {
+    const SparseBFMatrix& lB = dynamic_cast<const SparseBFMatrix&>(B);
+    SparseBFMatrix& lAB = dynamic_cast<SparseBFMatrix&>(AB);
+    if (Ncols() != lB.Ncols()) {throw BFMatrixException("SparseBFMatrix::VertConcat: Matrices must have same # of columns");}
+    *(lAB.mp) = *mp & *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+void SparseBFMatrix::VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const
+{
+  try {
+    SparseBFMatrix& lAB = dynamic_cast<SparseBFMatrix&>(AB);
+    if (int(Ncols()) != B.Ncols()) {throw BFMatrixException("SparseBFMatrix::VertConcat: Matrices must have same # of columns");}
+    *(lAB.mp) = *mp & B;
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+//
+// Concatenate another matrix to *this
+//
+void SparseBFMatrix::HorConcat2MyRight(const BFMatrix& B)
+{
+  try {
+    const SparseBFMatrix& lB = dynamic_cast<const SparseBFMatrix&>(B);
+    if (Nrows() != lB.Nrows()) {throw BFMatrixException("SparseBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");}
+    *mp |= *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+void SparseBFMatrix::HorConcat2MyRight(const NEWMAT::Matrix& B)
+{
+  if (int(Nrows()) != B.Nrows()) {throw BFMatrixException("SparseBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");}
+  *mp |= B;
+}
+
+void SparseBFMatrix::VertConcatBelowMe(const BFMatrix& B)
+{
+  try {
+    const SparseBFMatrix& lB = dynamic_cast<const SparseBFMatrix&>(B);
+    if (Ncols() != lB.Ncols()) {throw BFMatrixException("SparseBFMatrix::VertConcatBelowMe: Matrices must have same # of columns");}
+    *mp &= *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+void SparseBFMatrix::VertConcatBelowMe(const NEWMAT::Matrix& B)
+{
+  if (int(Ncols()) != B.Ncols()) {throw BFMatrixException("SparseBFMatrix::VertConcatBelowMe: Matrices must have same # of columns");}
+  *mp &= B;
+}
+
+// Multiply by vector
+NEWMAT::ReturnMatrix SparseBFMatrix::MulByVec(const NEWMAT::ColumnVector& invec) const
+{
+  if (invec.Nrows() != int(Ncols())) {throw BFMatrixException("Matrix-vector size mismatch");}
+  NEWMAT::ColumnVector   outvec = *mp * invec;
+  outvec.Release();
+  return(outvec);
+}
+
+// Add another matrix to this one
+void SparseBFMatrix::AddToMe(const BFMatrix& M, double s)
+{
+  try {
+    const SparseBFMatrix& lM = dynamic_cast<const SparseBFMatrix&>(M);
+    if (Ncols() != lM.Ncols() || Nrows() != lM.Nrows()) {
+      throw BFMatrixException("SparseBFMatrix::AddToMe: Matrix size mismatch");
+    }
+    if (s == 1.0) *mp += *(lM.mp);
+    else *mp += s * *(lM.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("SparseBFMatrix::AddToMe: dynamic cast error"); 
+  }
+}
+
+// Given A*x=b, solve for x
+NEWMAT::ReturnMatrix SparseBFMatrix::SolveForx(const NEWMAT::ColumnVector& b,
+					       MISCMATHS::MatrixType       type,
+					       double                      tol,
+                                               int                         miter) const
+{
+  if (b.Nrows() != int(Nrows())) {
+    throw BFMatrixException("SparseBFMatrix::SolveForx: Matrix-vector size mismatch");
+  }
+  NEWMAT::ColumnVector  x = mp->SolveForx(b,type,tol,miter);
+  x.Release();
+  return(x);
+}
+
+//
+// Member functions for FullBFMatrix
+//
+
+boost::shared_ptr<BFMatrix> FullBFMatrix::Transpose(boost::shared_ptr<BFMatrix>& pA) const
+{
+  boost::shared_ptr<FullBFMatrix>  tmp(new FullBFMatrix);
+  *(tmp->mp) = mp->t();
+  return(tmp);
+}
+
+//
+// Concatenate two matrices yielding a third
+//
+
+void FullBFMatrix::HorConcat(const BFMatrix& B, BFMatrix& AB) const
+{
+  try {
+    const FullBFMatrix& lB = dynamic_cast<const FullBFMatrix&>(B);
+    FullBFMatrix& lAB = dynamic_cast<FullBFMatrix&>(AB);
+    if (Nrows() != lB.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat: Matrices must have same # of rows");}
+    *(lAB.mp) = *mp | *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::HorConcat: dynamic cast error"); 
+  }
+}
+
+void FullBFMatrix::HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const
+{
+  try {
+    FullBFMatrix& lAB = dynamic_cast<FullBFMatrix&>(AB);
+    if (int(Nrows()) != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat: Matrices must have same # of rows");}
+    *(lAB.mp) = *mp | B;
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::HorConcat: dynamic cast error"); 
+  }
+}
+
+void FullBFMatrix::VertConcat(const BFMatrix& B, BFMatrix& AB) const
+{
+  try {
+    const FullBFMatrix& lB = dynamic_cast<const FullBFMatrix&>(B);
+    FullBFMatrix& lAB = dynamic_cast<FullBFMatrix&>(AB);
+    if (Ncols() != lB.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcat: Matrices must have same # of columns");}
+    *(lAB.mp) = *mp & *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+void FullBFMatrix::VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const
+{
+  try {
+    FullBFMatrix& lAB = dynamic_cast<FullBFMatrix&>(AB);
+    if (int(Ncols()) != B.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcat: Matrices must have same # of columns");}
+    *(lAB.mp) = *mp & B;
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::VertConcat: dynamic cast error"); 
+  }
+}
+
+//  
+// Concatenation of another matrix to *this
+//
+void FullBFMatrix::HorConcat2MyRight(const BFMatrix& B)
+{
+  try {
+    const FullBFMatrix& lB = dynamic_cast<const FullBFMatrix&>(B);
+    if (Nrows() != lB.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");}
+    *mp |= *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: dynamic cast error"); 
+  }
+}
+
+void FullBFMatrix::HorConcat2MyRight(const NEWMAT::Matrix& B)
+{
+  if (int(Nrows()) != B.Nrows()) {throw BFMatrixException("FullBFMatrix::HorConcat2MyRight: Matrices must have same # of rows");}
+  *mp |= B;
+}
+
+void FullBFMatrix::VertConcatBelowMe(const BFMatrix& B)
+{
+  try {
+    const FullBFMatrix& lB = dynamic_cast<const FullBFMatrix&>(B);
+    if (Ncols() != lB.Ncols()) {throw BFMatrixException("FullBFMatrix::VertConcatBelowMe: Matrices must have same # of columns");}
+    *mp &= *(lB.mp);
+  }
+  catch (std::bad_cast) {
+    throw BFMatrixException("FullBFMatrix::HorConcatBelowMe: dynamic cast error"); 
+  }
+}
+
+void FullBFMatrix::VertConcatBelowMe(const NEWMAT::Matrix& B)
+{
+  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)
+{
+  try {
+    const FullBFMatrix& lm = dynamic_cast<const FullBFMatrix&>(m);
+    if (Ncols() != lm.Ncols() || Nrows() != lm.Nrows()) {
+      throw BFMatrixException("FullBFMatrix::AddToMe: Matrix size mismatch");
+    }
+    *mp += s*(*lm.mp);
+  }
+  catch (std::bad_cast) {
+    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
diff --git a/bfmatrix.h b/bfmatrix.h
new file mode 100644
index 0000000..87fe792
--- /dev/null
+++ b/bfmatrix.h
@@ -0,0 +1,270 @@
+// Declarations for class BFMatrix.
+//
+// The purpose of class BFmatrix is to have a class from which
+// to derive 2 other classes; FullBFMatrix and SparseBFMatrix.
+// The reason for this is that the two classes SplineField and
+// DCTField will return Hessian matrices that are either Sparse
+// (SplineField) or full (DCTField). By defining a pure virtual
+// class BFMatrix with a minimal (only what is needed for non-
+// linear reg.) functionality I will be able to write code that
+// is independent of type of matrix returned, and hence of type
+// field.
+//
+// The syntax for the (little) functionality is sort of a mixture
+// of Newmat and SparseMatrix. Mostly SparseMatrix actually.
+// I hope this will not complicate the use of the nonlin package
+// for those who are only interested in the full (normal) case.
+//
+// At one point SparseMatrix was replaced by SpMat as the underlying
+// sparse matrix representation in SparseBFMatrix. SpMat was written
+// with an API that largely mimicks that of NEWMAT. This is the 
+// "historical" reason why a wrapper class was written, rather than
+// using templatisation which would have been possible given the
+// similarities in API between SpMat and NEWMAT.
+//
+
+#ifndef BFMatrix_h
+#define BFMatrix_h
+
+#include <boost/shared_ptr.hpp>
+#include "newmat.h"
+#include "SpMat.h"
+#include "cg.h"
+#include "bicg.h"
+
+namespace MISCMATHS {
+
+
+class BFMatrixException: public std::exception
+{
+private:
+  std::string m_msg;
+public:
+  BFMatrixException(const std::string& msg) throw(): m_msg(msg) {}
+
+  virtual const char * what() const throw() {
+    return string("BFMatrix::" + m_msg).c_str();
+  }
+
+  ~BFMatrixException() throw() {}
+};
+
+class BFMatrix
+{
+protected:
+virtual void print(const NEWMAT::Matrix& m, const std::string& fname) const;
+public:
+  // Constructors, destructors and stuff
+  BFMatrix() {}
+  BFMatrix(unsigned int m, unsigned int n) {}
+  virtual ~BFMatrix() {}
+
+  // Access as NEWMAT::Matrix
+  virtual NEWMAT::ReturnMatrix AsMatrix() const = 0;
+  
+  // Basic properties
+  virtual unsigned int Nrows() const = 0;
+  virtual unsigned int Ncols() const = 0;
+
+  // Print matrix (for debugging)
+  virtual void Print(const std::string fname=std::string("")) const = 0;
+
+  // Setting, deleting or resizing the whole sparse matrix.
+  virtual void SetMatrix(const MISCMATHS::SpMat<double>& M) = 0;
+  virtual void SetMatrix(const NEWMAT::Matrix& M) = 0;
+  virtual void Clear() = 0;
+  virtual void Resize(unsigned int m, unsigned int n) = 0;
+
+  // Accessing
+  inline double operator()(unsigned int r, unsigned int c) const {return(Peek(r,c));}
+  virtual double Peek(unsigned int r, unsigned int c) const = 0;
+
+  // Assigning
+  virtual void Set(unsigned int x, unsigned int y, double val) = 0;
+  virtual void Insert(unsigned int x, unsigned int y, double val) = 0;
+  virtual void AddTo(unsigned int x, unsigned int y, double val) = 0;  
+
+  // Transpose
+  virtual boost::shared_ptr<BFMatrix> Transpose(boost::shared_ptr<BFMatrix>& pA) const = 0;
+
+  // Concatenation. Note that desired polymorphism prevents us from using BFMatrix->NEWMAT::Matrix conversion
+  // Concatenate two matrices yielding a third
+  // AB = [*this B] in Matlab lingo
+  virtual void HorConcat(const BFMatrix& B, BFMatrix& AB) const = 0;
+  virtual void HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const = 0;
+  // AB = [*this; B] in Matlab lingo
+  virtual void VertConcat(const BFMatrix& B, BFMatrix& AB) const = 0;
+  virtual void VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const = 0;
+  // Concatenate another matrix to *this
+  virtual void HorConcat2MyRight(const BFMatrix& B) = 0;
+  virtual void HorConcat2MyRight(const NEWMAT::Matrix& B) = 0;
+  virtual void VertConcatBelowMe(const BFMatrix& B) = 0;
+  virtual void VertConcatBelowMe(const NEWMAT::Matrix& B) = 0;
+
+  // Multiply by scalar
+  virtual void MulMeByScalar(double s) = 0;
+  // Multiply by vector
+  virtual NEWMAT::ReturnMatrix MulByVec(const NEWMAT::ColumnVector& v) const = 0;
+  // Add another matrix to this one 
+  virtual void AddToMe(const BFMatrix& m, double s=1.0) = 0;
+  // Given A*x=b, solve for x.
+  virtual NEWMAT::ReturnMatrix SolveForx(const NEWMAT::ColumnVector& b,
+					 MISCMATHS::MatrixType       type=SYM_POSDEF,
+					 double                      tol=1e-6,
+                                         int                         miter=200) const = 0;  
+};
+
+class SparseBFMatrix : public BFMatrix
+{
+private:
+  boost::shared_ptr<MISCMATHS::SpMat<double> >    mp;
+  
+public:
+  // Constructors, destructor and assignment
+  SparseBFMatrix() 
+  : mp(boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>())) {}
+  SparseBFMatrix(unsigned int m, unsigned int n) 
+  : mp(boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(m,n))) {}
+  SparseBFMatrix(unsigned int m, unsigned int n, const unsigned int *irp, const unsigned int *jcp, const double *sp)
+  : mp(boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(m,n,irp,jcp,sp))) {}
+  SparseBFMatrix(const MISCMATHS::SpMat<double>& M) 
+  : mp(boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(M))) {}
+  SparseBFMatrix(const NEWMAT::Matrix& M) 
+  : mp(boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(M))) {}
+  virtual ~SparseBFMatrix() {}
+  virtual const SparseBFMatrix& operator=(const SparseBFMatrix& M) {
+    mp = boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(*(M.mp))); return(*this);
+  }
+
+  // Access as NEWMAT::Matrix
+  virtual NEWMAT::ReturnMatrix AsMatrix() const {NEWMAT::Matrix ret; ret = mp->AsNEWMAT(); ret.Release(); return(ret);}
+  
+  // Basic properties
+  virtual unsigned int Nrows() const {return(mp->Nrows());}
+  virtual unsigned int Ncols() const {return(mp->Ncols());}
+
+  // Print matrix (for debugging)
+  virtual void Print(const std::string fname=std::string("")) const {print(mp->AsNEWMAT(),fname);}
+
+  // Setting, deleting or resizing the whole sparse matrix.
+  virtual void SetMatrix(const MISCMATHS::SpMat<double>& M) {mp = boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(M));}
+  virtual void SetMatrix(const NEWMAT::Matrix& M) {mp = boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(M));}
+  virtual void SetMatrixPtr(boost::shared_ptr<MISCMATHS::SpMat<double> >& mptr) {mp = mptr;}
+  virtual void Clear() {mp = boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>());}
+  virtual void Resize(unsigned int m, unsigned int n) {mp = boost::shared_ptr<MISCMATHS::SpMat<double> >(new MISCMATHS::SpMat<double>(m,n));}
+
+  // Accessing values
+  virtual double Peek(unsigned int r, unsigned int c) const {return(mp->Peek(r,c));}
+
+  // Setting and inserting values
+  virtual void Set(unsigned int x, unsigned int y, double val) {mp->Set(x,y,val);}
+  virtual void Insert(unsigned int x, unsigned int y, double val) {mp->Set(x,y,val);}
+  virtual void AddTo(unsigned int x, unsigned int y, double val) {mp->AddTo(x,y,val);}
+
+  // Transpose. 
+  virtual boost::shared_ptr<BFMatrix> Transpose(boost::shared_ptr<BFMatrix>& pA) const {throw BFMatrixException("SparseBFMatrix::Transpose: Not yet implemented");}
+  
+  // Concatenation of two matrices returning a third
+  // AB = [*this B] in Matlab lingo
+  virtual void HorConcat(const BFMatrix& B, BFMatrix& AB) const;
+  virtual void HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const;
+  // AB = [*this; B] in Matlab lingo
+  virtual void VertConcat(const BFMatrix& B, BFMatrix& AB) const;
+  virtual void VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const;
+
+  // Concatenation of another matrix to *this
+  virtual void HorConcat2MyRight(const BFMatrix& B);
+  virtual void HorConcat2MyRight(const NEWMAT::Matrix& B);
+  virtual void VertConcatBelowMe(const BFMatrix& B);
+  virtual void VertConcatBelowMe(const NEWMAT::Matrix& B);
+
+  // Multiply by scalar
+  virtual void MulMeByScalar(double s) {(*mp)*=s;}
+
+  // Multiply by vector
+  virtual NEWMAT::ReturnMatrix MulByVec(const NEWMAT::ColumnVector& invec) const;
+
+  // Add another matrix to this one
+  virtual void AddToMe(const BFMatrix& m, double s=1.0);
+
+  // Given A*x=b, solve for x
+  virtual NEWMAT::ReturnMatrix SolveForx(const NEWMAT::ColumnVector& b,
+					 MISCMATHS::MatrixType       type,
+					 double                      tol,
+                                         int                         miter) const;
+};
+
+class FullBFMatrix : public BFMatrix
+{
+private:
+  boost::shared_ptr<NEWMAT::Matrix>    mp;
+public:
+  // Constructors, destructor and assignment
+  FullBFMatrix() {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix());}
+  FullBFMatrix(unsigned int m, unsigned int n) {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(m,n));}
+  FullBFMatrix(const MISCMATHS::SpMat<double>& M) {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(M.AsNEWMAT()));}
+  FullBFMatrix(const NEWMAT::Matrix& M) {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(M));}
+  virtual ~FullBFMatrix() {}
+  virtual const FullBFMatrix& operator=(const FullBFMatrix& M) {
+    mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(*(M.mp))); return(*this);
+  }
+
+  virtual NEWMAT::ReturnMatrix AsMatrix() const {NEWMAT::Matrix ret; ret = *mp; ret.Release(); return(ret);}
+
+  // Basic properties
+  virtual unsigned int Nrows() const {return(mp->Nrows());}
+  virtual unsigned int Ncols() const {return(mp->Ncols());}
+
+  // Print matrix (for debugging)
+  virtual void Print(const std::string fname=std::string("")) const {print(*mp,fname);}
+
+  // Setting, deleting or resizing the whole matrix.
+  virtual void SetMatrix(const MISCMATHS::SpMat<double>& M) {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(M.AsNEWMAT()));} 
+  virtual void SetMatrix(const NEWMAT::Matrix& M) {mp = boost::shared_ptr<NEWMAT::Matrix>(new NEWMAT::Matrix(M));}
+  virtual void SetMatrixPtr(boost::shared_ptr<NEWMAT::Matrix>& mptr) {mp = mptr;}
+  virtual void Clear() {mp->ReSize(0,0);}
+  virtual void Resize(unsigned int m, unsigned int n) {mp->ReSize(m,n);}
+
+  // Accessing values
+  virtual double Peek(unsigned int r, unsigned int c) const {return((*mp)(r,c));}
+
+  // Setting and inserting values.
+  virtual void Set(unsigned int x, unsigned int y, double val) {(*mp)(x,y)=val;}
+  virtual void Insert(unsigned int x, unsigned int y, double val) {(*mp)(x,y)=val;}
+  virtual void AddTo(unsigned int x, unsigned int y, double val) {(*mp)(x,y)+=val;}
+
+  // Transpose. 
+  virtual boost::shared_ptr<BFMatrix> Transpose(boost::shared_ptr<BFMatrix>& pA) const;
+  
+  // Concatenation of two matrices returning a third
+  virtual void HorConcat(const BFMatrix& B, BFMatrix& AB) const;
+  virtual void HorConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const;
+  virtual void VertConcat(const BFMatrix& B, BFMatrix& AB) const;
+  virtual void VertConcat(const NEWMAT::Matrix& B, BFMatrix& AB) const;
+
+  // Concatenation of another matrix to *this
+  virtual void HorConcat2MyRight(const BFMatrix& B);
+  virtual void HorConcat2MyRight(const NEWMAT::Matrix& B);
+  virtual void VertConcatBelowMe(const BFMatrix& B);
+  virtual void VertConcatBelowMe(const NEWMAT::Matrix& B);
+
+  // Multiply by scalar
+  virtual void MulMeByScalar(double s);
+
+  // Multiply by vector
+  virtual NEWMAT::ReturnMatrix MulByVec(const NEWMAT::ColumnVector& invec) const;
+
+  // Add another matrix to this one
+  virtual void AddToMe(const BFMatrix& m, double s);
+
+  // Given A*x=b, solve for x
+  virtual NEWMAT::ReturnMatrix SolveForx(const NEWMAT::ColumnVector& b,
+					 MISCMATHS::MatrixType       type,
+					 double                      tol,
+                                         int                         miter) const;
+    
+};
+
+} // End namespace MISCMATHS
+
+#endif // End #ifndef BFMatrix_h
-- 
GitLab