36 CMatrix(
int iHeight,
int iWidth);
49 const double GetValue(
int i,
int j)
const;
50 void SetValue(
int i,
int j,
double dVal);
73 void DivideRow(
int iRow,
double dDivisor);
75 void SubtractRow(
int iRow1,
int iRow2,
double dScale);
95 void PrintMatrix(
char szMatrixName[], ostream &Output = cout,
int iWidth = 16,
bool bScientific =
true);
146 assert(iHeight*iWidth > 0);
188 assert(i >= 0 && i < m_iHeight && j >= 0 && j <
m_iWidth);
195 assert(i >= 0 && i < m_iHeight && j >= 0 && j <
m_iWidth);
202 assert(i >= 0 && i < m_iHeight && j >= 0 && j <
m_iWidth);
209 assert(i >= 0 && i < m_iHeight && j >= 0 && j <
m_iWidth);
228 Transpose(j, i) = (*this)(i, j);
241 for (j=0; j<RightMatrix.
m_iWidth; ++j)
245 Multiplication(i, j) += (*this)(i, k) * RightMatrix(k, j);
249 return Multiplication;
260 Multiplication(i, j) = (*this)(i, j) * dRight;
263 return Multiplication;
296 assert(&LeftMatrix !=
this);
297 assert(&RightMatrix !=
this);
311 for (k=0; k<LeftMatrix.
m_iWidth; ++k)
313 (*this)(i, j) += LeftMatrix(i, k) * RightMatrix(k, j);
323 assert(&LeftMatrix !=
this);
324 assert(&RightMatrix !=
this);
340 (*this)(i, j) += LeftMatrix(k, i) * RightMatrix(k, j);
350 assert(&LeftMatrix !=
this);
351 assert(&RightMatrix !=
this);
365 for (k=0; k<LeftMatrix.
m_iWidth; ++k)
367 (*this)(i, j) += LeftMatrix(i, k) * RightMatrix(j, k);
381 (*this)(i, j) *= dRight;
395 (*this)(i, j) *= dRight;
413 (*this)(i, j) += RightMatrix(i, j);
431 (*this)(i, j) -= RightMatrix(i, j);
440 Output << szMatrixName << endl;
442 Output << setiosflags(ios_base::scientific);
447 Output << setw(iWidth) << setprecision(iWidth-9) << (*this)(i, j);
452 Output << resetiosflags(ios_base::scientific);
471 GetEigen(EigenVectors, EigenValues);
476 assert(EigenValues(0, i) >= 0);
477 A(i, i) = sqrt(EigenValues(0, i));
495 return (*
this)(0, 0);
498 return (*
this)(0, 0) * (*
this)(1, 1) - (*
this)(1, 0) * (*
this)(0, 1);
503 d1 = (*this)(1, 1) * (*
this)(2, 2) - (*
this)(2, 1) * (*
this)(1, 2);
504 d2 = (*this)(1, 2) * (*
this)(2, 0) - (*
this)(2, 2) * (*
this)(1, 0);
505 d3 = (*this)(1, 0) * (*
this)(2, 1) - (*
this)(2, 0) * (*
this)(1, 1);
506 return (*
this)(0, 0) * d1 + (*
this)(0, 1) * d2 + (*
this)(0, 2) * d3;
539 (*this)(i, j) = (i == j);
558 assert(dDeterminant);
560 dCoef = 1.0/dDeterminant;
562 Inverse(0, 0) = dCoef*(*this)(1, 1);
563 Inverse(1, 1) = dCoef*(*this)(0, 0);
564 Inverse(1, 0) = -dCoef*(*this)(1, 0);
565 Inverse(0, 1) = -dCoef*(*this)(0, 1);
574 assert(dDeterminant);
576 dCoef = 1.0/dDeterminant;
580 static CMatrix SubMatrix(2, 2);
586 SubMatrix(0, 0) = (*this)((i+1)%3, (j+1)%3);
587 SubMatrix(1, 0) = (*this)((i+2)%3, (j+1)%3);
588 SubMatrix(0, 1) = (*this)((i+1)%3, (j+2)%3);
589 SubMatrix(1, 1) = (*this)((i+2)%3, (j+2)%3);
602 vector<double> scale(n);
603 vector<int> index(n);
612 double scalemax = 0.;
614 scalemax = (scalemax > fabs(A(i,j))) ? scalemax : fabs(A(i,j));
620 for( k=0; k<n-1; k++ )
623 double ratiomax = 0.0;
627 double ratio = fabs(A(index[i],k))/scale[index[i]];
628 if( ratio > ratiomax )
635 int indexJ = index[k];
638 indexJ = index[jPivot];
639 index[jPivot] = index[k];
644 for( i=k+1; i<n; i++ )
646 double coeff = A(index[i],k)/A(indexJ,k);
647 for( j=k+1; j<n; j++ )
648 A(index[i],j) -= coeff*A(indexJ,j);
649 A(index[i],k) = coeff;
651 b(index[i],j) -= A(index[i],k)*b(indexJ,j);
655 double determ = signDet;
657 determ *= A(index[i],i);
662 Inverse(n-1,k) = b(index[n-1],k)/A(index[n-1],n-1);
663 for( i=n-2; i>=0; i--)
665 double sum = b(index[i],k);
667 sum -= A(index[i],j)*Inverse(j,k);
668 Inverse(i,k) = sum/A(index[i],i);
689 assert(dDeterminant);
691 dCoef = 1.0/dDeterminant;
719 dTemp = (*this)(iRow1, i);
720 (*this)(iRow1, i) = (*
this)(iRow2, i);
721 (*this)(iRow2, i) = dTemp;
729 assert(iColumn1 >= 0 && iColumn1 <
m_iWidth);
730 assert(iColumn2 >= 0 && iColumn2 <
m_iWidth);
735 dTemp = (*this)(i, iColumn1);
736 (*this)(i, iColumn1) = (*
this)(i, iColumn2);
737 (*this)(i, iColumn2) = dTemp;
749 (*this)(iRow, i) /= dDivisor;
757 assert(iColumn >= 0 && iColumn <
m_iWidth);
761 (*this)(i, iColumn) /= dDivisor;
774 (*this)(iRow1, i) -= (*
this)(iRow2, i) * dScale;
782 assert(iColumn1 >= 0 && iColumn1 <
m_iWidth);
783 assert(iColumn2 >= 0 && iColumn2 <
m_iWidth);
787 (*this)(i, iColumn1) -= (*
this)(i, iColumn2) * dScale;
808 SubMatrix(l, k) = (*this)(j, i);
834 bool bSymetric =
true;
836 for (i=0; i<n && bSymetric; ++i)
838 for (j=i+1; j<n && bSymetric; ++j)
840 if (fabs((*
this)(i, j) - (*
this)(j, i)) > 1e-6)
850 double *e =
new double[n];
854 EigenVectors = (*this);
860 for (j = 0; j < n; j++)
862 EigenValues(0, j) = EigenVectors(n - 1, j);
867 for (i = n - 1; i > 0; i--)
873 for (k = 0; k < i; k++)
875 scale = scale + fabs(EigenValues(0, k));
879 e[i] = EigenValues(0, i - 1);
880 for (j = 0; j < i; j++)
882 EigenValues(0, j) = EigenVectors(i - 1, j);
883 EigenVectors(i, j) = 0.0;
884 EigenVectors(j, i) = 0.0;
891 for (k = 0; k < i; k++)
893 EigenValues(0, k) /= scale;
894 h += EigenValues(0, k) * EigenValues(0, k);
896 double f = EigenValues(0, i - 1);
904 EigenValues(0, i - 1) = f - g;
905 for (j = 0; j < i; j++)
912 for (j = 0; j < i; j++)
914 f = EigenValues(0, j);
915 EigenVectors(j, i) = f;
916 g = e[j] + EigenVectors(j, j) * f;
917 for (k = j + 1; k <= i - 1; k++)
919 g += EigenVectors(k, j) * EigenValues(0, k);
920 e[k] += EigenVectors(k, j) * f;
925 for (j = 0; j < i; j++)
928 f += e[j] * EigenValues(0, j);
930 double hh = f / (h + h);
931 for (j = 0; j < i; j++)
933 e[j] -= hh * EigenValues(0, j);
935 for (j = 0; j < i; j++)
937 f = EigenValues(0, j);
939 for (k = j; k <= i - 1; k++)
941 EigenVectors(k, j) -= (f * e[k] + g * EigenValues(0, k));
943 EigenValues(0, j) = EigenVectors(i - 1, j);
944 EigenVectors(i, j) = 0.0;
947 EigenValues(0, i) = h;
952 for (i = 0; i < n - 1; i++)
954 EigenVectors(n - 1, i) = EigenVectors(i, i);
955 EigenVectors(i, i) = 1.0;
956 double h = EigenValues(0, i + 1);
959 for (k = 0; k <= i; k++)
961 EigenValues(0, k) = EigenVectors(k, i + 1) / h;
963 for (j = 0; j <= i; j++)
966 for (k = 0; k <= i; k++)
968 g += EigenVectors(k, i + 1) * EigenVectors(k, j);
970 for (k = 0; k <= i; k++)
972 EigenVectors(k, j) -= g * EigenValues(0, k);
976 for (k = 0; k <= i; k++)
978 EigenVectors(k, i + 1) = 0.0;
981 for (j = 0; j < n; j++)
983 EigenValues(0, j) = EigenVectors(n - 1, j);
984 EigenVectors(n - 1, j) = 0.0;
986 EigenVectors(n - 1, n - 1) = 1.0;
989 for (i = 1; i < n; i++)
998 for (l = 0; l < n; l++)
1001 if (fabs(EigenValues(0, l)) + fabs(e[l]) > tst1)
1002 tst1 = fabs(EigenValues(0, l)) + fabs(e[l]);
1007 if (fabs(e[m]) <= eps * tst1)
1026 double g = EigenValues(0, l);
1027 double p = (EigenValues(0, l + 1) - g) / (2.0 * e[l]);
1029 double r = sqrt(p*p+1);
1034 EigenValues(0, l) = e[l] / (p + r);
1035 EigenValues(0, l + 1) = e[l] * (p + r);
1036 double dl1 = EigenValues(0, l + 1);
1037 double h = g - EigenValues(0, l);
1038 for (i = l + 2; i < n; i++)
1040 EigenValues(0, i) -= h;
1046 p = EigenValues(0, m);
1050 double el1 = e[l + 1];
1053 for (i = m - 1; i >= l; i--)
1061 r = sqrt(p*p+e[i]*e[i]);
1065 p = c * EigenValues(0, i) - s * g;
1066 EigenValues(0, i + 1) = h + s * (c * g + s * EigenValues(0, i));
1070 for (k = 0; k < n; k++)
1072 h = EigenVectors(k, i + 1);
1073 EigenVectors(k, i + 1) = s * EigenVectors(k, i) + c * h;
1074 EigenVectors(k, i) = c * EigenVectors(k, i) - s * h;
1077 p = (- s) * s2 * c3 * el1 * e[l] / dl1;
1079 EigenValues(0, l) = c * p;
1083 while (fabs(e[l]) > eps * tst1);
1085 EigenValues(0, l) = EigenValues(0, l) + f;
1091 for (i = 0; i < n - 1; i++)
1094 double p = EigenValues(0, i);
1095 for (j = i + 1; j < n; j++)
1097 if (EigenValues(0, j) < p)
1100 p = EigenValues(0, j);
1105 EigenValues(0, k) = EigenValues(0, i);
1106 EigenValues(0, i) = p;
1107 for (j = 0; j < n; j++)
1109 p = EigenVectors(j, i);
1110 EigenVectors(j, i) = EigenVectors(j, k);
1111 EigenVectors(j, k) = p;
1123 for (
int i = 0; i < SubMatrix.
m_iHeight; ++i )
1125 for (
int j = 0; j < SubMatrix.
m_iWidth; ++j )
1127 (*this).SetValue( iRow+i, iColumn+j, SubMatrix.
GetValue( i, j ) );
Class to represent a matrix and perform various operations on it.
void Initialise(int iHeight, int iWidth)
CMatrix & operator=(const CMatrix &RightMatrix)
CMatrix & operator+=(const CMatrix &RightMatrix)
void SubtractRow(int iRow1, int iRow2, double dScale)
CMatrix operator*(const CMatrix &RightMatrix) const
void SetSubMatrix(CMatrix &SubMatrix, int iRow, int iColumn)
CMatrix & EqualsMultipleTranspose(const CMatrix &LeftMatrix, const CMatrix &RightMatrix)
This function multiplies the transpose of the left matrix with the right matrix.
void SwapRows(int iRow1, int iRow2)
double GetInverse(CMatrix &Inverse) const
void DivideColumn(int iColumn, double dDivisor)
void SwapColumns(int iColumn1, int iColumn2)
void PrintMatrix(char szMatrixName[], ostream &Output=cout, int iWidth=16, bool bScientific=true)
CMatrix & GetSubMatrix(CMatrix &SubMatrix, int iRow, int iColumn) const
double & operator()(int i, int j)
double GetDeterminant() const
void SubtractColumn(int iColumn1, int iColumn2, double dScale)
const double GetValue(int i, int j) const
CMatrix operator-(const CMatrix &RightMatrix) const
CMatrix operator+(const CMatrix &RightMatrix) const
void DivideRow(int iRow, double dDivisor)
double GetInverseSlow(CMatrix &Inverse) const
CMatrix & operator*=(double dRight)
CMatrix & EqualsTransposeMultiple(const CMatrix &LeftMatrix, const CMatrix &RightMatrix)
This function multiplies the transpose of the left matrix with the right matrix.
CMatrix & operator-=(const CMatrix &RightMatrix)
void GetSquareRoot(CMatrix &Root) const
void SetValue(int i, int j, double dVal)
void InitialiseIdentity(int iSize)
void GetEigen(CMatrix &EigenVectors, CMatrix &EigenValues) const
CMatrix & EqualsMultiple(const CMatrix &LeftMatrix, const CMatrix &RightMatrix)
This function multiplies the left matrix with the right matrix.
void GetPolarDecomposition(CMatrix &U, CMatrix &P) const
CMatrix & operator/=(double dRight)
Namespace containing a series of customised math operations not found in the standard c++ library.
ostream & operator<<(ostream &output, CMatrix &Matrix)