00001
00002
00003
00004
00005
00006 #include "include.h"
00007
00008 #include "newmat.h"
00009 #include "newmatrc.h"
00010
00011 #ifdef use_namespace
00012 namespace NEWMAT {
00013 #endif
00014
00015 #ifdef DO_REPORT
00016 #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; }
00017 #else
00018 #define REPORT {}
00019 #endif
00020
00021 #define DO_SEARCH // search for LHS of = in RHS
00022
00023
00024
00025 static int tristore(int n)
00026 { return (n*(n+1))/2; }
00027
00028
00029
00030 GeneralMatrix::GeneralMatrix()
00031 { store=0; storage=0; nrows=0; ncols=0; tag=-1; }
00032
00033 GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s) {
00034 REPORT
00035 storage=s.Value(); tag=-1;
00036 if (storage) {
00037 store = new Real [storage]; MatrixErrorNoSpace(store);
00038 MONITOR_REAL_NEW("Make (GenMatrix)",storage,store)
00039 }
00040 else store = 0;
00041 }
00042
00043 Matrix::Matrix(int m, int n) : GeneralMatrix(m*n)
00044 { REPORT nrows=m; ncols=n; }
00045
00046 SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n)
00047 : GeneralMatrix(tristore(n.Value()))
00048 { REPORT nrows=n.Value(); ncols=n.Value(); }
00049
00050 UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n)
00051 : GeneralMatrix(tristore(n.Value()))
00052 { REPORT nrows=n.Value(); ncols=n.Value(); }
00053
00054 LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n)
00055 : GeneralMatrix(tristore(n.Value()))
00056 { REPORT nrows=n.Value(); ncols=n.Value(); }
00057
00058 DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m)
00059 { REPORT nrows=m.Value(); ncols=m.Value(); }
00060
00061 Matrix::Matrix(const BaseMatrix& M) {
00062 REPORT
00063 MatrixConversionCheck mcc;
00064 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt);
00065 GetMatrix(gmx);
00066 }
00067
00068 RowVector::RowVector(const BaseMatrix& M) : Matrix(M) {
00069 if (nrows!=1) {
00070 Tracer tr("RowVector");
00071 Throw(VectorException(*this));
00072 }
00073 }
00074
00075 ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M) {
00076 if (ncols!=1) {
00077 Tracer tr("ColumnVector");
00078 Throw(VectorException(*this));
00079 }
00080 }
00081
00082 SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M) {
00083 REPORT
00084 MatrixConversionCheck mcc;
00085 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm);
00086 GetMatrix(gmx);
00087 }
00088
00089 UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M) {
00090 REPORT
00091 MatrixConversionCheck mcc;
00092 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT);
00093 GetMatrix(gmx);
00094 }
00095
00096 LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M) {
00097 REPORT
00098 MatrixConversionCheck mcc;
00099 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT);
00100 GetMatrix(gmx);
00101 }
00102
00103 DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M) {
00104 REPORT
00105 MatrixConversionCheck mcc;
00106 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg);
00107 GetMatrix(gmx);
00108 }
00109
00110 GeneralMatrix::~GeneralMatrix() {
00111 if (store) {
00112 MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store)
00113 delete [] store;
00114 }
00115 }
00116
00117 CroutMatrix::CroutMatrix(const BaseMatrix& m) {
00118 REPORT
00119 Tracer tr("CroutMatrix");
00120 GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::Rt);
00121 GetMatrix(gm);
00122 if (nrows!=ncols) Throw(NotSquareException(*this));
00123 d=true; sing=false;
00124 indx=new int [nrows]; MatrixErrorNoSpace(indx);
00125 MONITOR_INT_NEW("Index (CroutMat)",nrows,indx)
00126 ludcmp();
00127 }
00128
00129 CroutMatrix::~CroutMatrix() {
00130 MONITOR_INT_DELETE("Index (CroutMat)",nrows,indx)
00131 delete [] indx;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140 #ifndef TEMPS_DESTROYED_QUICKLY_R
00141
00142 GeneralMatrix::operator ReturnMatrixX() const {
00143 REPORT
00144 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00145 return ReturnMatrixX(gm);
00146 }
00147
00148 #else
00149
00150 GeneralMatrix::operator ReturnMatrixX&() const {
00151 REPORT
00152 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00153 ReturnMatrixX* x = new ReturnMatrixX(gm);
00154 MatrixErrorNoSpace(x); return *x;
00155 }
00156 #endif
00157
00158 #ifndef TEMPS_DESTROYED_QUICKLY_R
00159
00160 ReturnMatrixX GeneralMatrix::ForReturn() const {
00161 REPORT
00162 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00163 return ReturnMatrixX(gm);
00164 }
00165
00166 #else
00167
00168 ReturnMatrixX& GeneralMatrix::ForReturn() const {
00169 REPORT
00170 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00171 ReturnMatrixX* x = new ReturnMatrixX(gm);
00172 MatrixErrorNoSpace(x); return *x;
00173 }
00174 #endif
00175
00176
00177
00178 void GeneralMatrix::ReSize(int nr, int nc, int s) {
00179 REPORT
00180 if (store) {
00181 MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store)
00182 delete [] store;
00183 }
00184 storage=s; nrows=nr; ncols=nc; tag=-1;
00185 if (s) {
00186 store = new Real [storage]; MatrixErrorNoSpace(store);
00187 MONITOR_REAL_NEW("Make (ReDimensi)",storage,store)
00188 }
00189 else store = 0;
00190 }
00191
00192 void Matrix::ReSize(int nr, int nc)
00193 { REPORT GeneralMatrix::ReSize(nr,nc,nr*nc); }
00194
00195 void SymmetricMatrix::ReSize(int nr)
00196 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
00197
00198 void UpperTriangularMatrix::ReSize(int nr)
00199 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
00200
00201 void LowerTriangularMatrix::ReSize(int nr)
00202 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
00203
00204 void DiagonalMatrix::ReSize(int nr)
00205 { REPORT GeneralMatrix::ReSize(nr,nr,nr); }
00206
00207 void RowVector::ReSize(int nc)
00208 { REPORT GeneralMatrix::ReSize(1,nc,nc); }
00209
00210 void ColumnVector::ReSize(int nr)
00211 { REPORT GeneralMatrix::ReSize(nr,1,nr); }
00212
00213 void RowVector::ReSize(int nr, int nc) {
00214 Tracer tr("RowVector::ReSize");
00215 if (nr != 1) Throw(VectorException(*this));
00216 REPORT GeneralMatrix::ReSize(1,nc,nc);
00217 }
00218
00219 void ColumnVector::ReSize(int nr, int nc) {
00220 Tracer tr("ColumnVector::ReSize");
00221 if (nc != 1) Throw(VectorException(*this));
00222 REPORT GeneralMatrix::ReSize(nr,1,nr);
00223 }
00224
00225
00226
00227 int GeneralMatrix::search(const BaseMatrix* s) const
00228 { REPORT return (s==this) ? 1 : 0; }
00229
00230 int GenericMatrix::search(const BaseMatrix* s) const
00231 { REPORT return gm->search(s); }
00232
00233 int MultipliedMatrix::search(const BaseMatrix* s) const
00234 { REPORT return bm1->search(s) + bm2->search(s); }
00235
00236 int ShiftedMatrix::search(const BaseMatrix* s) const
00237 { REPORT return bm->search(s); }
00238
00239 int NegatedMatrix::search(const BaseMatrix* s) const
00240 { REPORT return bm->search(s); }
00241
00242 int ReturnMatrixX::search(const BaseMatrix* s) const
00243 { REPORT return (s==gm) ? 1 : 0; }
00244
00245 MatrixType Matrix::Type() const { return MatrixType::Rt; }
00246 MatrixType SymmetricMatrix::Type() const { return MatrixType::Sm; }
00247 MatrixType UpperTriangularMatrix::Type() const { return MatrixType::UT; }
00248 MatrixType LowerTriangularMatrix::Type() const { return MatrixType::LT; }
00249 MatrixType DiagonalMatrix::Type() const { return MatrixType::Dg; }
00250 MatrixType RowVector::Type() const { return MatrixType::RV; }
00251 MatrixType ColumnVector::Type() const { return MatrixType::CV; }
00252 MatrixType CroutMatrix::Type() const { return MatrixType::Ct; }
00253 MatrixType BandMatrix::Type() const { return MatrixType::BM; }
00254 MatrixType UpperBandMatrix::Type() const { return MatrixType::UB; }
00255 MatrixType LowerBandMatrix::Type() const { return MatrixType::LB; }
00256 MatrixType SymmetricBandMatrix::Type() const { return MatrixType::SB; }
00257
00258 MatrixBandWidth BaseMatrix::BandWidth() const { return -1; }
00259 MatrixBandWidth DiagonalMatrix::BandWidth() const { return 0; }
00260
00261 MatrixBandWidth BandMatrix::BandWidth() const
00262 { return MatrixBandWidth(lower,upper); }
00263
00264 MatrixBandWidth GenericMatrix::BandWidth() const { return gm->BandWidth(); }
00265
00266 MatrixBandWidth AddedMatrix::BandWidth() const
00267 { return gm1->BandWidth() + gm2->BandWidth(); }
00268
00269 MatrixBandWidth SPMatrix::BandWidth() const
00270 { return gm1->BandWidth().minimum(gm2->BandWidth()); }
00271
00272 MatrixBandWidth MultipliedMatrix::BandWidth() const
00273 { return gm1->BandWidth() * gm2->BandWidth(); }
00274
00275 MatrixBandWidth ConcatenatedMatrix::BandWidth() const { return -1; }
00276 MatrixBandWidth SolvedMatrix::BandWidth() const { return -1; }
00277 MatrixBandWidth ScaledMatrix::BandWidth() const { return gm->BandWidth(); }
00278 MatrixBandWidth NegatedMatrix::BandWidth() const { return gm->BandWidth(); }
00279
00280 MatrixBandWidth TransposedMatrix::BandWidth() const
00281 { return gm->BandWidth().t(); }
00282
00283 MatrixBandWidth InvertedMatrix::BandWidth() const { return -1; }
00284 MatrixBandWidth RowedMatrix::BandWidth() const { return -1; }
00285 MatrixBandWidth ColedMatrix::BandWidth() const { return -1; }
00286 MatrixBandWidth DiagedMatrix::BandWidth() const { return 0; }
00287 MatrixBandWidth MatedMatrix::BandWidth() const { return -1; }
00288 MatrixBandWidth ReturnMatrixX::BandWidth() const { return gm->BandWidth(); }
00289
00290 MatrixBandWidth GetSubMatrix::BandWidth() const {
00291
00292 if (row_skip==col_skip && row_number==col_number) return gm->BandWidth();
00293 else return MatrixBandWidth(-1);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 void GeneralMatrix::tDelete() {
00307 if (tag<0) {
00308 if (tag<-1) {
00309 REPORT store=0; delete this; return;
00310 }
00311 else { REPORT return; }
00312 }
00313 if (tag==1) {
00314 if (store) {
00315 REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store)
00316 delete [] store;
00317 }
00318 store=0; tag=-1; return;
00319 }
00320 if (tag==0) { REPORT delete this; return; }
00321 REPORT tag--; return;
00322 }
00323
00324 static void BlockCopy(int n, Real* from, Real* to) {
00325 REPORT
00326 int i = (n >> 3);
00327 while (i--) {
00328 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
00329 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
00330 }
00331 i = n & 7; while (i--) *to++ = *from++;
00332 }
00333
00334 bool GeneralMatrix::reuse() {
00335 if (tag<-1) {
00336 if (storage>0) {
00337 REPORT
00338 Real* s = new Real [storage]; MatrixErrorNoSpace(s);
00339 MONITOR_REAL_NEW("Make (reuse)",storage,s)
00340 BlockCopy(storage, store, s); store=s;
00341 }
00342 else store = 0;
00343 tag=0; return true;
00344 }
00345 if (tag<0) { REPORT return false; }
00346 if (tag<=1) { REPORT return true; }
00347 REPORT tag--; return false;
00348 }
00349
00350 Real* GeneralMatrix::GetStore() {
00351 if (tag<0 || tag>1) {
00352 Real* s;
00353 if (storage) {
00354 s = new Real [storage]; MatrixErrorNoSpace(s);
00355 MONITOR_REAL_NEW("Make (GetStore)",storage,s)
00356 BlockCopy(storage, store, s);
00357 }
00358 else s = 0;
00359 if (tag>1) { REPORT tag--; }
00360 else if (tag < -1) {
00361 REPORT store=0; delete this;
00362 }
00363 else { REPORT }
00364 return s;
00365 }
00366 Real* s=store; store=0;
00367 if (tag==0) { REPORT delete this; }
00368 else { REPORT tag=-1; }
00369 return s;
00370 }
00371
00372 void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx) {
00373 REPORT tag=-1; nrows=gmx->Nrows(); ncols=gmx->Ncols();
00374 storage=gmx->storage; SetParameters(gmx);
00375 store=((GeneralMatrix*)gmx)->GetStore();
00376 }
00377
00378 GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt) {
00379
00380
00381 if (!mt) {
00382 if (tag == -1) { REPORT gmx->tag = -2; gmx->store = store; }
00383 else { REPORT gmx->tag = 0; gmx->store = GetStore(); }
00384 }
00385 else if (Compare(gmx->Type(),mt))
00386 { REPORT gmx->tag = 0; gmx->store = GetStore(); }
00387 else {
00388 REPORT gmx->tag = -2; gmx->store = store;
00389 gmx = gmx->Evaluate(mt); gmx->tag = 0; tDelete();
00390 }
00391
00392 return gmx;
00393 }
00394
00395 void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt) {
00396
00397
00398
00399
00400 #ifdef DO_SEARCH
00401 int counter=X.search(this);
00402 if (counter==0) {
00403 REPORT
00404 if (store) {
00405 MONITOR_REAL_DELETE("Free (operator=)",storage,store)
00406 REPORT delete [] store; storage=0;
00407 }
00408 }
00409 else { REPORT Release(counter); }
00410 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
00411 if (gmx!=this) { REPORT GetMatrix(gmx); }
00412 else { REPORT }
00413 Protect();
00414 #else
00415 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
00416 if (gmx!=this) {
00417 REPORT
00418 if (store) {
00419 MONITOR_REAL_DELETE("Free (operator=)",storage,store)
00420 REPORT delete [] store; storage=0;
00421 }
00422 GetMatrix(gmx);
00423 }
00424 else { REPORT }
00425 Protect();
00426 #endif
00427 }
00428
00429 void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt) {
00430
00431
00432
00433
00434 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
00435 if (gmx!=this) {
00436 REPORT GetMatrix(gmx);
00437 }
00438 else { REPORT }
00439 Protect();
00440 }
00441
00442 void GeneralMatrix::Inject(const GeneralMatrix& X) {
00443
00444 REPORT
00445 Tracer tr("Inject");
00446 if (nrows != X.nrows || ncols != X.ncols)
00447 Throw(IncompatibleDimensionsException());
00448 MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
00449 MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart);
00450 int i=nrows;
00451 while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); }
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 bool MatrixConversionCheck::DoCheck;
00463
00464 void MatrixConversionCheck::DataLoss()
00465 { if (DoCheck) Throw(ProgramException("Illegal Conversion")); }
00466
00467 bool Compare(const MatrixType& source, MatrixType& destination) {
00468 if (!destination) { destination=source; return true; }
00469 if (destination==source) return true;
00470 if (MatrixConversionCheck::IsOn() && !(destination>=source))
00471 Throw(ProgramException("Illegal Conversion", source, destination));
00472 return false;
00473 }
00474
00475
00476
00477 GeneralMatrix* Matrix::Image() const {
00478 REPORT
00479 GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm);
00480 return gm;
00481 }
00482
00483 GeneralMatrix* SymmetricMatrix::Image() const {
00484 REPORT
00485 GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm);
00486 return gm;
00487 }
00488
00489 GeneralMatrix* UpperTriangularMatrix::Image() const {
00490 REPORT
00491 GeneralMatrix* gm = new UpperTriangularMatrix(*this);
00492 MatrixErrorNoSpace(gm); return gm;
00493 }
00494
00495 GeneralMatrix* LowerTriangularMatrix::Image() const {
00496 REPORT
00497 GeneralMatrix* gm = new LowerTriangularMatrix(*this);
00498 MatrixErrorNoSpace(gm); return gm;
00499 }
00500
00501 GeneralMatrix* DiagonalMatrix::Image() const {
00502 REPORT
00503 GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm);
00504 return gm;
00505 }
00506
00507 GeneralMatrix* RowVector::Image() const {
00508 REPORT
00509 GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm);
00510 return gm;
00511 }
00512
00513 GeneralMatrix* ColumnVector::Image() const {
00514 REPORT
00515 GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm);
00516 return gm;
00517 }
00518
00519 GeneralMatrix* BandMatrix::Image() const {
00520 REPORT
00521 GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm);
00522 return gm;
00523 }
00524
00525 GeneralMatrix* UpperBandMatrix::Image() const {
00526 REPORT
00527 GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm);
00528 return gm;
00529 }
00530
00531 GeneralMatrix* LowerBandMatrix::Image() const {
00532 REPORT
00533 GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm);
00534 return gm;
00535 }
00536
00537 GeneralMatrix* SymmetricBandMatrix::Image() const {
00538 REPORT
00539 GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm);
00540 return gm;
00541 }
00542
00543 GeneralMatrix* nricMatrix::Image() const {
00544 REPORT
00545 GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm);
00546 return gm;
00547 }
00548
00549 GeneralMatrix* GeneralMatrix::Image() const {
00550
00551 Throw(InternalException("Cannot apply Image to this matrix type"));
00552 return 0;
00553 }
00554
00555
00556
00557 void nricMatrix::MakeRowPointer() {
00558 row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer);
00559 Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer;
00560 while (i--) { *rp++ = s; s+=ncols; }
00561 }
00562
00563 void nricMatrix::DeleteRowPointer()
00564 { if (nrows) delete [] row_pointer; }
00565
00566 void GeneralMatrix::CheckStore() const {
00567 if (!store)
00568 Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
00569 }
00570
00571
00572
00573 void GeneralMatrix::CleanUp() {
00574
00575 REPORT
00576 if (store && storage) {
00577 MONITOR_REAL_DELETE("Free (CleanUp) ",storage,store)
00578 REPORT delete [] store;
00579 }
00580 store=0; storage=0; nrows=0; ncols=0;
00581 }
00582
00583 void nricMatrix::CleanUp()
00584 { DeleteRowPointer(); GeneralMatrix::CleanUp(); }
00585
00586 void RowVector::CleanUp()
00587 { GeneralMatrix::CleanUp(); nrows=1; }
00588
00589 void ColumnVector::CleanUp()
00590 { GeneralMatrix::CleanUp(); ncols=1; }
00591
00592 void CroutMatrix::CleanUp() {
00593 if (nrows) delete [] indx;
00594 GeneralMatrix::CleanUp();
00595 }
00596
00597 void BandLUMatrix::CleanUp() {
00598 if (nrows) delete [] indx;
00599 if (storage2) delete [] store2;
00600 GeneralMatrix::CleanUp();
00601 }
00602
00603 #ifdef use_namespace
00604 }
00605 #endif