Skip to content
Snippets Groups Projects
MatrixTest.h 2.72 KiB
Newer Older
Nick Draper's avatar
Nick Draper committed
#ifndef MANTID_TESTMATIX__
#define MANTID_TESTMATIX__
Stuart Ansell's avatar
Stuart Ansell committed

#include <cxxtest/TestSuite.h>
#include <cmath>
#include <ostream>
#include <vector>
Nick Draper's avatar
Nick Draper committed
#include <algorithm>
Stuart Ansell's avatar
Stuart Ansell committed

Nick Draper's avatar
Nick Draper committed
#include "MantidGeometry/Math/Matrix.h" 
Stuart Ansell's avatar
Stuart Ansell committed

using namespace Mantid;
using namespace Geometry;

class testMatrix: public CxxTest::TestSuite
{

public:

  void makeMatrix(Matrix<double>& A) const
Nick Draper's avatar
Nick Draper committed
  {
    A.setMem(3,3);
    A[0][0]=1.0;
Stuart Ansell's avatar
Stuart Ansell committed
    A[1][0]=3.0; 
Nick Draper's avatar
Nick Draper committed
    A[0][1]=4.0;
    A[0][2]=6.0;
    A[2][0]=5.0;
    A[1][1]=3.0;
    A[2][1]=1.0;
    A[1][2]=6.0;
    A[2][2]=-7.0;
    return;
  }
Stuart Ansell's avatar
Stuart Ansell committed

  /*!
Nick Draper's avatar
Nick Draper committed
  Test that a matrix can be inverted
Stuart Ansell's avatar
Stuart Ansell committed
  */
  void testInvert()
Nick Draper's avatar
Nick Draper committed
  {
    Matrix<double> A(3,3);

    A[0][0]=1.0;
    A[1][0]=3.0;
    A[0][1]=4.0;
    A[0][2]=6.0;
    A[2][0]=5.0;
    A[1][1]=3.0;
    A[2][1]=1.0;
    A[1][2]=6.0;
    A[2][2]=-7.0;

Nick Draper's avatar
Nick Draper committed
    TS_ASSERT_DELTA(A.Invert(),105.0,1e-5);
  }

  void testIdent()
  {
    Matrix<double> A(3,3);

    A[0][0]=1.0;
    A[1][0]=0.0;
    A[0][1]=0.0;
    A[0][2]=0.0;
    A[2][0]=0.0;
    A[1][1]=1.0;
    A[2][1]=0.0;
    A[1][2]=0.0;
    A[2][2]=1.0;

Nick Draper's avatar
Nick Draper committed
    Matrix<double> Ident(3,3);
Nick Draper's avatar
Nick Draper committed
    TS_ASSERT_DIFFERS(Ident,A);
Nick Draper's avatar
Nick Draper committed
    Ident.identityMatrix();
Nick Draper's avatar
Nick Draper committed
    TS_ASSERT_EQUALS(Ident,A);
Nick Draper's avatar
Nick Draper committed
  }
Stuart Ansell's avatar
Stuart Ansell committed

  /*!
Nick Draper's avatar
Nick Draper committed
  Check that we can swap rows and columns
Stuart Ansell's avatar
Stuart Ansell committed
  */
  void testSwapRows()
Nick Draper's avatar
Nick Draper committed
  {
    Matrix<double> A(3,3);
    makeMatrix(A);
    Matrix<double> B(A);
    A.swapRows(1,2);
    A.swapCols(1,2);
    TS_ASSERT_EQUALS(A[0][0],B[0][0]);
    TS_ASSERT_EQUALS(A[2][2],B[1][1]);
    // Plus all the others..
  }
Stuart Ansell's avatar
Stuart Ansell committed

  void testEigenvectors()
Nick Draper's avatar
Nick Draper committed
  {
    Matrix<double> Eval;
    Matrix<double> Diag;
    Matrix<double> A(3,3);  // NOTE: A must be symmetric
    A[0][0]=1.0;
    A[1][0]=A[0][1]=4.0;
    A[0][2]=A[2][0]=5.0;
    A[1][1]=3.0;
    A[2][1]=A[1][2]=6.0;
    A[2][2]=-7.0;
    TS_ASSERT(A.Diagonalise(Eval,Diag));

    Matrix<double> MA=A*Eval;
    Matrix<double> MV=Eval*Diag;
    Eval.sortEigen(Diag);
    TS_ASSERT(Diag[0][0]<Diag[1][1]);
    TS_ASSERT(Diag[1][1]<Diag[2][2]);
    TS_ASSERT(MA==MV);

    std::vector<double> X(3);
    X[0]=Eval[0][1];
    X[1]=Eval[1][1];
    X[2]=Eval[2][1];

    std::vector<double> out=A*X;
    transform(X.begin(),X.end(),X.begin(),std::bind2nd(std::multiplies<double>(),Diag[1][1]));
    TS_ASSERT_DELTA(X[0],out[0],0.0001);
    TS_ASSERT_DELTA(X[1],out[1],0.0001);
    TS_ASSERT_DELTA(X[2],out[2],0.0001);

  }

Stuart Ansell's avatar
Stuart Ansell committed
  /*!
Nick Draper's avatar
Nick Draper committed
  Tests the diagonalisation  on a symmetric 2x2 matrix
Stuart Ansell's avatar
Stuart Ansell committed
  */
  void testDiagonalise()
Nick Draper's avatar
Nick Draper committed
  {
    Matrix<double> Eval;
    Matrix<double> Diag;
    Matrix<double> A(2,2);   // symmetric only
    A[0][0]=1.0;
    A[1][0]=3.0;
    A[0][1]=3.0;
    A[1][1]=4.0;
    TS_ASSERT(A.Diagonalise(Eval,Diag));  // returns 1 or 2

    Matrix<double> EvalT(Eval);
    EvalT.Transpose();
    Eval*=Diag;
    Eval*=EvalT;
    TS_ASSERT(Eval==A);
  }

Stuart Ansell's avatar
Stuart Ansell committed
};

#endif