00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00262 #ifndef mat_INCLUDED
00263 #define mat_INCLUDED "mat.h"
00264
00265 #ifdef _KEEP_RCS_ID
00266 static char *mat_rcs_id = mat_INCLUDED "$Revision: 1.5 $";
00267 #endif
00268
00269
00270
00271 #ifndef __STRING_H__
00272 extern "C" {
00273 #include "string.h"
00274 }
00275 #endif
00276
00277
00278
00279 #ifndef defs_INCLUDED
00280 #include "defs.h"
00281 #endif
00282
00283
00284
00285 #ifndef CXX_MEMORY_INCLUDED
00286 #include "cxx_memory.h"
00287 #endif
00288 #ifndef ERRORS_INCLUDED
00289 #include "errors.h"
00290 #endif
00291 #ifndef frac_INCLUDED
00292 #include "frac.h"
00293 #endif
00294
00295
00296
00297
00298 template<class T>
00299 class MAT {
00300 public:
00301
00302 MAT(MEM_POOL* mp =0) :
00303 _r(0), _c(0), _rx(0), _cx(0),
00304 _pool(mp ? mp : _default_pool),
00305 _data(0) {}
00306 MAT(INT r, INT c, MEM_POOL* mp =0);
00307 MAT(const MAT<T>& a, MEM_POOL* mp =0);
00308 ~MAT() {if (_data) CXX_DELETE_ARRAY(_data, _pool);}
00309
00310 MAT<T>& operator =(const MAT<T>&);
00311
00312 INT Rows() const {return _r;}
00313 INT Cols() const {return _c;}
00314
00315 const T& operator ()(INT r, INT c) const {
00316 Is_True(r < _r && c < _c, ("Bad ref(%d,%d), size(%d,%d)", r, c, _r, _c));
00317 return _data[r*_cx + c];
00318 }
00319
00320 T& operator ()(INT r, INT c) {
00321 Is_True(r < _r && c < _c, ("Bad ref(%d,%d), size(%d,%d)", r, c, _r, _c));
00322 return _data[r*_cx + c];
00323 }
00324
00325 MAT<T> operator +(const MAT<T>&) const;
00326 MAT<T>& operator +=(const MAT<T>&);
00327 MAT<T> operator -(const MAT<T>&) const;
00328 MAT<T>& operator -=(const MAT<T>&);
00329 MAT<T> operator *(MAT<T> const&) const;
00330 MAT<T>& operator *=(MAT<T> const&);
00331
00332 friend MAT<T> operator *(T a, MAT<T> const& m) {return m * a;}
00333 MAT<T> operator *(T) const;
00334 MAT<T>& operator *=(T);
00335
00336 MAT<T> Trans() const;
00337 MAT<T> Inv() const;
00338 MAT<T> L() const;
00339 MAT<T> U() const;
00340
00341 MAT<T>& D_Zero();
00342 MAT<T>& D_Identity();
00343 MAT<T>& D_Trans();
00344 MAT<T>& D_Inv();
00345 MAT<T>& D_Swap_Rows(INT, INT);
00346 MAT<T>& D_Swap_Cols(INT, INT);
00347 MAT<T>& D_Add_Row(const T f[]);
00348 MAT<T>& D_Add_Col(const T f[]);
00349 MAT<T>& D_Add_Rows(INT how_many, BOOL = FALSE);
00350 MAT<T>& D_Add_Cols(INT how_many, BOOL = FALSE);
00351 MAT<T>& D_Add_Identity_Rows_and_Cols(INT how_many);
00352 MAT<T>& D_Subtract_Rows(INT how_many);
00353 MAT<T>& D_Update_Row(INT row, const T* f);
00354 MAT<T>& D_Update_Col(INT col, const T* f);
00355
00356 MAT<T>& D_Submul(const MAT<T>& mat, INT m, INT n);
00357
00358 BOOL Is_Identity() const;
00359
00360 void Print(FILE* f) const;
00361
00362 static MEM_POOL* Set_Default_Pool(MEM_POOL* mp) {
00363 MEM_POOL* oldpool = _default_pool;
00364 _default_pool = mp;
00365 return oldpool;
00366 }
00367
00368 static MEM_POOL* Default_Pool() {return _default_pool;}
00369 const MEM_POOL* Pool() const {return _pool;}
00370
00371 private:
00372
00373 INT _r;
00374 INT _c;
00375 INT _rx;
00376 INT _cx;
00377 T* _data;
00378 MEM_POOL* _pool;
00379
00380
00381
00382 static INT _calcx(INT);
00383 static void Print_Element(FILE* f, T);
00384 static MEM_POOL* _default_pool;
00385 void _expand(INT rx, INT cx);
00386 };
00387
00388 typedef MAT<mINT32> IMAT;
00389 typedef MAT<FRAC> FMAT;
00390 typedef MAT<double> DMAT;
00391
00392
00393
00394
00395 extern FMAT IMAT_to_FMAT(const IMAT&, MEM_POOL* =0);
00396 extern DMAT IMAT_to_DMAT(const IMAT&, MEM_POOL* =0);
00397 extern IMAT FMAT_to_IMAT(const FMAT&, MEM_POOL* =0);
00398 extern IMAT DMAT_to_IMAT(const DMAT&, MEM_POOL* =0);
00399
00400 #ifdef __GNUC__
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 template<class T>
00411 MAT<T>::MAT(INT r, INT c, MEM_POOL* mp)
00412 {
00413 _r = r;
00414 _c = c;
00415 _rx = _calcx(r);
00416 _cx = _calcx(c);
00417 _pool = (mp ? mp : _default_pool);
00418 if (_rx > 0 && _cx > 0) {
00419 _data = CXX_NEW_ARRAY(T, _rx*_cx, _pool);
00420 FmtAssert(_data, ("Bad _data in initialization"));
00421 }
00422 else
00423 _data = 0;
00424 }
00425
00426 template<class T>
00427 MAT<T>::MAT(const MAT<T>& a, MEM_POOL* mp)
00428 {
00429 _r = a._r;
00430 _c = a._c;
00431 _rx = a._rx;
00432 _cx = a._cx;
00433 _pool = (mp ? mp : _default_pool);
00434 if (_rx > 0 && _cx > 0) {
00435 _data = CXX_NEW_ARRAY(T, _rx*_cx, _pool);
00436 FmtAssert(_data, ("Bad _data in initialization"));
00437 memcpy(_data, a._data, _cx*_rx*sizeof(T[1]));
00438 }
00439 else
00440 _data = NULL;
00441 }
00442
00443 template<class T>
00444 INT MAT<T>::_calcx(INT v)
00445 {
00446 static INT szs[] = {0, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
00447 0x100, 0x200, 0x400, 0x800,
00448 0x1000, 0x2000, 0x4000, 0x8000,
00449 };
00450 static INT elts = sizeof(szs)/sizeof(INT[1]);
00451
00452 INT i;
00453 for (i = 0; i < elts; i++) {
00454 if (v <= szs[i])
00455 break;
00456 }
00457
00458 FmtAssert(i < elts, ("Matrix dimension %d too large\n", v));
00459 return szs[i];
00460 }
00461
00462 template<class T>
00463 void MAT<T>::_expand(INT rx, INT cx)
00464 {
00465 FmtAssert(_rx <= rx, ("Senseless call to MAT<T>::_expand()"));
00466 FmtAssert(_cx <= cx, ("Senseless call to MAT<T>::_expand()"));
00467
00468 if ((rx == _rx && cx == _cx) || rx == 0 || cx == 0) {
00469 _rx = rx;
00470 _cx = cx;
00471 return;
00472 }
00473
00474 T* newdata = CXX_NEW_ARRAY(T, rx*cx, _pool);
00475 for (INT r = 0; r < Rows(); r++) {
00476 T* pp = &newdata[r*cx];
00477 const T* p = &_data[r*_cx];
00478
00479 for (INT c = 0; c < Cols(); c++)
00480 *pp++ = *p++;
00481 }
00482 if (_data)
00483 CXX_DELETE_ARRAY(_data, _pool);
00484 _data = newdata;
00485 _rx = rx;
00486 _cx = cx;
00487 }
00488
00489 template<class T>
00490 MAT<T>& MAT<T>::operator =(const MAT<T>& a)
00491 {
00492 if (&a == this)
00493 return *this;
00494
00495 _r = a._r;
00496 _c = a._c;
00497
00498 if (a._data == NULL) {
00499 CXX_DELETE_ARRAY(_data, _pool);
00500 _rx = a._rx;
00501 _cx = a._cx;
00502 _data = NULL;
00503 return *this;
00504 }
00505
00506 if (_rx < a._rx || _cx < a._cx) {
00507
00508 if (_data)
00509 CXX_DELETE_ARRAY(_data, _pool);
00510 _data = CXX_NEW_ARRAY(T, a._rx * a._cx, _pool);
00511 FmtAssert(_data, ("Bad assignment to _data"));
00512 _rx = a._rx;
00513 }
00514 else
00515 FmtAssert(_data, ("missing _data in lhs MAT assignment"));
00516
00517 _cx = a._cx;
00518 _rx = a._rx;
00519 FmtAssert(_data != a._data, ("same data in MAT assignment"));
00520 memcpy(_data, a._data, _cx*_rx*sizeof(T[1]));
00521
00522 return *this;
00523 }
00524
00525 template<class T>
00526 MAT<T> MAT<T>::operator +(const MAT<T>& a) const
00527 {
00528 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00529 ("MATs incompatable (%d,%d) + (%d,%d)",
00530 Rows(), Cols(), a.Rows(), a.Cols())) ;
00531
00532 MAT<T> m(Rows(), Cols(), Default_Pool());
00533
00534 for (INT r = 0; r < Rows(); r++) {
00535 T* pm = &m._data[r*m._cx];
00536 T* p = &_data[r*_cx];
00537 T* pa = &a._data[r*a._cx];
00538
00539 for (INT c = 0; c < Cols(); c++)
00540 *pm++ = *p++ + *pa++;
00541 }
00542
00543 return m;
00544 }
00545
00546 template<class T>
00547 MAT<T>& MAT<T>::operator +=(const MAT<T>& a)
00548 {
00549 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00550 ("MATs incompatable (%d,%d) + (%d,%d)",
00551 Rows(), Cols(), a.Rows(), a.Cols())) ;
00552
00553 for (INT r = 0; r < Rows(); r++) {
00554 T* p = &_data[r*_cx];
00555 const T* pa = &a._data[r*a._cx];
00556
00557 for (INT c = 0; c < Cols(); c++)
00558 *p++ += *pa++;
00559 }
00560
00561 return *this;
00562 }
00563
00564 template<class T>
00565 MAT<T> MAT<T>::operator -(const MAT<T>& a) const
00566 {
00567 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00568 ("MATs incompatable (%d,%d) - (%d,%d)",
00569 Rows(), Cols(), a.Rows(), a.Cols())) ;
00570
00571 MAT<T> m(Rows(), Cols(), Default_Pool());
00572
00573 for (INT r = 0; r < Rows(); r++) {
00574 T* pm = &m._data[r*m._cx];
00575 const T* p = &_data[r*_cx];
00576 const T* pa = &a._data[r*a._cx];
00577
00578 for (INT c = 0; c < Cols(); c++)
00579 *pm++ = *p++ - *pa++;
00580 }
00581
00582 return m;
00583 }
00584
00585 template<class T>
00586 MAT<T>& MAT<T>::operator -=(const MAT<T>& a)
00587 {
00588 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00589 ("MATs incompatable (%d,%d) - (%d,%d)",
00590 Rows(), Cols(), a.Rows(), a.Cols())) ;
00591
00592 for (INT r = 0; r < Rows(); r++) {
00593 T* p = &_data[r*_cx];
00594 const T* pa = &a._data[r*a._cx];
00595
00596 for (INT c = 0; c < Cols(); c++)
00597 *p++ -= *pa++;
00598 }
00599
00600 return *this;
00601 }
00602
00603 template<class T>
00604 MAT<T> MAT<T>::operator *(const MAT<T>& a) const
00605 {
00606 FmtAssert(Cols() == a.Rows(),
00607 ("MAT incompatable (%d,%d) * (%d,%d)",
00608 Rows(), Cols(), a.Rows(), a.Cols())) ;
00609
00610 MAT<T> m(Rows(), a.Cols(), Default_Pool());
00611
00612 m.D_Zero();
00613
00614 for (INT i = 0; i < Rows(); i++) {
00615 for (INT k = 0; k < Cols(); k++) {
00616 T* pm = &m._data[i*m._cx];
00617 const T* pa = &a._data[k*a._cx];
00618 const T t = _data[i*_cx+k];
00619
00620 for (INT j = 0; j < a.Cols(); j++)
00621 *pm++ += t * *pa++;
00622 }
00623 }
00624
00625 return m;
00626 }
00627
00628
00629
00630 template<class T>
00631 MAT<T>& MAT<T>::operator *=(const MAT<T>& a)
00632 {
00633 FmtAssert(Cols() == a.Rows(),
00634 ("MAT incompatable (%d,%d) * (%d,%d)",
00635 Rows(), Cols(), a.Rows(), a.Cols())) ;
00636
00637 MAT<T> m = (*this) * a;
00638 *this = m;
00639 return *this;
00640 }
00641
00642 template<class T>
00643 MAT<T>& MAT<T>::D_Submul(const MAT<T>& mat, INT m, INT n)
00644 {
00645 MAT<T> mm(m, n, &LNO_local_pool);
00646 INT i;
00647 for (i = 0; i < m; i++) {
00648 for (INT j = 0; j < n; j++) {
00649 T r = T(0);
00650 for (INT k = 0; k < n; k++)
00651 r += (*this)(i,k) * mat(k,j);
00652 mm(i,j) = r;
00653 }
00654 }
00655 for (i = 0; i < m; i++)
00656 for (INT j = 0; j < n; j++)
00657 (*this)(i,j) = mm(i,j);
00658 return *this;
00659 }
00660
00661 template<class T>
00662 MAT<T> MAT<T>::operator *(T a) const
00663 {
00664 MAT<T> m(Rows(), Cols(), Default_Pool());
00665
00666 for (INT r = 0; r < Rows(); r++) {
00667 const T* p = &_data[r*_cx];
00668 T* mp = &m._data[r*m._cx];
00669
00670 for (INT c = 0; c < Cols(); c++)
00671 *mp++ = *p++ * a;
00672 }
00673
00674 return m;
00675 }
00676
00677 template<class T>
00678 MAT<T>& MAT<T>::operator *=(T a)
00679 {
00680 for (INT r = 0; r < Rows(); r++) {
00681 T* p = &_data[r*_cx];
00682
00683 for (INT c = 0; c < Cols(); c++)
00684 *p++ = (*p) * a;
00685 }
00686
00687 return *this;
00688 }
00689
00690 template<class T>
00691 MAT<T> MAT<T>::Trans() const
00692 {
00693 MAT<T> m(Cols(), Rows());
00694
00695 for (INT r = 0; r < Rows(); r++)
00696 for (INT c = 0; c < Cols(); c++)
00697 m(c,r) = (*this)(r,c);
00698
00699 return m;
00700 }
00701
00702 template<class T>
00703 MAT<T>& MAT<T>::D_Trans()
00704 {
00705 MAT<T> m = Trans();
00706 *this = m;
00707 return *this;
00708 }
00709
00710 template<class T>
00711 MAT<T>& MAT<T>::D_Zero()
00712 {
00713 for (INT r = 0; r < Rows(); r++) {
00714 T* p = &_data[r*_cx];
00715 const T zero = T(0);
00716
00717 for (INT c = 0; c < Cols(); c++)
00718 *p++ = zero;
00719 }
00720
00721 return *this;
00722 }
00723
00724 template<class T>
00725 MAT<T>& MAT<T>::D_Identity()
00726 {
00727 for (INT r = 0; r < Rows(); r++) {
00728 T* p = &_data[r*_cx];
00729 const T zero(0);
00730 const T one(1);
00731
00732 for (INT c = 0; c < Cols(); c++)
00733 *p++ = (c == r) ? one : zero;
00734 }
00735
00736 return *this;
00737 }
00738
00739 template<class T>
00740 MAT<T>& MAT<T>::D_Swap_Rows(INT r1, INT r2)
00741 {
00742 if (r1 == r2)
00743 return *this;
00744
00745 FmtAssert(r1 < Rows() && r2 < Rows(), ("Bad call to D_Swap_Rows()"));
00746
00747 T* p1 = &_data[r1*_cx];
00748 T* p2 = &_data[r2*_cx];
00749
00750 for (INT cc = 0; cc < Cols(); cc++) {
00751 T x = *p1;
00752 *p1++ = *p2;
00753 *p2++ = x;
00754 }
00755
00756 return *this;
00757 }
00758
00759 template<class T>
00760 MAT<T>& MAT<T>::D_Swap_Cols(INT c1, INT c2)
00761 {
00762 if (c1 == c2)
00763 return *this;
00764
00765 FmtAssert(c1 < Cols() && c2 < Cols(), ("Bad call to D_Swap_Cols()"));
00766
00767 for (INT r = 0; r < Rows(); r++) {
00768 T x = (*this)(r,c1);
00769 (*this)(r,c1) = (*this)(r,c2);
00770 (*this)(r,c2) = x;
00771 }
00772
00773 return *this;
00774 }
00775
00776 template<class T>
00777 MAT<T>& MAT<T>::D_Update_Row(INT r, const T f[])
00778 {
00779 FmtAssert(r < Rows(), ("Bad call to D_Update_Rows()"));
00780
00781 T* p = &_data[r*_cx];
00782
00783 for (INT c = 0; c < Cols(); c++)
00784 *p++ = f[c];
00785
00786 return *this;
00787 }
00788
00789 template<class T>
00790 MAT<T>& MAT<T>::D_Update_Col(INT c, const T f[])
00791 {
00792 FmtAssert(c < Cols(), ("Bad call to D_Update_Cols()"));
00793
00794 for (INT r = 0; r < Rows(); r++)
00795 (*this)(r,c) = f[r];
00796
00797 return *this;
00798 }
00799
00800 template<class T>
00801 MAT<T>& MAT<T>::D_Add_Row(const T f[])
00802 {
00803 D_Add_Rows(1, FALSE);
00804 D_Update_Row(_r-1, f);
00805 return *this;
00806 }
00807
00808 template<class T>
00809 MAT<T>& MAT<T>::D_Add_Col(const T f[])
00810 {
00811 D_Add_Cols(1, FALSE);
00812 D_Update_Col(_c-1, f);
00813 return *this;
00814 }
00815
00816 template<class T>
00817 MAT<T>& MAT<T>::D_Add_Rows(INT how_many, BOOL init_to_zero)
00818 {
00819 Is_True(_r <= _rx, ("D_Add_Rows(): broken row size"));
00820 Is_True(how_many >= 0, ("D_Add_Rows(): passed how_many=%d", how_many));
00821
00822 if (_r + how_many > _rx)
00823 _expand(_calcx(_r + how_many), _cx);
00824
00825 _r += how_many;
00826
00827 if (init_to_zero) {
00828 for (INT r = _r - how_many; r < _r; r++) {
00829 T* p = &_data[r*_cx];
00830 for (INT c = 0; c < Cols(); c++)
00831 *p++ = T(0);
00832 }
00833 }
00834 return *this;
00835 }
00836
00837 template<class T>
00838 MAT<T>& MAT<T>::D_Subtract_Rows(INT how_many)
00839 {
00840 Is_True(_r <= _rx, ("D_Subtract_Rows(): broken row size"));
00841 Is_True(_r >= how_many, ("D_Subtract_Rows(): subtracting too many rows"));
00842 Is_True(how_many >= 0, ("D_Subtract_Rows(): passed how_many=%d", how_many));
00843
00844 _r -= how_many;
00845
00846 return *this;
00847 }
00848
00849 template<class T>
00850 MAT<T>& MAT<T>::D_Add_Cols(INT how_many, BOOL init_to_zero)
00851 {
00852 Is_True(_c <= _cx, ("D_Add_Cols(): broken col size"));
00853 Is_True(how_many >= 0, ("D_Add_Cols(): passed how_many=%d", how_many));
00854
00855 if (_c + how_many > _cx)
00856 _expand(_rx, _calcx(_c + how_many));
00857
00858 _c += how_many;
00859
00860 if (init_to_zero) {
00861 for (INT r = 0; r < Rows(); r++) {
00862 T* p = &_data[r*_cx];
00863 for (INT c = _c - how_many; c < _c; c++)
00864 p[c] = T(0);
00865 }
00866 }
00867 return *this;
00868 }
00869
00870 template<class T>
00871 MAT<T>& MAT<T>::D_Add_Identity_Rows_and_Cols(INT how_many)
00872 {
00873 FmtAssert(Rows() == Cols(),
00874 ("D_Add_Identity_Rows_and_Cols() requires square matrix"));
00875 D_Add_Rows(how_many, TRUE);
00876 D_Add_Cols(how_many, TRUE);
00877 for (INT r = _r - how_many; r < _r; r++)
00878 (*this)(r,r) = T(1);
00879 return *this;
00880 }
00881
00882 template<class T>
00883 BOOL MAT<T>::Is_Identity() const
00884 {
00885 FmtAssert(Rows() == Cols(), ("Is_Identity() requires square matrix"));
00886 for (INT r = 0; r < Rows(); r++)
00887 for (INT c = 0; c < Cols(); c++)
00888 if ((*this)(r,c) != (r==c))
00889 return FALSE;
00890 return TRUE;
00891 }
00892
00893
00894 template<class T>
00895 void MAT<T>::Print(FILE* f) const
00896 {
00897 for (INT r = 0; r < Rows(); r++) {
00898 for (INT c = 0; c < Cols(); c++) {
00899 fprintf(f, " ");
00900 Print_Element(f, (*this)(r,c));
00901 }
00902 fprintf(f, "\n");
00903 }
00904 }
00905
00906 template<class T>
00907 MAT<T>& MAT<T>::D_Inv()
00908 {
00909 return *this = Inv();
00910 }
00911
00912 template<class T>
00913 MAT<T> MAT<T>::L() const
00914 {
00915 MAT<T> rval(Rows(), Rows(), 0);
00916
00917 for(INT i = 0; i < Rows(); i++) {
00918 for (INT j = 0; j < Rows(); j++) {
00919 if (i < j)
00920 rval(i,j) = FRAC(0);
00921 else if(i == j)
00922 rval(i,j) = FRAC(1);
00923 else if (j < Cols())
00924 rval(i,j) = (*this)(i,j);
00925 else
00926 rval(i,j) = FRAC(0);
00927 }
00928 }
00929 return rval;
00930 }
00931
00932 template<class T>
00933 MAT<T> MAT<T>::U() const
00934 {
00935 MAT<T> rval(Rows(), Cols(), 0);
00936
00937 for(INT i = 0; i < Rows(); i++) {
00938 for(INT j = 0; j < Cols(); j++) {
00939 if (i <= j)
00940 rval(i,j) = (*this)(i,j);
00941 else
00942 rval(i,j) = FRAC(0);
00943 }
00944 }
00945
00946 return rval;
00947 }
00948 #endif
00949
00950 #endif