Newer
Older
Gigg, Martyn Anthony
committed
#include "MantidKernel/Matrix.h"
#include "MantidKernel/V3D.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/MersenneTwister.h"
Gigg, Martyn Anthony
committed
#include <iomanip>
Gigg, Martyn Anthony
committed
using Mantid::Kernel::TimeSeriesProperty;
Gigg, Martyn Anthony
committed
namespace Kernel
Gigg, Martyn Anthony
committed
//
#define fabs(x) std::fabs((x)*1.0)
Gigg, Martyn Anthony
committed
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
namespace
{
//-------------------------------------------------------------------------
// Utility methods and function objects in anonymous namespace
//-------------------------------------------------------------------------
/**
\class PIndex
\author S. Ansell
\date Aug 2005
\version 1.0
\brief Class to fill an index with a progressive count
*/
template<typename T>
struct PIndex
{
private:
int count; ///< counter
public:
/// Constructor
PIndex() : count(0) { }
/// functional
std::pair<T,int> operator()(const T& A) { return std::pair<T,int>(A,count++); }
};
/**
\class PSep
\author S. Ansell
\date Aug 2005
\version 1.0
\brief Class to access the second object in index pair.
*/
template<typename T>
struct PSep
{
/// Functional to the second object
int operator()(const std::pair<T,int>& A) { return A.second; }
};
/**
* Function to take a vector and sort the vector
* so as to produce an index. Leaves the vector unchanged.
* @param pVec :: Input vector
* @param Index :: Output vector
*/
template<typename T>
void
indexSort(const std::vector<T>& pVec,std::vector<int>& Index)
{
Index.resize(pVec.size());
std::vector<typename std::pair<T,int> > PartList;
Gigg, Martyn Anthony
committed
PartList.resize(pVec.size());
transform(pVec.begin(),pVec.end(),PartList.begin(),PIndex<T>());
sort(PartList.begin(),PartList.end());
transform(PartList.begin(),PartList.end(),Index.begin(),PSep<T>());
return;
}
template void indexSort(const std::vector<double>&,std::vector<int>&);
template void indexSort(const std::vector<float>&,std::vector<int>&);
template void indexSort(const std::vector<int>&,std::vector<int>&);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
Alex Buts
committed
template<typename T>
std::vector<T>
Alex Buts
committed
{
Gigg, Martyn Anthony
committed
std::vector<T> rez(nx*ny);
size_t ic(0);
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
rez[ic]=V[i][j];
ic++;
}
}
return rez;
Alex Buts
committed
}
//
Matrix<T>::Matrix(const size_t nrow, const size_t ncol, const bool makeIdentity)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param nrow :: number of rows
@param ncol :: number of columns
Savici, Andrei T.
committed
@param makeIdentity :: flag for the constructor to return an identity matrix
*/
{
// Note:: nx,ny zeroed so setMem always works
setMem(nrow,ncol);
zeroMatrix();
Savici, Andrei T.
committed
if(makeIdentity==true) identityMatrix();
}
template<typename T>
Matrix<T>::Matrix(const std::vector<T>& A,const std::vector<T>& B)
: nx(0),ny(0),V(0)
Janik Zikovsky
committed
/**
Constructor to take two vectors and multiply them to
construct a matrix. (assuming that we have columns x row
vector.
Janik Zikovsky
committed
@param A :: Column vector to multiply
@param B :: Row vector to multiply
*/
{
// Note:: nx,ny zeroed so setMem always works
setMem(A.size(),B.size());
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
//
template<typename T>
Michael Reuter
committed
Matrix<T>::Matrix(const std::vector<T>&data) : nx(0),ny(0),V(0)
Gigg, Martyn Anthony
committed
size_t numel = data.size();
size_t nxt =(size_t)sqrt(double(numel));
size_t test = nxt*nxt;
if(test != numel){
throw(std::invalid_argument("number of elements in input vector have to be square of some value"));
}
setMem(nxt,nxt);
size_t ic(0);
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
V[i][j]=data[ic];
ic++;
}
}
Gigg, Martyn Anthony
committed
template<typename T>
Matrix<T>::Matrix(const Matrix<T>& A,const size_t nrow,const size_t ncol)
: nx(A.nx-1),ny(A.ny-1),V(0)
/**
Constructor with for a missing row/column.
@param A :: The input matrix
@param nrow :: number of row to miss
@param ncol :: number of column to miss
*/
{
// Note:: nx,ny zeroed so setMem always works
Gigg, Martyn Anthony
committed
if (nrow>nx)
Gigg, Martyn Anthony
committed
throw Kernel::Exception::IndexError(nrow,A.nx, "Matrix::Constructor without col");
Gigg, Martyn Anthony
committed
if (ncol>ny)
Gigg, Martyn Anthony
committed
throw Kernel::Exception::IndexError(ncol,A.ny, "Matrix::Constructor without col");
setMem(nx,ny);
size_t iR(0);
for(size_t i=0;i<=nx;i++)
{
if (i!=nrow)
{
size_t jR(0);
for(size_t j=0;j<=ny;j++)
{
if (j!=ncol)
{
V[iR][jR]=A.V[i][j];
jR++;
}
}
Gigg, Martyn Anthony
committed
iR++;
Gigg, Martyn Anthony
committed
}
}
}
template<typename T>
Matrix<T>::Matrix(const Matrix<T>& A)
: nx(0),ny(0),V(0)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param A :: Object to copy
*/
{
// Note:: nx,ny zeroed so setMem always works
setMem(A.nx,A.ny);
if (nx*ny)
Gigg, Martyn Anthony
committed
{
for(size_t i=0;i<nx;i++)
Gigg, Martyn Anthony
committed
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
V[i][j]=A.V[i][j];
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
}
}
template<typename T>
Matrix<T>&
Matrix<T>::operator=(const Matrix<T>& A)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param A :: Object to copy
@return the copied object
*/
{
if (&A!=this)
{
setMem(A.nx,A.ny);
if (nx*ny)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
V[i][j]=A.V[i][j];
}
}
Gigg, Martyn Anthony
committed
}
}
return *this;
}
template<typename T>
Matrix<T>::~Matrix()
Janik Zikovsky
committed
/**
Delete operator :: removes memory for
matrix
*/
{
deleteMem();
}
template<typename T>
Matrix<T>&
Matrix<T>::operator+=(const Matrix<T>& A)
Janik Zikovsky
committed
/**
Matrix addition THIS + A
If the size is different then 0 is added where appropiate
Matrix A is not expanded.
Janik Zikovsky
committed
@param A :: Matrix to add
@return Matrix(this + A)
const size_t Xpt((nx>A.nx) ? A.nx : nx);
const size_t Ypt((ny>A.ny) ? A.ny : ny);
for(size_t i=0;i<Xpt;i++)
{
for(size_t j=0;j<Ypt;j++)
{
}
}
return *this;
}
template<typename T>
Matrix<T>&
Matrix<T>::operator-=(const Matrix<T>& A)
Janik Zikovsky
committed
/**
Matrix subtractoin THIS - A
If the size is different then 0 is added where appropiate
Matrix A is not expanded.
Janik Zikovsky
committed
@param A :: Matrix to add
@return Ma
const size_t Xpt((nx>A.nx) ? A.nx : nx);
const size_t Ypt((ny>A.ny) ? A.ny : ny);
Gigg, Martyn Anthony
committed
for(size_t i=0;i<Xpt;i++)
{
Gigg, Martyn Anthony
committed
for(size_t j=0;j<Ypt;j++)
{
}
}
return *this;
}
template<typename T>
Matrix<T>
Matrix<T>::operator+(const Matrix<T>& A) const
Janik Zikovsky
committed
/**
Matrix addition THIS + A
If the size is different then 0 is added where appropiate
Matrix A is not expanded.
Janik Zikovsky
committed
@param A :: Matrix to add
@return Matrix(this + A)
*/
{
Matrix<T> X(*this);
return X+=A;
}
template<typename T>
Matrix<T>
Matrix<T>::operator-(const Matrix<T>& A) const
Janik Zikovsky
committed
/**
Matrix subtraction THIS - A
If the size is different then 0 is subtracted where
appropiate. This matrix determines the size
Janik Zikovsky
committed
@param A :: Matrix to add
@return Matrix(this + A)
template<typename T>
Matrix<T>
Matrix<T>::operator*(const Matrix<T>& A) const
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param A :: Matrix to multiply by (this->row must == A->columns)
Gigg, Martyn Anthony
committed
@throw MisMatch<size_t> if there is a size mismatch.
Janik Zikovsky
committed
@return Matrix(This * A)
throw Kernel::Exception::MisMatch<size_t>(ny,A.nx,"Matrix::operator*(Matrix)");
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<A.ny;j++)
{
for(size_t kk=0;kk<ny;kk++)
{
Gigg, Martyn Anthony
committed
X.V[i][j]+=V[i][kk]*A.V[kk][j];
}
}
}
return X;
}
template<typename T>
std::vector<T>
Matrix<T>::operator*(const std::vector<T>& Vec) const
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Vec :: size of vector > this->nrows
Gigg, Martyn Anthony
committed
@throw MisMatch<size_t> if there is a size mismatch.
Janik Zikovsky
committed
@return Matrix(This * Vec)
Gigg, Martyn Anthony
committed
if (ny>Vec.size())
Gigg, Martyn Anthony
committed
throw Kernel::Exception::MisMatch<size_t>(ny,Vec.size(),"Matrix::operator*(Vec)");
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
Out[i]=0;
for(size_t j=0;j<ny;j++)
Gigg, Martyn Anthony
committed
Out[i]+=V[i][j]*Vec[j];
Gigg, Martyn Anthony
committed
}
V3D
Matrix<T>::operator*(const V3D& Vx) const
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Vx :: Colunm vector to multiply by
Gigg, Martyn Anthony
committed
@throw MisMatch<size_t> if there is a size mismatch.
Janik Zikovsky
committed
@return Matrix(This * A)
throw Kernel::Exception::MisMatch<size_t>(ny,3,"Matrix::operator*(V3D)");
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t kk=0;kk<ny;kk++)
{
Gigg, Martyn Anthony
committed
}
}
template<typename T>
Matrix<T>
Matrix<T>::operator*(const T& Value) const
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Value :: Scalar to multiply by
@return V * (this)
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
/**
Matrix multiplication THIS *= A
Note that we call operator* to avoid the problem
of changing matrix size.
@param A :: Matrix to multiply by (this->row must == A->columns)
@return This *= A
*/
template<typename T>
Matrix<T>&
Matrix<T>::operator*=(const Matrix<T>& A)
{
if (ny!=A.nx)
Gigg, Martyn Anthony
committed
throw Kernel::Exception::MisMatch<size_t>(ny,A.nx,"Matrix*=(Matrix<T>)");
// This construct to avoid the problem of changing size
*this = this->operator*(A);
return *this;
}
template<typename T>
Matrix<T>&
Matrix<T>::operator*=(const T& Value)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Value :: Scalar to multiply matrix by
@return *this
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
return *this;
}
template<typename T>
Matrix<T>&
Matrix<T>::operator/=(const T& Value)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Value :: Scalar to multiply matrix by
@return *this
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param A :: Matrix to check
@return true :: on succees
@return false :: failure
Gigg, Martyn Anthony
committed
bool Matrix<T>::operator==(const Matrix<T>& A) const
Janik Zikovsky
committed
/**
Element by element comparison within tolerance.
Tolerance means that the value must be > tolerance
and less than (diff/max)>tolerance
Janik Zikovsky
committed
@param A :: matrix to check.
@return true on success
Gigg, Martyn Anthony
committed
return this->equals(A, 1e-8);
}
//---------------------------------------------------------------------------------------
Gigg, Martyn Anthony
committed
template<typename T>
bool Matrix<T>::equals(const Matrix<T>& A, const double Tolerance) const
/**
Element by element comparison within tolerance.
Tolerance means that the value must be > tolerance
and less than (diff/max)>tolerance
Always returns 0 if the Matrix have different sizes
@param A :: matrix to check.
@param Tolerance :: tolerance in comparing elements
@return true on success
*/
{
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
for(size_t j=0;j<ny;j++)
{
const T diff=(V[i][j]-A.V[i][j]);
if (fabs(diff)>maxDiff)
maxDiff=fabs(diff);
if (fabs(V[i][j])>maxS)
maxS=fabs(V[i][j]);
}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
//---------------------------------------------------------------------------------------
/** Element by element comparison of <
Always returns false if the Matrix have different sizes
@param A :: matrix to check.
@return true if this < A
*/
template<typename T>
bool Matrix<T>::operator<(const Matrix<T>& A) const
{
if (&A == this) // this < A == always false
return false;
if(A.nx!=nx || A.ny!=ny)
return false;
for(size_t i=0;i<nx;i++)
for(size_t j=0;j<ny;j++)
{
if (V[i][j] >= A.V[i][j])
return false;
}
return true;
}
//---------------------------------------------------------------------------------------
/** Element by element comparison of >=
Always returns false if the Matrix have different sizes
@param A :: matrix to check.
@return true if this >= A
*/
template<typename T>
bool Matrix<T>::operator>=(const Matrix<T>& A) const
{
if (&A == this)
return true;
if(A.nx!=nx || A.ny!=ny)
return false;
for(size_t i=0;i<nx;i++)
for(size_t j=0;j<ny;j++)
{
if (V[i][j] < A.V[i][j])
return false;
}
return true;
}
//---------------------------------------------------------------------------------------
Janik Zikovsky
committed
/**
Deletes the memory held in matrix
*/
{
if (V)
{
delete [] *V;
delete [] V;
V=0;
}
nx=0;
ny=0;
return;
}
/**
Sets the memory held in matrix
@param a :: number of rows
@param b :: number of columns
*/
Matrix<T>::setMem(const size_t a,const size_t b)
{
if (a==nx && b==ny)
return;
deleteMem();
if (a<=0 || b<=0)
return;
nx=a;
ny=b;
if (nx*ny)
{
T* tmpX=new T[nx*ny];
V=new T*[nx];
Gigg, Martyn Anthony
committed
for (size_t i=0;i<nx;i++)
{
V[i]=tmpX + (i*ny);
Gigg, Martyn Anthony
committed
}
/**
Swap rows I and J
@param RowI :: row I to swap
@param RowJ :: row J to swap
*/
Gigg, Martyn Anthony
committed
Matrix<T>::swapRows(const size_t RowI,const size_t RowJ)
Gigg, Martyn Anthony
committed
if (nx*ny && RowI<nx && RowJ<nx && RowI!=RowJ)
{
for(size_t k=0;k<ny;k++)
Gigg, Martyn Anthony
committed
T tmp=V[RowI][k];
V[RowI][k]=V[RowJ][k];
V[RowJ][k]=tmp;
Gigg, Martyn Anthony
committed
}
/**
Swap columns I and J
@param colI :: col I to swap
@param colJ :: col J to swap
*/
Gigg, Martyn Anthony
committed
Matrix<T>::swapCols(const size_t colI, const size_t colJ)
Gigg, Martyn Anthony
committed
if (nx*ny && colI<ny && colJ<ny && colI!=colJ)
{
for(size_t k=0;k<nx;k++)
Gigg, Martyn Anthony
committed
T tmp=V[k][colI];
V[k][colI]=V[k][colJ];
V[k][colJ]=tmp;
Gigg, Martyn Anthony
committed
}
return;
}
template<typename T>
void
Matrix<T>::zeroMatrix()
Janik Zikovsky
committed
/**
Gigg, Martyn Anthony
committed
{
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
V[i][j]=static_cast<T>(0);
}
}
}
return;
}
template<typename T>
void
Matrix<T>::identityMatrix()
Janik Zikovsky
committed
/**
Makes the matrix an idenity matrix.
Zeros all the terms outside of the square
*/
{
if (nx*ny)
Gigg, Martyn Anthony
committed
{
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
V[i][j]=(T)((j==i) ? 1 : 0);
Gigg, Martyn Anthony
committed
}
}
}
Alex Buts
committed
template<typename T>
void
Matrix<T>::setColumn(const size_t nCol,const std::vector<T> &newCol)
Alex Buts
committed
{
Gigg, Martyn Anthony
committed
if(nCol>=this->ny){
throw(std::invalid_argument("nCol requested> nCol availible"));
}
size_t nxM = newCol.size();
if(nx < nxM) nxM=nx;
for(size_t i=0; i< nxM;i++)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
V[i][nCol]=newCol[i];
}
Alex Buts
committed
}
template<typename T>
void
Matrix<T>::setRow(const size_t nRow,const std::vector<T> &newRow)
Alex Buts
committed
{
Gigg, Martyn Anthony
committed
if(nRow>=this->nx){
throw(std::invalid_argument("nRow requested> nRow availible"));
}
size_t nyM = newRow.size();
if(ny < nyM) nyM=ny;
for(size_t j=0; j < nyM;j++)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
V[nRow][j]=newRow[j];
}
Alex Buts
committed
}
template<typename T>
void
Matrix<T>::rotate(const double tau,const double s,const int i,const int j,
Gigg, Martyn Anthony
committed
const int k,const int m)
Janik Zikovsky
committed
/**
Applies a rotation to a particular point of tan(theta)=tau.
Note that you need both sin(theta) and tan(theta) because of
sign preservation.
Janik Zikovsky
committed
@param tau :: tan(theta)
@param s :: sin(theta)
@param i :: first index (xpos)
@param j :: first index (ypos)
@param k :: second index (xpos)
@param m :: second index (ypos)
*/
{
const T gg=V[i][j];
const T hh=V[k][m];
V[i][j]=static_cast<T>(gg-s*(hh+gg*tau));
V[k][m]=static_cast<T>(hh+s*(gg-hh*tau));
return;
}
template<typename T>
Matrix<T>
Matrix<T>::fDiagonal(const std::vector<T>& Dvec) const
Janik Zikovsky
committed
/**
Calculate the forward diagonal product.
Construct a matrix based on Dvec * This,
where Dvec is made into a diagonal matrix.
Janik Zikovsky
committed
@param Dvec :: diagonal matrix (just centre points)
@return D*this
Gigg, Martyn Anthony
committed
if (Dvec.size()!=nx)
{
std::ostringstream cx;
cx<<"Matrix::fDiagonal Size: "<<Dvec.size()<<" "<<nx<<" "<<ny;
Gigg, Martyn Anthony
committed
for(size_t i=0; i < Dvec.size();i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
return X;
}
template<typename T>
Matrix<T>
Matrix<T>::bDiagonal(const std::vector<T>& Dvec) const
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@param Dvec :: diagonal matrix (just centre points)
@return this*D
Gigg, Martyn Anthony
committed
if (Dvec.size()!=ny)
{
std::ostringstream cx;
cx<<"Error Matrix::bDiaognal size:: "<<Dvec.size()
Gigg, Martyn Anthony
committed
<<" "<<nx<<" "<<ny;
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<Dvec.size();j++)
{
Gigg, Martyn Anthony
committed
}
}
Janik Zikovsky
committed
/**
Transpose the matrix :
Has transpose for a square matrix case.
Janik Zikovsky
committed
@return M^T
*/
{
if (!nx*ny)
return *this;
if (nx==ny) // inplace transpose
{
Matrix<T> MT(*this);
MT.Transpose();
return MT;
}
// irregular matrix
Matrix<T> MT(ny,nx);
Gigg, Martyn Anthony
committed
for(size_t i=0;i<nx;i++)
for(size_t j=0;j<ny;j++)
Alex Buts
committed
Janik Zikovsky
committed
/**
Transpose the matrix :
Has a inplace transpose for a square matrix case.
Janik Zikovsky
committed
@return this^T
*/
{
if (!nx*ny)
return *this;
if (nx==ny) // inplace transpose
Gigg, Martyn Anthony
committed
{
for(size_t i=0;i<nx;i++)
Gigg, Martyn Anthony
committed
for(size_t j=i+1;j<ny;j++)
{
T tmp=V[i][j];
V[i][j]=V[j][i];
V[j][i]=tmp;
}
Gigg, Martyn Anthony
committed
return *this;
}
// irregular matrix
// get some memory
T* tmpX=new T[ny*nx];
T** Vt=new T*[ny];
Gigg, Martyn Anthony
committed
for (size_t i=0;i<ny;i++)
{
Vt[i] = tmpX + (i*nx);
}
for(size_t i=0;i<nx;i++)
{
for(size_t j=0;j<ny;j++)
{
Gigg, Martyn Anthony
committed
}
}
Gigg, Martyn Anthony
committed
const size_t tx=nx;
const size_t ty=ny;
deleteMem(); // resets nx,ny
// replace memory
V=Vt;
nx=ty;
ny=tx;
return *this;
}
template<>
int
Gigg, Martyn Anthony
committed
Matrix<int>::GaussJordan(Kernel::Matrix<int>&)
Janik Zikovsky
committed
/**
Janik Zikovsky
committed
@return zero
*/
{
return 0;
}
template<typename T>
int
Matrix<T>::GaussJordan(Matrix<T>& B)
Janik Zikovsky
committed
/**
Invert this Matrix and solve the
form such that if A.x=B then solve to generate x.
This requires that B is B[A.nx][Any]
The result is placed back in B
Janik Zikovsky
committed
@return the calculation result
*/
{
// check for input errors
if (nx!=ny || B.nx!=nx)
return -1;
// pivoted rows
std::vector<int> pivoted(nx);
fill(pivoted.begin(),pivoted.end(),0);
std::vector<int> indxcol(nx); // Column index
Gigg, Martyn Anthony
committed
size_t irow(0),icol(0);
for(size_t i=0;i<nx;i++)
{
// Get Biggest non-pivoted item
double bigItem=0.0; // get point to pivot over
for(size_t j=0;j<nx;j++)
{
Gigg, Martyn Anthony
committed
if (pivoted[j]!= 1) //check only non-pivots
{
for(size_t k=0;k<nx;k++)
{
if (!pivoted[k])
{
if (fabs(V[j][k]) >=bigItem)
{
bigItem=fabs(V[j][k]);
irow=j;
icol=k;
}
}
Gigg, Martyn Anthony
committed
}
}
Gigg, Martyn Anthony
committed
else if (pivoted[j]>1)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
throw std::runtime_error("Error doing G-J elem on a singular matrix");
Gigg, Martyn Anthony
committed
}
}
pivoted[icol]++;
// Swap in row/col to make a diagonal item
if (irow != icol)