newmat4.cc
Go to the documentation of this file.
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; CleanUp(); 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)
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 { REPORT store = 0; CleanUp(); }
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 CleanUp(); 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    if (nrows > 0)
00797    {
00798       row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer);
00799       Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer;
00800       if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols; }
00801    }
00802    else row_pointer = 0;
00803 }
00804 
00805 void nricMatrix::DeleteRowPointer()
00806 { if (nrows) delete [] row_pointer; }
00807 
00808 void GeneralMatrix::CheckStore() const
00809 {
00810    if (!store)
00811       Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
00812 }
00813 
00814 
00815 // *************************** CleanUp routines *****************************/
00816 
00817 void GeneralMatrix::CleanUp()
00818 {
00819    // set matrix dimensions to zero, delete storage
00820    REPORT
00821    if (store && storage)
00822    {
00823       MONITOR_REAL_DELETE("Free (CleanUp)    ",storage,store)
00824       REPORT delete [] store;
00825    }
00826    store=0; storage=0; nrows=0; ncols=0;
00827 }
00828 
00829 void nricMatrix::CleanUp()
00830 { DeleteRowPointer(); GeneralMatrix::CleanUp(); }
00831 
00832 void RowVector::CleanUp()
00833 { GeneralMatrix::CleanUp(); nrows=1; }
00834 
00835 void ColumnVector::CleanUp()
00836 { GeneralMatrix::CleanUp(); ncols=1; }
00837 
00838 void CroutMatrix::CleanUp()
00839 {
00840    if (nrows) delete [] indx;
00841    GeneralMatrix::CleanUp();
00842 }
00843 
00844 void BandLUMatrix::CleanUp()
00845 {
00846    if (nrows) delete [] indx;
00847    if (storage2) delete [] store2;
00848    GeneralMatrix::CleanUp();
00849 }
00850 
00851 // ************************ simple integer array class ***********************
00852 
00853 // construct a new array of length xn. Check that xn is non-negative and
00854 // that space is available
00855 
00856 SimpleIntArray::SimpleIntArray(int xn) : n(xn)
00857 {
00858    if (n < 0) Throw(Logic_error("invalid array length"));
00859    else if (n == 0) { REPORT  a = 0; }
00860    else { REPORT  a = new int [n]; if (!a) Throw(Bad_alloc()); }
00861 }
00862 
00863 // destroy an array - return its space to memory
00864 
00865 SimpleIntArray::~SimpleIntArray() { REPORT  if (a) delete [] a; }
00866 
00867 // access an element of an array; return a "reference" so elements
00868 // can be modified.
00869 // check index is within range
00870 // in this array class the index runs from 0 to n-1
00871 
00872 int& SimpleIntArray::operator[](int i)
00873 {
00874    REPORT
00875    if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
00876    return a[i];
00877 }
00878 
00879 // same thing again but for arrays declared constant so we can't
00880 // modify its elements
00881 
00882 int SimpleIntArray::operator[](int i) const
00883 {
00884    REPORT
00885    if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
00886    return a[i];
00887 }
00888 
00889 // set all the elements equal to a given value
00890 
00891 void SimpleIntArray::operator=(int ai)
00892    { REPORT  for (int i = 0; i < n; i++) a[i] = ai; }
00893 
00894 // set the elements equal to those of another array.
00895 // check the arrays are of the same length
00896 
00897 void SimpleIntArray::operator=(const SimpleIntArray& b)
00898 {
00899    REPORT
00900    if (b.n != n) Throw(Logic_error("array lengths differ in copy"));
00901    for (int i = 0; i < n; i++) a[i] = b.a[i];
00902 }
00903 
00904 // construct a new array equal to an existing array
00905 // check that space is available
00906 
00907 SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : n(b.n)
00908 {
00909    if (n == 0) { REPORT  a = 0; }
00910    else
00911    {
00912       REPORT
00913       a = new int [n]; if (!a) Throw(Bad_alloc());
00914       for (int i = 0; i < n; i++) a[i] = b.a[i];
00915    }
00916 }
00917 
00918 // change the size of an array; optionally copy data from old array to
00919 // new array
00920 
00921 void SimpleIntArray::ReSize(int n1, bool keep)
00922 {
00923    if (n1 == n) { REPORT  return; }
00924    else if (n1 == 0) { REPORT  n = 0; delete [] a; a = 0; }
00925    else if (n == 0)
00926       { REPORT  a = new int [n1]; if (!a) Throw(Bad_alloc()); n = n1; }
00927    else
00928    {
00929       int* a1 = a;
00930       if (keep)
00931       {
00932          REPORT
00933          a = new int [n1]; if (!a) Throw(Bad_alloc());
00934          if (n > n1) n = n1;
00935          for (int i = 0; i < n; i++) a[i] = a1[i];
00936          n = n1; delete [] a1;
00937       }
00938       else
00939       {
00940          REPORT  n = n1; delete [] a1;
00941          a = new int [n]; if (!a) Throw(Bad_alloc());
00942       }
00943    }
00944 }
00945 
00946 
00947 #ifdef use_namespace
00948 }
00949 #endif
00950 


rl_agent
Author(s): Todd Hester
autogenerated on Thu Jun 6 2019 22:00:13