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
00048 #ifndef mat_CXX
00049 #define mat_CXX "mat.cxx"
00050 #endif
00051
00052 #define __STDC_LIMIT_MACROS
00053 #include <stdint.h>
00054 #ifndef mat_INCLUDED
00055 #include "lnopt_main.h"
00056 #include "mat.h"
00057 #endif
00058
00059
00060
00061 extern MEM_POOL LNO_local_pool;
00062
00063
00064
00065
00066
00067
00068
00069 #ifndef __GNUC__
00070 template<class T>
00071 MAT<T>::MAT(INT r, INT c, MEM_POOL* mp)
00072 {
00073 _r = r;
00074 _c = c;
00075 _rx = _calcx(r);
00076 _cx = _calcx(c);
00077 _pool = (mp ? mp : _default_pool);
00078 if (_rx > 0 && _cx > 0) {
00079 _data = CXX_NEW_ARRAY(T, _rx*_cx, _pool);
00080 FmtAssert(_data, ("Bad _data in initialization"));
00081 }
00082 else
00083 _data = 0;
00084 }
00085
00086 template<class T>
00087 MAT<T>::MAT(const MAT<T>& a, MEM_POOL* mp)
00088 {
00089 _r = a._r;
00090 _c = a._c;
00091 _rx = a._rx;
00092 _cx = a._cx;
00093 _pool = (mp ? mp : _default_pool);
00094 if (_rx > 0 && _cx > 0) {
00095 _data = CXX_NEW_ARRAY(T, _rx*_cx, _pool);
00096 FmtAssert(_data, ("Bad _data in initialization"));
00097 memcpy(_data, a._data, _cx*_rx*sizeof(T[1]));
00098 }
00099 else
00100 _data = NULL;
00101 }
00102
00103 template<class T>
00104 INT MAT<T>::_calcx(INT v)
00105 {
00106 static INT szs[] = {0, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
00107 0x100, 0x200, 0x400, 0x800,
00108 0x1000, 0x2000, 0x4000, 0x8000,
00109 };
00110 static INT elts = sizeof(szs)/sizeof(INT[1]);
00111
00112 for (INT i = 0; i < elts; i++) {
00113 if (v <= szs[i])
00114 break;
00115 }
00116
00117 FmtAssert(i < elts, ("Matrix dimension %d too large\n", v));
00118 return szs[i];
00119 }
00120
00121 template<class T>
00122 void MAT<T>::_expand(INT rx, INT cx)
00123 {
00124 FmtAssert(_rx <= rx, ("Senseless call to MAT<T>::_expand()"));
00125 FmtAssert(_cx <= cx, ("Senseless call to MAT<T>::_expand()"));
00126
00127 if ((rx == _rx && cx == _cx) || rx == 0 || cx == 0) {
00128 _rx = rx;
00129 _cx = cx;
00130 return;
00131 }
00132
00133 T* newdata = CXX_NEW_ARRAY(T, rx*cx, _pool);
00134 for (INT r = 0; r < Rows(); r++) {
00135 T* pp = &newdata[r*cx];
00136 const T* p = &_data[r*_cx];
00137
00138 for (INT c = 0; c < Cols(); c++)
00139 *pp++ = *p++;
00140 }
00141 if (_data)
00142 CXX_DELETE_ARRAY(_data, _pool);
00143 _data = newdata;
00144 _rx = rx;
00145 _cx = cx;
00146 }
00147
00148 template<class T>
00149 MAT<T>& MAT<T>::operator =(const MAT<T>& a)
00150 {
00151 if (&a == this)
00152 return *this;
00153
00154 _r = a._r;
00155 _c = a._c;
00156
00157 if (a._data == NULL) {
00158 CXX_DELETE_ARRAY(_data, _pool);
00159 _rx = a._rx;
00160 _cx = a._cx;
00161 _data = NULL;
00162 return *this;
00163 }
00164
00165 if (_rx < a._rx || _cx < a._cx) {
00166
00167 if (_data)
00168 CXX_DELETE_ARRAY(_data, _pool);
00169 _data = CXX_NEW_ARRAY(T, a._rx * a._cx, _pool);
00170 FmtAssert(_data, ("Bad assignment to _data"));
00171 _rx = a._rx;
00172 }
00173 else
00174 FmtAssert(_data, ("missing _data in lhs MAT assignment"));
00175
00176 _cx = a._cx;
00177 _rx = a._rx;
00178 FmtAssert(_data != a._data, ("same data in MAT assignment"));
00179 memcpy(_data, a._data, _cx*_rx*sizeof(T[1]));
00180
00181 return *this;
00182 }
00183
00184 template<class T>
00185 MAT<T> MAT<T>::operator +(const MAT<T>& a) const
00186 {
00187 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00188 ("MATs incompatable (%d,%d) + (%d,%d)",
00189 Rows(), Cols(), a.Rows(), a.Cols())) ;
00190
00191 MAT<T> m(Rows(), Cols(), Default_Pool());
00192
00193 for (INT r = 0; r < Rows(); rr++) {
00194 T* pm = &m._data[r*m._cx];
00195 T* p = &_data[r*_cx];
00196 T* pa = &a._data[r*a._cx];
00197
00198 for (INT c = 0; c < Cols(); c++)
00199 *pm++ = *p++ + *pa++;
00200 }
00201
00202 return m;
00203 }
00204
00205 template<class T>
00206 MAT<T>& MAT<T>::operator +=(const MAT<T>& a)
00207 {
00208 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00209 ("MATs incompatable (%d,%d) + (%d,%d)",
00210 Rows(), Cols(), a.Rows(), a.Cols())) ;
00211
00212 for (INT r = 0; r < Rows(); r++) {
00213 T* p = &_data[r*_cx];
00214 const T* pa = &a._data[r*a._cx];
00215
00216 for (INT c = 0; c < Cols(); c++)
00217 *p++ += *pa++;
00218 }
00219
00220 return *this;
00221 }
00222
00223 template<class T>
00224 MAT<T> MAT<T>::operator -(const MAT<T>& a) const
00225 {
00226 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00227 ("MATs incompatable (%d,%d) - (%d,%d)",
00228 Rows(), Cols(), a.Rows(), a.Cols())) ;
00229
00230 MAT<T> m(Rows(), Cols(), Default_Pool());
00231
00232 for (INT r = 0; r < Rows(); r++) {
00233 T* pm = &m._data[r*m._cx];
00234 const T* p = &_data[r*_cx];
00235 const T* pa = &a._data[r*a._cx];
00236
00237 for (INT c = 0; c < Cols(); c++)
00238 *pm++ = *p++ - *pa++;
00239 }
00240
00241 return m;
00242 }
00243
00244 template<class T>
00245 MAT<T>& MAT<T>::operator -=(const MAT<T>& a)
00246 {
00247 FmtAssert(Rows() == a.Rows() && a.Cols() == Cols(),
00248 ("MATs incompatable (%d,%d) - (%d,%d)",
00249 Rows(), Cols(), a.Rows(), a.Cols())) ;
00250
00251 for (INT r = 0; r < Rows(); r++) {
00252 T* p = &_data[r*_cx];
00253 const T* pa = &a._data[r*a._cx];
00254
00255 for (INT c = 0; c < Cols(); c++)
00256 *p++ -= *pa++;
00257 }
00258
00259 return *this;
00260 }
00261
00262 template<class T>
00263 MAT<T> MAT<T>::operator *(const MAT<T>& a) const
00264 {
00265 FmtAssert(Cols() == a.Rows(),
00266 ("MAT incompatable (%d,%d) * (%d,%d)",
00267 Rows(), Cols(), a.Rows(), a.Cols())) ;
00268
00269 MAT<T> m(Rows(), a.Cols(), Default_Pool());
00270
00271 m.D_Zero();
00272
00273 for (INT i = 0; i < Rows(); i++) {
00274 for (INT k = 0; k < Cols(); k++) {
00275 T* pm = &m._data[i*m._cx];
00276 const T* pa = &a._data[k*a._cx];
00277 const T t = _data[i*_cx+k];
00278
00279 for (INT j = 0; j < a.Cols(); j++)
00280 *pm++ += t * *pa++;
00281 }
00282 }
00283
00284 return m;
00285 }
00286
00287
00288
00289 template<class T>
00290 MAT<T>& MAT<T>::operator *=(const MAT<T>& a)
00291 {
00292 FmtAssert(Cols() == a.Rows(),
00293 ("MAT incompatable (%d,%d) * (%d,%d)",
00294 Rows(), Cols(), a.Rows(), a.Cols())) ;
00295
00296 MAT<T> m = (*this) * a;
00297 *this = m;
00298 return *this;
00299 }
00300
00301 template<class T>
00302 MAT<T>& MAT<T>::D_Submul(const MAT<T>& mat, INT m, INT n)
00303 {
00304 MAT<T> mm(m, n, &LNO_local_pool);
00305 for (INT i = 0; i < m; i++) {
00306 for (INT j = 0; j < n; j++) {
00307 T r = T(0);
00308 for (INT k = 0; k < n; k++)
00309 r += (*this)(i,k) * mat(k,j);
00310 mm(i,j) = r;
00311 }
00312 }
00313 for (i = 0; i < m; i++)
00314 for (INT j = 0; j < n; j++)
00315 (*this)(i,j) = mm(i,j);
00316 return *this;
00317 }
00318
00319 template<class T>
00320 MAT<T> MAT<T>::operator *(T a) const
00321 {
00322 MAT<T> m(Rows(), Cols(), Default_Pool());
00323
00324 for (INT r = 0; r < Rows(); r++) {
00325 const T* p = &_data[r*_cx];
00326 T* mp = &m._data[r*m._cx];
00327
00328 for (INT c = 0; c < Cols(); c++)
00329 *mp++ = *p++ * a;
00330 }
00331
00332 return m;
00333 }
00334
00335 template<class T>
00336 MAT<T>& MAT<T>::operator *=(T a)
00337 {
00338 for (INT r = 0; r < Rows(); r++) {
00339 T* p = &_data[r*_cx];
00340
00341 for (INT c = 0; c < Cols(); c++)
00342 *p++ = (*p) * a;
00343 }
00344
00345 return *this;
00346 }
00347
00348 template<class T>
00349 MAT<T> MAT<T>::Trans() const
00350 {
00351 MAT<T> m(Cols(), Rows());
00352
00353 for (INT r = 0; r < Rows(); r++)
00354 for (INT c = 0; c < Cols(); c++)
00355 m(c,r) = (*this)(r,c);
00356
00357 return m;
00358 }
00359
00360 template<class T>
00361 MAT<T>& MAT<T>::D_Trans()
00362 {
00363 MAT<T> m = Trans();
00364 *this = m;
00365 return *this;
00366 }
00367
00368 template<class T>
00369 MAT<T>& MAT<T>::D_Zero()
00370 {
00371 for (INT r = 0; r < Rows(); r++) {
00372 T* p = &_data[r*_cx];
00373 const T zero = T(0);
00374
00375 for (INT c = 0; c < Cols(); c++)
00376 *p++ = zero;
00377 }
00378
00379 return *this;
00380 }
00381
00382 template<class T>
00383 MAT<T>& MAT<T>::D_Identity()
00384 {
00385 for (INT r = 0; r < Rows(); r++) {
00386 T* p = &_data[r*_cx];
00387 const T zero(0);
00388 const T one(1);
00389
00390 for (INT c = 0; c < Cols(); c++)
00391 *p++ = (c == r) ? one : zero;
00392 }
00393
00394 return *this;
00395 }
00396
00397 template<class T>
00398 MAT<T>& MAT<T>::D_Swap_Rows(INT r1, INT r2)
00399 {
00400 if (r1 == r2)
00401 return *this;
00402
00403 FmtAssert(r1 < Rows() && r2 < Rows(), ("Bad call to D_Swap_Rows()"));
00404
00405 T* p1 = &_data[r1*_cx];
00406 T* p2 = &_data[r2*_cx];
00407
00408 for (INT cc = 0; cc < Cols(); cc++) {
00409 T x = *p1;
00410 *p1++ = *p2;
00411 *p2++ = x;
00412 }
00413
00414 return *this;
00415 }
00416
00417 template<class T>
00418 MAT<T>& MAT<T>::D_Swap_Cols(INT c1, INT c2)
00419 {
00420 if (c1 == c2)
00421 return *this;
00422
00423 FmtAssert(c1 < Cols() && c2 < Cols(), ("Bad call to D_Swap_Cols()"));
00424
00425 for (INT r = 0; r < Rows(); r++) {
00426 T x = (*this)(r,c1);
00427 (*this)(r,c1) = (*this)(r,c2);
00428 (*this)(r,c2) = x;
00429 }
00430
00431 return *this;
00432 }
00433
00434 template<class T>
00435 MAT<T>& MAT<T>::D_Update_Row(INT r, const T f[])
00436 {
00437 FmtAssert(r < Rows(), ("Bad call to D_Update_Rows()"));
00438
00439 T* p = &_data[r*_cx];
00440
00441 for (INT c = 0; c < Cols(); c++)
00442 *p++ = f[c];
00443
00444 return *this;
00445 }
00446
00447 template<class T>
00448 MAT<T>& MAT<T>::D_Update_Col(INT c, const T f[])
00449 {
00450 FmtAssert(c < Cols(), ("Bad call to D_Update_Cols()"));
00451
00452 for (INT r = 0; r < Rows(); r++)
00453 (*this)(r,c) = f[r];
00454
00455 return *this;
00456 }
00457
00458 template<class T>
00459 MAT<T>& MAT<T>::D_Add_Row(const T f[])
00460 {
00461 D_Add_Rows(1, FALSE);
00462 D_Update_Row(_r-1, f);
00463 return *this;
00464 }
00465
00466 template<class T>
00467 MAT<T>& MAT<T>::D_Add_Col(const T f[])
00468 {
00469 D_Add_Cols(1, FALSE);
00470 D_Update_Col(_c-1, f);
00471 return *this;
00472 }
00473
00474 template<class T>
00475 MAT<T>& MAT<T>::D_Add_Rows(INT how_many, BOOL init_to_zero)
00476 {
00477 Is_True(_r <= _rx, ("D_Add_Rows(): broken row size"));
00478 Is_True(how_many >= 0, ("D_Add_Rows(): passed how_many=%d", how_many));
00479
00480 if (_r + how_many > _rx)
00481 _expand(_calcx(_r + how_many), _cx);
00482
00483 _r += how_many;
00484
00485 if (init_to_zero) {
00486 for (INT r = _r - how_many; r < _r; r++) {
00487 T* p = &_data[r*_cx];
00488 for (INT c = 0; c < Cols(); c++)
00489 *p++ = T(0);
00490 }
00491 }
00492 return *this;
00493 }
00494
00495 template<class T>
00496 MAT<T>& MAT<T>::D_Subtract_Rows(INT how_many)
00497 {
00498 Is_True(_r <= _rx, ("D_Subtract_Rows(): broken row size"));
00499 Is_True(_r >= how_many, ("D_Subtract_Rows(): subtracting too many rows"));
00500 Is_True(how_many >= 0, ("D_Subtract_Rows(): passed how_many=%d", how_many));
00501
00502 _r -= how_many;
00503
00504 return *this;
00505 }
00506
00507 template<class T>
00508 MAT<T>& MAT<T>::D_Add_Cols(INT how_many, BOOL init_to_zero)
00509 {
00510 Is_True(_c <= _cx, ("D_Add_Cols(): broken col size"));
00511 Is_True(how_many >= 0, ("D_Add_Cols(): passed how_many=%d", how_many));
00512
00513 if (_c + how_many > _cx)
00514 _expand(_rx, _calcx(_c + how_many));
00515
00516 _c += how_many;
00517
00518 if (init_to_zero) {
00519 for (INT r = 0; r < Rows(); r++) {
00520 T* p = &_data[r*_cx];
00521 for (INT c = _c - how_many; c < _c; c++)
00522 p[c] = T(0);
00523 }
00524 }
00525 return *this;
00526 }
00527
00528 template<class T>
00529 MAT<T>& MAT<T>::D_Add_Identity_Rows_and_Cols(INT how_many)
00530 {
00531 FmtAssert(Rows() == Cols(),
00532 ("D_Add_Identity_Rows_and_Cols() requires square matrix"));
00533 D_Add_Rows(how_many, TRUE);
00534 D_Add_Cols(how_many, TRUE);
00535 for (INT r = _r - how_many; r < _r; r++)
00536 (*this)(r,r) = T(1);
00537 return *this;
00538 }
00539
00540 template<class T>
00541 BOOL MAT<T>::Is_Identity() const
00542 {
00543 FmtAssert(Rows() == Cols(), ("Is_Identity() requires square matrix"));
00544 for (INT r = 0; r < Rows(); r++)
00545 for (INT c = 0; c < Cols(); c++)
00546 if ((*this)(r,c) != (r==c))
00547 return FALSE;
00548 return TRUE;
00549 }
00550
00551
00552 template<class T>
00553 void MAT<T>::Print(FILE* f) const
00554 {
00555 for (INT r = 0; r < Rows(); r++) {
00556 for (INT c = 0; c < Cols(); c++) {
00557 fprintf(f, " ");
00558 Print_Element(f, (*this)(r,c));
00559 }
00560 fprintf(f, "\n");
00561 }
00562 }
00563
00564 template<class T>
00565 MAT<T>& MAT<T>::D_Inv()
00566 {
00567 return *this = Inv();
00568 }
00569
00570 template<class T>
00571 MAT<T> MAT<T>::L() const
00572 {
00573 MAT<T> rval(Rows(), Rows(), 0);
00574
00575 for(INT i = 0; i < Rows(); i++) {
00576 for (INT j = 0; j < Rows(); j++) {
00577 if (i < j)
00578 rval(i,j) = FRAC(0);
00579 else if(i == j)
00580 rval(i,j) = FRAC(1);
00581 else if (j < Cols())
00582 rval(i,j) = (*this)(i,j);
00583 else
00584 rval(i,j) = FRAC(0);
00585 }
00586 }
00587 return rval;
00588 }
00589
00590 template<class T>
00591 MAT<T> MAT<T>::U() const
00592 {
00593 MAT<T> rval(Rows(), Cols(), 0);
00594
00595 for(INT i = 0; i < Rows(); i++) {
00596 for(INT j = 0; j < Cols(); j++) {
00597 if (i <= j)
00598 rval(i,j) = (*this)(i,j);
00599 else
00600 rval(i,j) = FRAC(0);
00601 }
00602 }
00603
00604 return rval;
00605 }
00606
00607 #endif