MOOS 0.2375
|
00001 //$$ newmat4.cpp Constructors, ReSize, basic utilities 00002 00003 // Copyright (C) 1991,2,3,4,8,9: R B Davies 00004 00005 #include "include.h" 00006 00007 #include "newmat.h" 00008 #include "newmatrc.h" 00009 00010 #ifdef use_namespace 00011 namespace NEWMAT { 00012 #endif 00013 00014 00015 00016 #ifdef DO_REPORT 00017 #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; } 00018 #else 00019 #define REPORT {} 00020 #endif 00021 00022 00023 #define DO_SEARCH // search for LHS of = in RHS 00024 00025 // ************************* general utilities *************************/ 00026 00027 static int tristore(int n) // elements in triangular matrix 00028 { return (n*(n+1))/2; } 00029 00030 00031 // **************************** constructors ***************************/ 00032 00033 GeneralMatrix::GeneralMatrix() 00034 { store=0; storage=0; nrows=0; ncols=0; tag=-1; } 00035 00036 GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s) 00037 { 00038 REPORT 00039 storage=s.Value(); tag=-1; 00040 if (storage) 00041 { 00042 store = new Real [storage]; MatrixErrorNoSpace(store); 00043 MONITOR_REAL_NEW("Make (GenMatrix)",storage,store) 00044 } 00045 else store = 0; 00046 } 00047 00048 Matrix::Matrix(int m, int n) : GeneralMatrix(m*n) 00049 { REPORT nrows=m; ncols=n; } 00050 00051 SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n) 00052 : GeneralMatrix(tristore(n.Value())) 00053 { REPORT nrows=n.Value(); ncols=n.Value(); } 00054 00055 UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n) 00056 : GeneralMatrix(tristore(n.Value())) 00057 { REPORT nrows=n.Value(); ncols=n.Value(); } 00058 00059 LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n) 00060 : GeneralMatrix(tristore(n.Value())) 00061 { REPORT nrows=n.Value(); ncols=n.Value(); } 00062 00063 DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m) 00064 { REPORT nrows=m.Value(); ncols=m.Value(); } 00065 00066 Matrix::Matrix(const BaseMatrix& M) 00067 { 00068 REPORT // CheckConversion(M); 00069 // MatrixConversionCheck mcc; 00070 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt); 00071 GetMatrix(gmx); 00072 } 00073 00074 RowVector::RowVector(const BaseMatrix& M) : Matrix(M) 00075 { 00076 if (nrows!=1) 00077 { 00078 Tracer tr("RowVector"); 00079 Throw(VectorException(*this)); 00080 } 00081 } 00082 00083 ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M) 00084 { 00085 if (ncols!=1) 00086 { 00087 Tracer tr("ColumnVector"); 00088 Throw(VectorException(*this)); 00089 } 00090 } 00091 00092 SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M) 00093 { 00094 REPORT // CheckConversion(M); 00095 // MatrixConversionCheck mcc; 00096 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm); 00097 GetMatrix(gmx); 00098 } 00099 00100 UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M) 00101 { 00102 REPORT // CheckConversion(M); 00103 // MatrixConversionCheck mcc; 00104 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT); 00105 GetMatrix(gmx); 00106 } 00107 00108 LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M) 00109 { 00110 REPORT // CheckConversion(M); 00111 // MatrixConversionCheck mcc; 00112 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT); 00113 GetMatrix(gmx); 00114 } 00115 00116 DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M) 00117 { 00118 REPORT //CheckConversion(M); 00119 // MatrixConversionCheck mcc; 00120 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg); 00121 GetMatrix(gmx); 00122 } 00123 00124 IdentityMatrix::IdentityMatrix(const BaseMatrix& M) 00125 { 00126 REPORT //CheckConversion(M); 00127 // MatrixConversionCheck mcc; 00128 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id); 00129 GetMatrix(gmx); 00130 } 00131 00132 GeneralMatrix::~GeneralMatrix() 00133 { 00134 if (store) 00135 { 00136 MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store) 00137 delete [] store; 00138 } 00139 } 00140 00141 CroutMatrix::CroutMatrix(const BaseMatrix& m) 00142 { 00143 REPORT 00144 Tracer tr("CroutMatrix"); 00145 indx = 0; // in case of exception at next line 00146 GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::Rt); 00147 GetMatrix(gm); 00148 if (nrows!=ncols) { CleanUp(); Throw(NotSquareException(*gm)); } 00149 d=true; sing=false; 00150 indx=new int [nrows]; MatrixErrorNoSpace(indx); 00151 MONITOR_INT_NEW("Index (CroutMat)",nrows,indx) 00152 ludcmp(); 00153 } 00154 00155 CroutMatrix::~CroutMatrix() 00156 { 00157 MONITOR_INT_DELETE("Index (CroutMat)",nrows,indx) 00158 delete [] indx; 00159 } 00160 00161 //ReturnMatrixX::ReturnMatrixX(GeneralMatrix& gmx) 00162 //{ 00163 // REPORT 00164 // gm = gmx.Image(); gm->ReleaseAndDelete(); 00165 //} 00166 00167 #ifndef TEMPS_DESTROYED_QUICKLY_R 00168 00169 GeneralMatrix::operator ReturnMatrixX() const 00170 { 00171 REPORT 00172 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); 00173 return ReturnMatrixX(gm); 00174 } 00175 00176 #else 00177 00178 GeneralMatrix::operator ReturnMatrixX&() const 00179 { 00180 REPORT 00181 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); 00182 ReturnMatrixX* x = new ReturnMatrixX(gm); 00183 MatrixErrorNoSpace(x); return *x; 00184 } 00185 00186 #endif 00187 00188 #ifndef TEMPS_DESTROYED_QUICKLY_R 00189 00190 ReturnMatrixX GeneralMatrix::ForReturn() const 00191 { 00192 REPORT 00193 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); 00194 return ReturnMatrixX(gm); 00195 } 00196 00197 #else 00198 00199 ReturnMatrixX& GeneralMatrix::ForReturn() const 00200 { 00201 REPORT 00202 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); 00203 ReturnMatrixX* x = new ReturnMatrixX(gm); 00204 MatrixErrorNoSpace(x); return *x; 00205 } 00206 00207 #endif 00208 00209 // ************************** ReSize matrices ***************************/ 00210 00211 void GeneralMatrix::ReSize(int nr, int nc, int s) 00212 { 00213 REPORT 00214 if (store) 00215 { 00216 MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store) 00217 delete [] store; 00218 } 00219 storage=s; nrows=nr; ncols=nc; tag=-1; 00220 if (s) 00221 { 00222 store = new Real [storage]; MatrixErrorNoSpace(store); 00223 MONITOR_REAL_NEW("Make (ReDimensi)",storage,store) 00224 } 00225 else store = 0; 00226 } 00227 00228 void Matrix::ReSize(int nr, int nc) 00229 { REPORT GeneralMatrix::ReSize(nr,nc,nr*nc); } 00230 00231 void SymmetricMatrix::ReSize(int nr) 00232 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } 00233 00234 void UpperTriangularMatrix::ReSize(int nr) 00235 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } 00236 00237 void LowerTriangularMatrix::ReSize(int nr) 00238 { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } 00239 00240 void DiagonalMatrix::ReSize(int nr) 00241 { REPORT GeneralMatrix::ReSize(nr,nr,nr); } 00242 00243 void RowVector::ReSize(int nc) 00244 { REPORT GeneralMatrix::ReSize(1,nc,nc); } 00245 00246 void ColumnVector::ReSize(int nr) 00247 { REPORT GeneralMatrix::ReSize(nr,1,nr); } 00248 00249 void RowVector::ReSize(int nr, int nc) 00250 { 00251 Tracer tr("RowVector::ReSize"); 00252 if (nr != 1) Throw(VectorException(*this)); 00253 REPORT GeneralMatrix::ReSize(1,nc,nc); 00254 } 00255 00256 void ColumnVector::ReSize(int nr, int nc) 00257 { 00258 Tracer tr("ColumnVector::ReSize"); 00259 if (nc != 1) Throw(VectorException(*this)); 00260 REPORT GeneralMatrix::ReSize(nr,1,nr); 00261 } 00262 00263 void IdentityMatrix::ReSize(int nr) 00264 { REPORT GeneralMatrix::ReSize(nr,nr,1); *store = 1; } 00265 00266 00267 void Matrix::ReSize(const GeneralMatrix& A) 00268 { REPORT ReSize(A.Nrows(), A.Ncols()); } 00269 00270 void nricMatrix::ReSize(const GeneralMatrix& A) 00271 { REPORT ReSize(A.Nrows(), A.Ncols()); } 00272 00273 void ColumnVector::ReSize(const GeneralMatrix& A) 00274 { REPORT ReSize(A.Nrows(), A.Ncols()); } 00275 00276 void RowVector::ReSize(const GeneralMatrix& A) 00277 { REPORT ReSize(A.Nrows(), A.Ncols()); } 00278 00279 void SymmetricMatrix::ReSize(const GeneralMatrix& A) 00280 { 00281 REPORT 00282 int n = A.Nrows(); 00283 if (n != A.Ncols()) 00284 { 00285 Tracer tr("SymmetricMatrix::ReSize(GM)"); 00286 Throw(NotSquareException(*this)); 00287 } 00288 ReSize(n); 00289 } 00290 00291 void DiagonalMatrix::ReSize(const GeneralMatrix& A) 00292 { 00293 REPORT 00294 int n = A.Nrows(); 00295 if (n != A.Ncols()) 00296 { 00297 Tracer tr("DiagonalMatrix::ReSize(GM)"); 00298 Throw(NotSquareException(*this)); 00299 } 00300 ReSize(n); 00301 } 00302 00303 void UpperTriangularMatrix::ReSize(const GeneralMatrix& A) 00304 { 00305 REPORT 00306 int n = A.Nrows(); 00307 if (n != A.Ncols()) 00308 { 00309 Tracer tr("UpperTriangularMatrix::ReSize(GM)"); 00310 Throw(NotSquareException(*this)); 00311 } 00312 ReSize(n); 00313 } 00314 00315 void LowerTriangularMatrix::ReSize(const GeneralMatrix& A) 00316 { 00317 REPORT 00318 int n = A.Nrows(); 00319 if (n != A.Ncols()) 00320 { 00321 Tracer tr("LowerTriangularMatrix::ReSize(GM)"); 00322 Throw(NotSquareException(*this)); 00323 } 00324 ReSize(n); 00325 } 00326 00327 void IdentityMatrix::ReSize(const GeneralMatrix& A) 00328 { 00329 REPORT 00330 int n = A.Nrows(); 00331 if (n != A.Ncols()) 00332 { 00333 Tracer tr("IdentityMatrix::ReSize(GM)"); 00334 Throw(NotSquareException(*this)); 00335 } 00336 ReSize(n); 00337 } 00338 00339 void GeneralMatrix::ReSize(const GeneralMatrix&) 00340 { 00341 REPORT 00342 Tracer tr("GeneralMatrix::ReSize(GM)"); 00343 Throw(NotDefinedException("ReSize", "this type of matrix")); 00344 } 00345 00346 void GeneralMatrix::ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix&) 00347 { REPORT ReSize(A); } 00348 00349 void GeneralMatrix::ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix&) 00350 { REPORT ReSize(A); } 00351 00352 00353 // ************************* SameStorageType ******************************/ 00354 00355 // SameStorageType checks A and B have same storage type including bandwidth 00356 // It does not check same dimensions since we assume this is already done 00357 00358 bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const 00359 { 00360 REPORT 00361 return Type() == A.Type(); 00362 } 00363 00364 00365 // ******************* manipulate types, storage **************************/ 00366 00367 int GeneralMatrix::search(const BaseMatrix* s) const 00368 { REPORT return (s==this) ? 1 : 0; } 00369 00370 int GenericMatrix::search(const BaseMatrix* s) const 00371 { REPORT return gm->search(s); } 00372 00373 int MultipliedMatrix::search(const BaseMatrix* s) const 00374 { REPORT return bm1->search(s) + bm2->search(s); } 00375 00376 int ShiftedMatrix::search(const BaseMatrix* s) const 00377 { REPORT return bm->search(s); } 00378 00379 int NegatedMatrix::search(const BaseMatrix* s) const 00380 { REPORT return bm->search(s); } 00381 00382 int ReturnMatrixX::search(const BaseMatrix* s) const 00383 { REPORT return (s==gm) ? 1 : 0; } 00384 00385 MatrixType Matrix::Type() const { return MatrixType::Rt; } 00386 MatrixType SymmetricMatrix::Type() const { return MatrixType::Sm; } 00387 MatrixType UpperTriangularMatrix::Type() const { return MatrixType::UT; } 00388 MatrixType LowerTriangularMatrix::Type() const { return MatrixType::LT; } 00389 MatrixType DiagonalMatrix::Type() const { return MatrixType::Dg; } 00390 MatrixType RowVector::Type() const { return MatrixType::RV; } 00391 MatrixType ColumnVector::Type() const { return MatrixType::CV; } 00392 MatrixType CroutMatrix::Type() const { return MatrixType::Ct; } 00393 MatrixType BandMatrix::Type() const { return MatrixType::BM; } 00394 MatrixType UpperBandMatrix::Type() const { return MatrixType::UB; } 00395 MatrixType LowerBandMatrix::Type() const { return MatrixType::LB; } 00396 MatrixType SymmetricBandMatrix::Type() const { return MatrixType::SB; } 00397 00398 MatrixType IdentityMatrix::Type() const { return MatrixType::Id; } 00399 00400 00401 00402 MatrixBandWidth BaseMatrix::BandWidth() const { REPORT return -1; } 00403 MatrixBandWidth DiagonalMatrix::BandWidth() const { REPORT return 0; } 00404 MatrixBandWidth IdentityMatrix::BandWidth() const { REPORT return 0; } 00405 00406 MatrixBandWidth UpperTriangularMatrix::BandWidth() const 00407 { REPORT return MatrixBandWidth(0,-1); } 00408 00409 MatrixBandWidth LowerTriangularMatrix::BandWidth() const 00410 { REPORT return MatrixBandWidth(-1,0); } 00411 00412 MatrixBandWidth BandMatrix::BandWidth() const 00413 { REPORT return MatrixBandWidth(lower,upper); } 00414 00415 MatrixBandWidth GenericMatrix::BandWidth()const 00416 { REPORT return gm->BandWidth(); } 00417 00418 MatrixBandWidth AddedMatrix::BandWidth() const 00419 { REPORT return gm1->BandWidth() + gm2->BandWidth(); } 00420 00421 MatrixBandWidth SPMatrix::BandWidth() const 00422 { REPORT return gm1->BandWidth().minimum(gm2->BandWidth()); } 00423 00424 MatrixBandWidth KPMatrix::BandWidth() const 00425 { 00426 int lower, upper; 00427 MatrixBandWidth bw1 = gm1->BandWidth(), bw2 = gm2->BandWidth(); 00428 if (bw1.Lower() < 0) 00429 { 00430 if (bw2.Lower() < 0) { REPORT lower = -1; } 00431 else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); } 00432 } 00433 else 00434 { 00435 if (bw2.Lower() < 0) 00436 { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; } 00437 else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); } 00438 } 00439 if (bw1.Upper() < 0) 00440 { 00441 if (bw2.Upper() < 0) { REPORT upper = -1; } 00442 else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); } 00443 } 00444 else 00445 { 00446 if (bw2.Upper() < 0) 00447 { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; } 00448 else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); } 00449 } 00450 return MatrixBandWidth(lower, upper); 00451 } 00452 00453 MatrixBandWidth MultipliedMatrix::BandWidth() const 00454 { REPORT return gm1->BandWidth() * gm2->BandWidth(); } 00455 00456 MatrixBandWidth ConcatenatedMatrix::BandWidth() const { REPORT return -1; } 00457 00458 MatrixBandWidth SolvedMatrix::BandWidth() const 00459 { 00460 if (+gm1->Type() & MatrixType::Diagonal) 00461 { REPORT return gm2->BandWidth(); } 00462 else { REPORT return -1; } 00463 } 00464 00465 MatrixBandWidth ScaledMatrix::BandWidth() const 00466 { REPORT return gm->BandWidth(); } 00467 00468 MatrixBandWidth NegatedMatrix::BandWidth() const 00469 { REPORT return gm->BandWidth(); } 00470 00471 MatrixBandWidth TransposedMatrix::BandWidth() const 00472 { REPORT return gm->BandWidth().t(); } 00473 00474 MatrixBandWidth InvertedMatrix::BandWidth() const 00475 { 00476 if (+gm->Type() & MatrixType::Diagonal) 00477 { REPORT return MatrixBandWidth(0,0); } 00478 else { REPORT return -1; } 00479 } 00480 00481 MatrixBandWidth RowedMatrix::BandWidth() const { REPORT return -1; } 00482 MatrixBandWidth ColedMatrix::BandWidth() const { REPORT return -1; } 00483 MatrixBandWidth DiagedMatrix::BandWidth() const { REPORT return 0; } 00484 MatrixBandWidth MatedMatrix::BandWidth() const { REPORT return -1; } 00485 MatrixBandWidth ReturnMatrixX::BandWidth() const 00486 { REPORT return gm->BandWidth(); } 00487 00488 MatrixBandWidth GetSubMatrix::BandWidth() const 00489 { 00490 00491 if (row_skip==col_skip && row_number==col_number) 00492 { REPORT return gm->BandWidth(); } 00493 else { REPORT return MatrixBandWidth(-1); } 00494 } 00495 00496 // ********************** the memory managment tools **********************/ 00497 00498 // Rules regarding tDelete, reuse, GetStore 00499 // All matrices processed during expression evaluation must be subject 00500 // to exactly one of reuse(), tDelete(), GetStore() or BorrowStore(). 00501 // If reuse returns true the matrix must be reused. 00502 // GetMatrix(gm) always calls gm->GetStore() 00503 // gm->Evaluate obeys rules 00504 // bm->Evaluate obeys rules for matrices in bm structure 00505 00506 void GeneralMatrix::tDelete() 00507 { 00508 if (tag<0) 00509 { 00510 if (tag<-1) { REPORT store=0; delete this; return; } // borrowed 00511 else { REPORT return; } 00512 } 00513 if (tag==1) 00514 { 00515 if (store) 00516 { 00517 REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store) 00518 delete [] store; 00519 } 00520 store=0; tag=-1; return; 00521 } 00522 if (tag==0) { REPORT delete this; return; } 00523 REPORT tag--; return; 00524 } 00525 00526 static void BlockCopy(int n, Real* from, Real* to) 00527 { 00528 REPORT 00529 int i = (n >> 3); 00530 while (i--) 00531 { 00532 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; 00533 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; 00534 } 00535 i = n & 7; while (i--) *to++ = *from++; 00536 } 00537 00538 bool GeneralMatrix::reuse() 00539 { 00540 if (tag<-1) 00541 { 00542 if (storage>0) 00543 { 00544 REPORT 00545 Real* s = new Real [storage]; MatrixErrorNoSpace(s); 00546 MONITOR_REAL_NEW("Make (reuse)",storage,s) 00547 BlockCopy(storage, store, s); store=s; 00548 } 00549 else store = 0; 00550 tag=0; return true; 00551 } 00552 if (tag<0) { REPORT return false; } 00553 if (tag<=1) { REPORT return true; } 00554 REPORT tag--; return false; 00555 } 00556 00557 Real* GeneralMatrix::GetStore() 00558 { 00559 if (tag<0 || tag>1) 00560 { 00561 Real* s; 00562 if (storage) 00563 { 00564 s = new Real [storage]; MatrixErrorNoSpace(s); 00565 MONITOR_REAL_NEW("Make (GetStore)",storage,s) 00566 BlockCopy(storage, store, s); 00567 } 00568 else s = 0; 00569 if (tag>1) { REPORT tag--; } 00570 else if (tag < -1) { REPORT store=0; delete this; } // borrowed store 00571 else { REPORT } 00572 return s; 00573 } 00574 Real* s=store; store=0; 00575 if (tag==0) { REPORT delete this; } 00576 else { REPORT tag=-1; } 00577 return s; 00578 } 00579 00580 void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx) 00581 { 00582 REPORT tag=-1; nrows=gmx->Nrows(); ncols=gmx->Ncols(); 00583 storage=gmx->storage; SetParameters(gmx); 00584 store=((GeneralMatrix*)gmx)->GetStore(); 00585 } 00586 00587 GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt) 00588 // Copy storage of *this to storage of *gmx. Then convert to type mt. 00589 // If mt == 0 just let *gmx point to storage of *this if tag==-1. 00590 { 00591 if (!mt) 00592 { 00593 if (tag == -1) { REPORT gmx->tag = -2; gmx->store = store; } 00594 else { REPORT gmx->tag = 0; gmx->store = GetStore(); } 00595 } 00596 else if (Compare(gmx->Type(),mt)) 00597 { REPORT gmx->tag = 0; gmx->store = GetStore(); } 00598 else 00599 { 00600 REPORT gmx->tag = -2; gmx->store = store; 00601 gmx = gmx->Evaluate(mt); gmx->tag = 0; tDelete(); 00602 } 00603 00604 return gmx; 00605 } 00606 00607 void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt) 00608 // Count number of references to this in X. 00609 // If zero delete storage in this; 00610 // otherwise tag this to show when storage can be deleted 00611 // evaluate X and copy to this 00612 { 00613 #ifdef DO_SEARCH 00614 int counter=X.search(this); 00615 if (counter==0) 00616 { 00617 REPORT 00618 if (store) 00619 { 00620 MONITOR_REAL_DELETE("Free (operator=)",storage,store) 00621 REPORT delete [] store; storage=0; store = 0; 00622 } 00623 } 00624 else { REPORT Release(counter); } 00625 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); 00626 if (gmx!=this) { REPORT GetMatrix(gmx); } 00627 else { REPORT } 00628 Protect(); 00629 #else 00630 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); 00631 if (gmx!=this) 00632 { 00633 REPORT 00634 if (store) 00635 { 00636 MONITOR_REAL_DELETE("Free (operator=)",storage,store) 00637 REPORT delete [] store; storage=0; store = 0; 00638 } 00639 GetMatrix(gmx); 00640 } 00641 else { REPORT } 00642 Protect(); 00643 #endif 00644 } 00645 00646 // version to work with operator<< 00647 void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok) 00648 { 00649 REPORT 00650 if (ldok) mt.SetDataLossOK(); 00651 Eq(X, mt); 00652 } 00653 00654 void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt) 00655 // a cut down version of Eq for use with += etc. 00656 // we know BaseMatrix points to two GeneralMatrix objects, 00657 // the first being this (may be the same). 00658 // we know tag has been set correctly in each. 00659 { 00660 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); 00661 if (gmx!=this) { REPORT GetMatrix(gmx); } // simplify GetMatrix ? 00662 else { REPORT } 00663 Protect(); 00664 } 00665 00666 void GeneralMatrix::Inject(const GeneralMatrix& X) 00667 // copy stored values of X; otherwise leave els of *this unchanged 00668 { 00669 REPORT 00670 Tracer tr("Inject"); 00671 if (nrows != X.nrows || ncols != X.ncols) 00672 Throw(IncompatibleDimensionsException()); 00673 MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry); 00674 MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart); 00675 int i=nrows; 00676 while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); } 00677 } 00678 00679 // ************* checking for data loss during conversion *******************/ 00680 00681 bool Compare(const MatrixType& source, MatrixType& destination) 00682 { 00683 if (!destination) { destination=source; return true; } 00684 if (destination==source) return true; 00685 if (!destination.DataLossOK && !(destination>=source)) 00686 Throw(ProgramException("Illegal Conversion", source, destination)); 00687 return false; 00688 } 00689 00690 // ************* Make a copy of a matrix on the heap *********************/ 00691 00692 GeneralMatrix* Matrix::Image() const 00693 { 00694 REPORT 00695 GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm); 00696 return gm; 00697 } 00698 00699 GeneralMatrix* SymmetricMatrix::Image() const 00700 { 00701 REPORT 00702 GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm); 00703 return gm; 00704 } 00705 00706 GeneralMatrix* UpperTriangularMatrix::Image() const 00707 { 00708 REPORT 00709 GeneralMatrix* gm = new UpperTriangularMatrix(*this); 00710 MatrixErrorNoSpace(gm); return gm; 00711 } 00712 00713 GeneralMatrix* LowerTriangularMatrix::Image() const 00714 { 00715 REPORT 00716 GeneralMatrix* gm = new LowerTriangularMatrix(*this); 00717 MatrixErrorNoSpace(gm); return gm; 00718 } 00719 00720 GeneralMatrix* DiagonalMatrix::Image() const 00721 { 00722 REPORT 00723 GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm); 00724 return gm; 00725 } 00726 00727 GeneralMatrix* RowVector::Image() const 00728 { 00729 REPORT 00730 GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm); 00731 return gm; 00732 } 00733 00734 GeneralMatrix* ColumnVector::Image() const 00735 { 00736 REPORT 00737 GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm); 00738 return gm; 00739 } 00740 00741 GeneralMatrix* BandMatrix::Image() const 00742 { 00743 REPORT 00744 GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm); 00745 return gm; 00746 } 00747 00748 GeneralMatrix* UpperBandMatrix::Image() const 00749 { 00750 REPORT 00751 GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm); 00752 return gm; 00753 } 00754 00755 GeneralMatrix* LowerBandMatrix::Image() const 00756 { 00757 REPORT 00758 GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm); 00759 return gm; 00760 } 00761 00762 GeneralMatrix* SymmetricBandMatrix::Image() const 00763 { 00764 REPORT 00765 GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm); 00766 return gm; 00767 } 00768 00769 GeneralMatrix* nricMatrix::Image() const 00770 { 00771 REPORT 00772 GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm); 00773 return gm; 00774 } 00775 00776 GeneralMatrix* IdentityMatrix::Image() const 00777 { 00778 REPORT 00779 GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm); 00780 return gm; 00781 } 00782 00783 GeneralMatrix* GeneralMatrix::Image() const 00784 { 00785 bool dummy = true; 00786 if (dummy) // get rid of warning message 00787 Throw(InternalException("Cannot apply Image to this matrix type")); 00788 return 0; 00789 } 00790 00791 00792 // *********************** nricMatrix routines *****************************/ 00793 00794 void nricMatrix::MakeRowPointer() 00795 { 00796 row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer); 00797 Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer; 00798 // while (i--) { *rp++ = s; s+=ncols; } 00799 if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols; } 00800 } 00801 00802 void nricMatrix::DeleteRowPointer() 00803 { if (nrows) delete [] row_pointer; } 00804 00805 void GeneralMatrix::CheckStore() const 00806 { 00807 if (!store) 00808 Throw(ProgramException("NRIC accessing matrix with unset dimensions")); 00809 } 00810 00811 00812 // *************************** CleanUp routines *****************************/ 00813 00814 void GeneralMatrix::CleanUp() 00815 { 00816 // set matrix dimensions to zero, delete storage 00817 REPORT 00818 if (store && storage) 00819 { 00820 MONITOR_REAL_DELETE("Free (CleanUp) ",storage,store) 00821 REPORT delete [] store; 00822 } 00823 store=0; storage=0; nrows=0; ncols=0; 00824 } 00825 00826 void nricMatrix::CleanUp() 00827 { DeleteRowPointer(); GeneralMatrix::CleanUp(); } 00828 00829 void RowVector::CleanUp() 00830 { GeneralMatrix::CleanUp(); nrows=1; } 00831 00832 void ColumnVector::CleanUp() 00833 { GeneralMatrix::CleanUp(); ncols=1; } 00834 00835 void CroutMatrix::CleanUp() 00836 { 00837 if (nrows) delete [] indx; 00838 GeneralMatrix::CleanUp(); 00839 } 00840 00841 void BandLUMatrix::CleanUp() 00842 { 00843 if (nrows) delete [] indx; 00844 if (storage2) delete [] store2; 00845 GeneralMatrix::CleanUp(); 00846 } 00847 00848 // ************************ simple integer array class *********************** 00849 00850 // construct a new array of length xn. Check that xn is non-negative and 00851 // that space is available 00852 00853 SimpleIntArray::SimpleIntArray(int xn) : n(xn) 00854 { 00855 if (n < 0) Throw(Logic_error("invalid array length")); 00856 else if (n == 0) { REPORT a = 0; } 00857 else { REPORT a = new int [n]; if (!a) Throw(Bad_alloc()); } 00858 } 00859 00860 // destroy an array - return its space to memory 00861 00862 SimpleIntArray::~SimpleIntArray() { REPORT if (a) delete [] a; } 00863 00864 // access an element of an array; return a "reference" so elements 00865 // can be modified. 00866 // check index is within range 00867 // in this array class the index runs from 0 to n-1 00868 00869 int& SimpleIntArray::operator[](int i) 00870 { 00871 REPORT 00872 if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); 00873 return a[i]; 00874 } 00875 00876 // same thing again but for arrays declared constant so we can't 00877 // modify its elements 00878 00879 int SimpleIntArray::operator[](int i) const 00880 { 00881 REPORT 00882 if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); 00883 return a[i]; 00884 } 00885 00886 // set all the elements equal to a given value 00887 00888 void SimpleIntArray::operator=(int ai) 00889 { REPORT for (int i = 0; i < n; i++) a[i] = ai; } 00890 00891 // set the elements equal to those of another array. 00892 // check the arrays are of the same length 00893 00894 void SimpleIntArray::operator=(const SimpleIntArray& b) 00895 { 00896 REPORT 00897 if (b.n != n) Throw(Logic_error("array lengths differ in copy")); 00898 for (int i = 0; i < n; i++) a[i] = b.a[i]; 00899 } 00900 00901 // construct a new array equal to an existing array 00902 // check that space is available 00903 00904 SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : n(b.n) 00905 { 00906 if (n == 0) { REPORT a = 0; } 00907 else 00908 { 00909 REPORT 00910 a = new int [n]; if (!a) Throw(Bad_alloc()); 00911 for (int i = 0; i < n; i++) a[i] = b.a[i]; 00912 } 00913 } 00914 00915 // change the size of an array; optionally copy data from old array to 00916 // new array 00917 00918 void SimpleIntArray::ReSize(int n1, bool keep) 00919 { 00920 if (n1 == n) { REPORT return; } 00921 else if (n1 == 0) { REPORT n = 0; delete [] a; a = 0; } 00922 else if (n == 0) 00923 { REPORT a = new int [n1]; if (!a) Throw(Bad_alloc()); n = n1; } 00924 else 00925 { 00926 int* a1 = a; 00927 if (keep) 00928 { 00929 REPORT 00930 a = new int [n1]; if (!a) Throw(Bad_alloc()); 00931 if (n > n1) n = n1; 00932 for (int i = 0; i < n; i++) a[i] = a1[i]; 00933 n = n1; delete [] a1; 00934 } 00935 else 00936 { 00937 REPORT n = n1; delete [] a1; 00938 a = new int [n]; if (!a) Throw(Bad_alloc()); 00939 } 00940 } 00941 } 00942 00943 00944 #ifdef use_namespace 00945 } 00946 #endif 00947