78 #error Must use C++ for the type matrix.
81 #if !defined(__STD_MATRIX_H)
82 #define __STD_MATRIX_H
84 #define __GXX_WEAK__ 1
85 #define __DEPRECATED 1
87 #define __EXCEPTIONS 1
88 #define __private_extern__ extern
95 #if defined(__BORLANDC__)
96 #pragma option -w-inl -w-pch
99 #if (defined(__BORLANDC__) || _MSC_VER <= 1000 ) && !defined(__GNUG__ )
103 # include <iostream.h>
114 #if defined(_MSC_VER) && _MSC_VER <= 1000
115 # define _NO_EXCEPTION // stdexception is not fully supported in MSVC++ 4.0
125 #if defined(__BORLANDC__) && !defined(__WIN32__)
126 # define _NO_EXCEPTION // std exception and namespace are not fully
127 # define _NO_NAMESPACE // supported in 16-bit compiler
130 #if defined(_MSC_VER) && !defined(_WIN32)
131 # define _NO_EXCEPTION
134 #if defined(_NO_EXCEPTION)
136 # define _THROW_MATRIX_ERROR
138 # if defined(_MSC_VER)
139 # if _MSC_VER >= 1020
140 # include <stdexcept>
142 # include <stdexcpt.h>
144 # elif defined(__MWERKS__)
145 # include <stdexcept>
146 # elif (__GNUC__ >= 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
147 # include <stdexcept>
151 # define _NO_THROW throw ()
152 # define _THROW_MATRIX_ERROR throw (matrix_error)
155 #ifndef __MINMAX_DEFINED
156 # define max(a,b) (((a) > (b)) ? (a) : (b))
157 # define min(a,b) (((a) < (b)) ? (a) : (b))
160 #if defined(_MSC_VER)
161 #undef _MSC_EXTENSIONS // To include overloaded abs function definitions!
164 #if (defined(__BORLANDC__) || _MSC_VER ) && !defined(__GNUG__ )
165 inline float abs (
float v) {
return (
float)fabs(v); }
166 inline double abs (
double v) {
return fabs(v); }
167 inline long double abs (
long double v) {
return fabsl(v); }
170 #if defined(__GNUG__) || defined(__MWERKS__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x540))
171 #define FRIEND_FUN_TEMPLATE <>
173 #define FRIEND_FUN_TEMPLATE
176 #if defined(_MSC_VER) && _MSC_VER <= 1020 // MSVC++ 4.0/4.2 does not
177 # define _NO_NAMESPACE // support "std" namespace
180 #if !defined(_NO_NAMESPACE)
181 #if defined(_SGI_BROKEN_STL ) // For SGI C++ v.7.2.1 compiler
187 #ifndef _NO_NAMESPACE
191 #if !defined(_NO_EXCEPTION)
197 #define REPORT_ERROR(ErrormMsg) throw matrix_error(ErrormMsg);
199 inline void _matrix_error (
const char* pErrMsg)
201 cerr << pErrMsg << endl;
204 #define REPORT_ERROR(ErrormMsg) _matrix_error(ErrormMsg);
207 #if !defined(_NO_TEMPLATE)
208 # define MAT_TEMPLATE template <class T>
209 # define matrixT matrix<T>
211 # define MAT_TEMPLATE
212 # define matrixT matrix
214 typedef MATRIX_TYPE T;
227 matrix (
size_t row = 6,
size_t col = 6);
236 size_t RowNo ()
const {
return _m->Row; }
237 size_t ColNo ()
const {
return _m->Col; }
251 matrixT& operator *= (const T& c) _NO_THROW;
252 matrixT& operator /= (const T& c) _NO_THROW;
253 matrixT& operator ^= (const
size_t& pow) _THROW_MATRIX_ERROR;
256 void Null (const
size_t& row, const
size_t& col) _NO_THROW;
257 void Null () _NO_THROW;
258 void Unit (const
size_t& row) _NO_THROW;
259 void Unit () _NO_THROW;
260 void SetSize (
size_t row,
size_t col) _NO_THROW;
264 matrixT Adj () _THROW_MATRIX_ERROR;
265 matrixT Inv () _THROW_MATRIX_ERROR;
266 T Det () const _THROW_MATRIX_ERROR;
268 T Cofact (
size_t row,
size_t col) _THROW_MATRIX_ERROR;
272 bool IsSquare () _NO_THROW {
return (_m->Row == _m->Col); }
273 bool IsSingular () _NO_THROW;
274 bool IsDiagonal () _NO_THROW;
275 bool IsScalar () _NO_THROW;
276 bool IsUnit () _NO_THROW;
277 bool IsNull () _NO_THROW;
278 bool IsSymmetric () _NO_THROW;
279 bool IsSkewSymmetric () _NO_THROW;
280 bool IsUpperTriangular () _NO_THROW;
281 bool IsLowerTriangular () _NO_THROW;
292 Row = row; RowSiz = row;
293 Col = col; ColSiz = col;
297 size_t rowlen = col *
sizeof(T);
299 for (
size_t i=0; i < row; i++)
301 Val[i] =
new T [col];
302 if (v) memcpy(Val[i], v[i], rowlen);
307 for (
size_t i=0; i < RowSiz; i++)
315 void realloc (
size_t row,
size_t col);
316 int pivot (
size_t row);
319 #if defined(_MSC_VER) && _MSC_VER <= 1020
320 # undef _NO_THROW // MSVC++ 4.0/4.2 does not support
321 # undef _THROW_MATRIX_ERROR // exception specification in definition
323 # define _THROW_MATRIX_ERROR
328 matrixT::matrix (
size_t row,
size_t col)
330 _m =
new base_mat(row, col, 0);
335 matrixT::matrix (
const matrixT& m)
346 _m =
new base_mat(_m->Row, _m->Col, _m->Val);
353 if (--_m->Refcnt == 0)
delete _m;
361 if (--_m->Refcnt == 0)
delete _m;
368 matrixT::realloc (
size_t row,
size_t col)
370 if (row == _m->RowSiz && col == _m->ColSiz)
372 _m->Row = _m->RowSiz;
373 _m->Col = _m->ColSiz;
377 base_mat *m1 =
new base_mat(row, col, NULL);
378 size_t colSize =
min(_m->Col,col) *
sizeof(T);
379 size_t minRow =
min(_m->Row,row);
381 for (
size_t i=0; i < minRow; i++)
382 memcpy(m1->Val[i], _m->Val[i], colSize);
384 if (--_m->Refcnt == 0)
393 matrixT::SetSize (
size_t row,
size_t col)
_NO_THROW
396 size_t oldRow = _m->Row;
397 size_t oldCol = _m->Col;
399 if (row != _m->RowSiz || col != _m->ColSiz)
402 for (i=oldRow; i < row; i++)
403 for (j=0; j < col; j++)
404 _m->Val[i][j] = T(0);
406 for (i=0; i < row; i++)
407 for (j=oldCol; j < col; j++)
408 _m->Val[i][j] = T(0);
417 if (row >= _m->Row || col >= _m->Col)
418 REPORT_ERROR(
"matrixT::operator(): Index out of range!");
419 if (_m->Refcnt > 1) clone();
420 return _m->Val[row][col];
427 if (row >= _m->Row || col >= _m->Col)
428 REPORT_ERROR(
"matrixT::operator(): Index out of range!");
429 return _m->Val[row][col];
436 for (
size_t i=0; i < m.RowNo(); i++)
437 for (
size_t j=0; j < m.ColNo(); j++)
450 for (
size_t i=0; i < m.RowNo(); i++)
452 for (
size_t j=0; j < m.ColNo(); j++)
467 if (m1.RowNo() != m2.RowNo() || m1.ColNo() != m2.ColNo())
470 for (
size_t i=0; i < m1.RowNo(); i++)
471 for (
size_t j=0; j < m1.ColNo(); j++)
472 if (m1(i,j) != m2(i,j))
482 return (m1 == m2) ?
false :
true;
489 if (_m->Row != m._m->Row || _m->Col != m._m->Col)
490 REPORT_ERROR(
"matrixT::operator+= : Inconsistent matrix sizes in addition!");
491 if (_m->Refcnt > 1) clone();
492 for (
size_t i=0; i < m._m->Row; i++)
493 for (
size_t j=0; j < m._m->Col; j++)
494 _m->Val[i][j] += m._m->Val[i][j];
502 if (_m->Row != m._m->Row || _m->Col != m._m->Col)
503 REPORT_ERROR(
"matrixT::operator-= : Inconsistent matrix sizes in subtraction!");
504 if (_m->Refcnt > 1) clone();
505 for (
size_t i=0; i < m._m->Row; i++)
506 for (
size_t j=0; j < m._m->Col; j++)
507 _m->Val[i][j] -= m._m->Val[i][j];
513 matrixT::operator *= (
const T& c)
_NO_THROW
515 if (_m->Refcnt > 1) clone();
516 for (
size_t i=0; i < _m->Row; i++)
517 for (
size_t j=0; j < _m->Col; j++)
526 if (_m->Col != m._m->Row)
527 REPORT_ERROR(
"matrixT::operator*= : Inconsistent matrix sizes in multiplication!");
529 matrixT temp(_m->Row,m._m->Col);
531 for (
size_t i=0; i < _m->Row; i++)
532 for (
size_t j=0; j < m._m->Col; j++)
534 temp._m->Val[i][j] = T(0);
535 for (
size_t k=0; k < _m->Col; k++)
536 temp._m->Val[i][j] += _m->Val[i][k] * m._m->Val[k][j];
545 matrixT::operator /= (
const T& c)
_NO_THROW
547 if (_m->Refcnt > 1) clone();
548 for (
size_t i=0; i < _m->Row; i++)
549 for (
size_t j=0; j < _m->Col; j++)
561 for (
size_t i=2; i <= pow; i++)
562 *
this = *
this * temp;
573 for (
size_t i=0; i < _m->Row; i++)
574 for (
size_t j=0; j < _m->Col; j++)
575 temp._m->Val[i][j] = - _m->Val[i][j];
629 return (m * (T(1) / no));
660 matrixT temp(m.ColNo(),m.RowNo());
662 for (
size_t i=0; i < m.RowNo(); i++)
663 for (
size_t j=0; j < m.ColNo(); j++)
686 if (_m->Row != _m->Col)
687 REPORT_ERROR(
"matrixT::operator!: Inversion of a non-square matrix");
690 if (_m->Refcnt > 1) clone();
694 for (k=0; k < _m->Row; k++)
698 REPORT_ERROR(
"matrixT::operator!: Inversion of a singular matrix");
702 rowptr = temp._m->Val[k];
703 temp._m->Val[k] = temp._m->Val[indx];
704 temp._m->Val[indx] = rowptr;
707 for (j=0; j < _m->Row; j++)
710 temp._m->Val[k][j] /= a1;
712 for (i=0; i < _m->Row; i++)
716 for (j=0; j < _m->Row; j++)
718 _m->Val[i][j] -= a2 * _m->Val[k][j];
719 temp._m->Val[i][j] -= a2 * temp._m->Val[k][j];
733 if ( ! (_m->Row == _m->Col && _m->Col == v._m->Row))
734 REPORT_ERROR(
"matrixT::Solve():Inconsistent matrices!");
736 matrixT temp(_m->Row,_m->Col+v._m->Col);
737 for (i=0; i < _m->Row; i++)
739 for (j=0; j < _m->Col; j++)
740 temp._m->Val[i][j] = _m->Val[i][j];
741 for (k=0; k < v._m->Col; k++)
742 temp._m->Val[i][_m->Col+k] = v._m->Val[i][k];
744 for (k=0; k < _m->Row; k++)
746 int indx = temp.pivot(k);
750 a1 = temp._m->Val[k][k];
751 for (j=k; j < temp._m->Col; j++)
752 temp._m->Val[k][j] /= a1;
754 for (i=k+1; i < _m->Row; i++)
756 a1 = temp._m->Val[i][k];
757 for (j=k; j < temp._m->Col; j++)
758 temp._m->Val[i][j] -= a1 * temp._m->Val[k][j];
761 matrixT s(v._m->Row,v._m->Col);
762 for (k=0; k < v._m->Col; k++)
763 for (
int m=
int(_m->Row)-1; m >= 0; m--)
765 s._m->Val[m][k] = temp._m->Val[m][_m->Col+k];
766 for (j=m+1; j < _m->Col; j++)
767 s._m->Val[m][k] -= temp._m->Val[m][j] * s._m->Val[j][k];
774 matrixT::Null (
const size_t& row,
const size_t& col)
_NO_THROW
776 if (row != _m->Row || col != _m->Col)
782 for (
size_t i=0; i < _m->Row; i++)
783 for (
size_t j=0; j < _m->Col; j++)
784 _m->Val[i][j] = T(0);
792 if (_m->Refcnt > 1) clone();
793 for (
size_t i=0; i < _m->Row; i++)
794 for (
size_t j=0; j < _m->Col; j++)
795 _m->Val[i][j] = T(0);
801 matrixT::Unit (
const size_t& row)
_NO_THROW
803 if (row != _m->Row || row != _m->Col)
809 for (
size_t i=0; i < _m->Row; i++)
810 for (
size_t j=0; j < _m->Col; j++)
811 _m->Val[i][j] = i == j ? T(1) : T(0);
819 if (_m->Refcnt > 1) clone();
820 size_t row =
min(_m->Row,_m->Col);
821 _m->Row = _m->Col = row;
823 for (
size_t i=0; i < _m->Row; i++)
824 for (
size_t j=0; j < _m->Col; j++)
825 _m->Val[i][j] = i == j ? T(1) : T(0);
831 matrixT::pivot (
size_t row)
837 for (
size_t i=row; i < _m->Row; i++)
838 if ((temp = abs(_m->Val[i][row])) > amax && temp != 0.0)
843 if (_m->Val[k][row] == T(0))
847 T* rowptr = _m->Val[k];
848 _m->Val[k] = _m->Val[row];
849 _m->Val[row] = rowptr;
862 if (_m->Row != _m->Col)
863 REPORT_ERROR(
"matrixT::Det(): Determinant a non-square matrix!");
866 if (temp._m->Refcnt > 1) temp.clone();
868 for (k=0; k < _m->Row; k++)
870 int indx = temp.pivot(k);
875 detVal = detVal * temp._m->Val[k][k];
876 for (i=k+1; i < _m->Row; i++)
878 piv = temp._m->Val[i][k] / temp._m->Val[k][k];
879 for (j=k+1; j < _m->Row; j++)
880 temp._m->Val[i][j] -= piv * temp._m->Val[k][j];
892 for (
size_t i=0; i < _m->Row; i++)
893 for (
size_t j=0; j < _m->Col; j++)
894 retVal += _m->Val[i][j] * _m->Val[i][j];
895 retVal = sqrt(retVal);
905 return (Norm() * inv.Norm());
914 if (_m->Row != _m->Col)
915 REPORT_ERROR(
"matrixT::Cofact(): Cofactor of a non-square matrix!");
917 if (row > _m->Row || col > _m->Col)
920 matrixT temp (_m->Row-1,_m->Col-1);
922 for (i=i1=0; i < _m->Row; i++)
926 for (j=j1=0; j < _m->Col; j++)
930 temp._m->Val[i1][j1] = _m->Val[i][j];
936 if ((row+col)%2 == 1)
947 if (_m->Row != _m->Col)
948 REPORT_ERROR(
"matrixT::Adj(): Adjoin of a non-square matrix.");
952 for (
size_t i=0; i < _m->Row; i++)
953 for (
size_t j=0; j < _m->Col; j++)
954 temp._m->Val[j][i] = Cofact(i,j);
962 if (_m->Row != _m->Col)
964 return (Det() == T(0));
971 if (_m->Row != _m->Col)
973 for (
size_t i=0; i < _m->Row; i++)
974 for (
size_t j=0; j < _m->Col; j++)
975 if (i != j && _m->Val[i][j] != T(0))
987 for (
size_t i=1; i < _m->Row; i++)
988 if (_m->Val[i][i] != v)
997 if (IsScalar() && _m->Val[0][0] == T(1))
1006 for (
size_t i=0; i < _m->Row; i++)
1007 for (
size_t j=0; j < _m->Col; j++)
1008 if (_m->Val[i][j] != T(0))
1017 if (_m->Row != _m->Col)
1019 for (
size_t i=0; i < _m->Row; i++)
1020 for (
size_t j=0; j < _m->Col; j++)
1021 if (_m->Val[i][j] != _m->Val[j][i])
1030 if (_m->Row != _m->Col)
1032 for (
size_t i=0; i < _m->Row; i++)
1033 for (
size_t j=0; j < _m->Col; j++)
1034 if (_m->Val[i][j] != -_m->Val[j][i])
1043 if (_m->Row != _m->Col)
1045 for (
size_t i=1; i < _m->Row; i++)
1046 for (
size_t j=0; j < i-1; j++)
1047 if (_m->Val[i][j] != T(0))
1056 if (_m->Row != _m->Col)
1059 for (
size_t j=1; j < _m->Col; j++)
1060 for (
size_t i=0; i < j-1; i++)
1061 if (_m->Val[i][j] != T(0))
1067 #ifndef _NO_NAMESPACE
1071 #endif //__STD_MATRIX_H
MAT_TEMPLATE matrixT operator!(const matrixT m) _THROW_MATRIX_ERROR
MAT_TEMPLATE ostream & operator<<(ostream &ostrm, const matrixT &m)
MAT_TEMPLATE matrixT operator^(const matrixT &m, const size_t &pow) _THROW_MATRIX_ERROR
CPoint operator+(CPoint Q, CPoint R)
#define _THROW_MATRIX_ERROR
MAT_TEMPLATE matrixT operator*(const matrixT &m1, const matrixT &m2) _THROW_MATRIX_ERROR
MAT_TEMPLATE bool operator!=(const matrixT &m1, const matrixT &m2) _NO_THROW
#define REPORT_ERROR(ErrormMsg)
MAT_TEMPLATE matrixT operator/(const matrixT &m1, const matrixT &m2) _THROW_MATRIX_ERROR
MAT_TEMPLATE istream & operator>>(istream &istrm, matrixT &m)
matrix_error(const string &what_arg)
MAT_TEMPLATE matrixT operator~(const matrixT &m) _NO_THROW
MAT_TEMPLATE matrixT operator-(const matrixT &m1, const matrixT &m2) _THROW_MATRIX_ERROR
MAT_TEMPLATE bool operator==(const matrixT &m1, const matrixT &m2) _NO_THROW
base_mat(size_t row, size_t col, T **v)