newmat5.cc
Go to the documentation of this file.
00001 //$$ newmat5.cpp         Transpose, evaluate etc
00002 
00003 // Copyright (C) 1991,2,3,4: R B Davies
00004 
00005 //#define WANT_STREAM
00006 
00007 #include "include.h"
00008 
00009 #include "newmat.h"
00010 #include "newmatrc.h"
00011 
00012 #ifdef use_namespace
00013 namespace NEWMAT {
00014 #endif
00015 
00016 
00017 #ifdef DO_REPORT
00018 #define REPORT { static ExeCounter ExeCount(__LINE__,5); ++ExeCount; }
00019 #else
00020 #define REPORT {}
00021 #endif
00022 
00023 
00024 /************************ carry out operations ******************************/
00025 
00026 
00027 GeneralMatrix* GeneralMatrix::Transpose(TransposedMatrix* tm, MatrixType mt)
00028 {
00029    GeneralMatrix* gm1;
00030 
00031    if (Compare(Type().t(),mt))
00032    {
00033       REPORT
00034       gm1 = mt.New(ncols,nrows,tm);
00035       for (int i=0; i<ncols; i++)
00036       {
00037          MatrixRow mr(gm1, StoreOnExit+DirectPart, i);
00038          MatrixCol mc(this, mr.Data(), LoadOnEntry, i);
00039       }
00040    }
00041    else
00042    {
00043       REPORT
00044       gm1 = mt.New(ncols,nrows,tm);
00045       MatrixRow mr(this, LoadOnEntry);
00046       MatrixCol mc(gm1, StoreOnExit+DirectPart);
00047       int i = nrows;
00048       while (i--) { mc.Copy(mr); mr.Next(); mc.Next(); }
00049    }
00050    tDelete(); gm1->ReleaseAndDelete(); return gm1;
00051 }
00052 
00053 GeneralMatrix* SymmetricMatrix::Transpose(TransposedMatrix*, MatrixType mt)
00054 { REPORT  return Evaluate(mt); }
00055 
00056 
00057 GeneralMatrix* DiagonalMatrix::Transpose(TransposedMatrix*, MatrixType mt)
00058 { REPORT return Evaluate(mt); }
00059 
00060 GeneralMatrix* ColumnVector::Transpose(TransposedMatrix*, MatrixType mt)
00061 {
00062    REPORT
00063    GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
00064    gmx->nrows = 1; gmx->ncols = gmx->storage = storage;
00065    return BorrowStore(gmx,mt);
00066 }
00067 
00068 GeneralMatrix* RowVector::Transpose(TransposedMatrix*, MatrixType mt)
00069 {
00070    REPORT
00071    GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
00072    gmx->ncols = 1; gmx->nrows = gmx->storage = storage;
00073    return BorrowStore(gmx,mt);
00074 }
00075 
00076 GeneralMatrix* IdentityMatrix::Transpose(TransposedMatrix*, MatrixType mt)
00077 { REPORT return Evaluate(mt); }
00078 
00079 GeneralMatrix* GeneralMatrix::Evaluate(MatrixType mt)
00080 {
00081    if (Compare(this->Type(),mt)) { REPORT return this; }
00082    REPORT
00083    GeneralMatrix* gmx = mt.New(nrows,ncols,this);
00084    MatrixRow mr(this, LoadOnEntry);
00085    MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00086    int i=nrows;
00087    while (i--) { mrx.Copy(mr); mrx.Next(); mr.Next(); }
00088    tDelete(); gmx->ReleaseAndDelete(); return gmx;
00089 }
00090 
00091 GeneralMatrix* GenericMatrix::Evaluate(MatrixType mt)
00092    { REPORT  return gm->Evaluate(mt); }
00093 
00094 GeneralMatrix* ShiftedMatrix::Evaluate(MatrixType mt)
00095 {
00096    gm=((BaseMatrix*&)bm)->Evaluate();
00097    int nr=gm->Nrows(); int nc=gm->Ncols();
00098    Compare(gm->Type().AddEqualEl(),mt);
00099    if (!(mt==gm->Type()))
00100    {
00101       REPORT
00102       GeneralMatrix* gmx = mt.New(nr,nc,this);
00103       MatrixRow mr(gm, LoadOnEntry);
00104       MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00105       while (nr--) { mrx.Add(mr,f); mrx.Next(); mr.Next(); }
00106       gmx->ReleaseAndDelete(); gm->tDelete();
00107 #ifdef TEMPS_DESTROYED_QUICKLY
00108       delete this;
00109 #endif
00110       return gmx;
00111    }
00112    else if (gm->reuse())
00113    {
00114       REPORT gm->Add(f);
00115 #ifdef TEMPS_DESTROYED_QUICKLY
00116       GeneralMatrix* gmx = gm; delete this; return gmx;
00117 #else
00118       return gm;
00119 #endif
00120    }
00121    else
00122    {
00123       REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
00124       gmy->ReleaseAndDelete(); gmy->Add(gm,f);
00125 #ifdef TEMPS_DESTROYED_QUICKLY
00126       delete this;
00127 #endif
00128       return gmy;
00129    }
00130 }
00131 
00132 GeneralMatrix* NegShiftedMatrix::Evaluate(MatrixType mt)
00133 {
00134    gm=((BaseMatrix*&)bm)->Evaluate();
00135    int nr=gm->Nrows(); int nc=gm->Ncols();
00136    Compare(gm->Type().AddEqualEl(),mt);
00137    if (!(mt==gm->Type()))
00138    {
00139       REPORT
00140       GeneralMatrix* gmx = mt.New(nr,nc,this);
00141       MatrixRow mr(gm, LoadOnEntry);
00142       MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00143       while (nr--) { mrx.NegAdd(mr,f); mrx.Next(); mr.Next(); }
00144       gmx->ReleaseAndDelete(); gm->tDelete();
00145 #ifdef TEMPS_DESTROYED_QUICKLY
00146       delete this;
00147 #endif
00148       return gmx;
00149    }
00150    else if (gm->reuse())
00151    {
00152       REPORT gm->NegAdd(f);
00153 #ifdef TEMPS_DESTROYED_QUICKLY
00154       GeneralMatrix* gmx = gm; delete this; return gmx;
00155 #else
00156       return gm;
00157 #endif
00158    }
00159    else
00160    {
00161       REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
00162       gmy->ReleaseAndDelete(); gmy->NegAdd(gm,f);
00163 #ifdef TEMPS_DESTROYED_QUICKLY
00164       delete this;
00165 #endif
00166       return gmy;
00167    }
00168 }
00169 
00170 GeneralMatrix* ScaledMatrix::Evaluate(MatrixType mt)
00171 {
00172    gm=((BaseMatrix*&)bm)->Evaluate();
00173    int nr=gm->Nrows(); int nc=gm->Ncols();
00174    if (Compare(gm->Type(),mt))
00175    {
00176       if (gm->reuse())
00177       {
00178          REPORT gm->Multiply(f);
00179 #ifdef TEMPS_DESTROYED_QUICKLY
00180          GeneralMatrix* gmx = gm; delete this; return gmx;
00181 #else
00182          return gm;
00183 #endif
00184       }
00185       else
00186       {
00187          REPORT GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
00188          gmx->ReleaseAndDelete(); gmx->Multiply(gm,f);
00189 #ifdef TEMPS_DESTROYED_QUICKLY
00190          delete this;
00191 #endif
00192          return gmx;
00193       }
00194    }
00195    else
00196    {
00197       REPORT
00198       GeneralMatrix* gmx = mt.New(nr,nc,this);
00199       MatrixRow mr(gm, LoadOnEntry);
00200       MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00201       while (nr--) { mrx.Multiply(mr,f); mrx.Next(); mr.Next(); }
00202       gmx->ReleaseAndDelete(); gm->tDelete();
00203 #ifdef TEMPS_DESTROYED_QUICKLY
00204       delete this;
00205 #endif
00206       return gmx;
00207    }
00208 }
00209 
00210 GeneralMatrix* NegatedMatrix::Evaluate(MatrixType mt)
00211 {
00212    gm=((BaseMatrix*&)bm)->Evaluate();
00213    int nr=gm->Nrows(); int nc=gm->Ncols();
00214    if (Compare(gm->Type(),mt))
00215    {
00216       if (gm->reuse())
00217       {
00218          REPORT gm->Negate();
00219 #ifdef TEMPS_DESTROYED_QUICKLY
00220          GeneralMatrix* gmx = gm; delete this; return gmx;
00221 #else
00222          return gm;
00223 #endif
00224       }
00225       else
00226       {
00227          REPORT
00228          GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
00229          gmx->ReleaseAndDelete(); gmx->Negate(gm);
00230 #ifdef TEMPS_DESTROYED_QUICKLY
00231          delete this;
00232 #endif
00233          return gmx;
00234       }
00235    }
00236    else
00237    {
00238       REPORT
00239       GeneralMatrix* gmx = mt.New(nr,nc,this);
00240       MatrixRow mr(gm, LoadOnEntry);
00241       MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00242       while (nr--) { mrx.Negate(mr); mrx.Next(); mr.Next(); }
00243       gmx->ReleaseAndDelete(); gm->tDelete();
00244 #ifdef TEMPS_DESTROYED_QUICKLY
00245       delete this;
00246 #endif
00247       return gmx;
00248    }
00249 }
00250 
00251 GeneralMatrix* ReversedMatrix::Evaluate(MatrixType mt)
00252 {
00253    gm=((BaseMatrix*&)bm)->Evaluate(); GeneralMatrix* gmx;
00254 
00255    if ((gm->Type()).IsBand() && ! (gm->Type()).IsDiagonal())
00256    {
00257       gm->tDelete();
00258 #ifdef TEMPS_DESTROYED_QUICKLY
00259       delete this;
00260 #endif
00261       Throw(NotDefinedException("Reverse", "band matrices"));
00262    }
00263 
00264    if (gm->reuse()) { REPORT gm->ReverseElements(); gmx = gm; }
00265    else
00266    {
00267       REPORT
00268       gmx = gm->Type().New(gm->Nrows(), gm->Ncols(), this);
00269       gmx->ReverseElements(gm); gmx->ReleaseAndDelete();
00270    }
00271 #ifdef TEMPS_DESTROYED_QUICKLY
00272    delete this;
00273 #endif
00274    return gmx->Evaluate(mt); // target matrix is different type?
00275 
00276 }
00277 
00278 GeneralMatrix* TransposedMatrix::Evaluate(MatrixType mt)
00279 {
00280    REPORT
00281    gm=((BaseMatrix*&)bm)->Evaluate();
00282    Compare(gm->Type().t(),mt);
00283    GeneralMatrix* gmx=gm->Transpose(this, mt);
00284 #ifdef TEMPS_DESTROYED_QUICKLY
00285    delete this;
00286 #endif
00287    return gmx;
00288 }
00289 
00290 GeneralMatrix* RowedMatrix::Evaluate(MatrixType mt)
00291 {
00292    gm = ((BaseMatrix*&)bm)->Evaluate();
00293    GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
00294    gmx->nrows = 1; gmx->ncols = gmx->storage = gm->storage;
00295 #ifdef TEMPS_DESTROYED_QUICKLY
00296    GeneralMatrix* gmy = gm; delete this; return gmy->BorrowStore(gmx,mt);
00297 #else
00298    return gm->BorrowStore(gmx,mt);
00299 #endif
00300 }
00301 
00302 GeneralMatrix* ColedMatrix::Evaluate(MatrixType mt)
00303 {
00304    gm = ((BaseMatrix*&)bm)->Evaluate();
00305    GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
00306    gmx->ncols = 1; gmx->nrows = gmx->storage = gm->storage;
00307 #ifdef TEMPS_DESTROYED_QUICKLY
00308    GeneralMatrix* gmy = gm; delete this; return gmy->BorrowStore(gmx,mt);
00309 #else
00310    return gm->BorrowStore(gmx,mt);
00311 #endif
00312 }
00313 
00314 GeneralMatrix* DiagedMatrix::Evaluate(MatrixType mt)
00315 {
00316    gm = ((BaseMatrix*&)bm)->Evaluate();
00317    GeneralMatrix* gmx = new DiagonalMatrix; MatrixErrorNoSpace(gmx);
00318    gmx->nrows = gmx->ncols = gmx->storage = gm->storage;
00319 #ifdef TEMPS_DESTROYED_QUICKLY
00320    GeneralMatrix* gmy = gm; delete this; return gmy->BorrowStore(gmx,mt);
00321 #else
00322    return gm->BorrowStore(gmx,mt);
00323 #endif
00324 }
00325 
00326 GeneralMatrix* MatedMatrix::Evaluate(MatrixType mt)
00327 {
00328    Tracer tr("MatedMatrix::Evaluate");
00329    gm = ((BaseMatrix*&)bm)->Evaluate();
00330    GeneralMatrix* gmx = new Matrix; MatrixErrorNoSpace(gmx);
00331    gmx->nrows = nr; gmx->ncols = nc; gmx->storage = gm->storage;
00332    if (nr*nc != gmx->storage)
00333       Throw(IncompatibleDimensionsException());
00334 #ifdef TEMPS_DESTROYED_QUICKLY
00335    GeneralMatrix* gmy = gm; delete this; return gmy->BorrowStore(gmx,mt);
00336 #else
00337    return gm->BorrowStore(gmx,mt);
00338 #endif
00339 }
00340 
00341 GeneralMatrix* GetSubMatrix::Evaluate(MatrixType mt)
00342 {
00343    REPORT
00344    Tracer tr("SubMatrix(evaluate)");
00345    gm = ((BaseMatrix*&)bm)->Evaluate();
00346    if (row_number < 0) row_number = gm->Nrows();
00347    if (col_number < 0) col_number = gm->Ncols();
00348    if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
00349    {
00350       gm->tDelete();
00351 #ifdef TEMPS_DESTROYED_QUICKLY
00352       delete this;
00353 #endif
00354       Throw(SubMatrixDimensionException());
00355    }
00356    if (IsSym) Compare(gm->Type().ssub(), mt);
00357    else Compare(gm->Type().sub(), mt);
00358    GeneralMatrix* gmx = mt.New(row_number, col_number, this);
00359    int i = row_number;
00360    MatrixRow mr(gm, LoadOnEntry, row_skip); 
00361    MatrixRow mrx(gmx, StoreOnExit+DirectPart);
00362    MatrixRowCol sub;
00363    while (i--)
00364    {
00365       mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
00366       mrx.Copy(sub); mrx.Next(); mr.Next();
00367    }
00368    gmx->ReleaseAndDelete(); gm->tDelete();
00369 #ifdef TEMPS_DESTROYED_QUICKLY
00370    delete this;
00371 #endif
00372    return gmx;
00373 }   
00374 
00375 
00376 GeneralMatrix* ReturnMatrixX::Evaluate(MatrixType mt)
00377 {
00378 #ifdef TEMPS_DESTROYED_QUICKLY_R
00379    GeneralMatrix* gmx = gm; delete this; return gmx->Evaluate(mt);
00380 #else
00381    return gm->Evaluate(mt);
00382 #endif
00383 }
00384 
00385 
00386 void GeneralMatrix::Add(GeneralMatrix* gm1, Real f)
00387 {
00388    REPORT
00389    Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
00390    while (i--)
00391    { *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; }
00392    i = storage & 3; while (i--) *s++ = *s1++ + f;
00393 }
00394    
00395 void GeneralMatrix::Add(Real f)
00396 {
00397    REPORT
00398    Real* s=store; int i=(storage >> 2);
00399    while (i--) { *s++ += f; *s++ += f; *s++ += f; *s++ += f; }
00400    i = storage & 3; while (i--) *s++ += f;
00401 }
00402    
00403 void GeneralMatrix::NegAdd(GeneralMatrix* gm1, Real f)
00404 {
00405    REPORT
00406    Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
00407    while (i--)
00408    { *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; }
00409    i = storage & 3; while (i--) *s++ = f - *s1++;
00410 }
00411    
00412 void GeneralMatrix::NegAdd(Real f)
00413 {
00414    REPORT
00415    Real* s=store; int i=(storage >> 2);
00416    while (i--)
00417    {
00418       *s = f - *s; s++; *s = f - *s; s++;
00419       *s = f - *s; s++; *s = f - *s; s++;
00420    }
00421    i = storage & 3; while (i--)  { *s = f - *s; s++; }
00422 }
00423    
00424 void GeneralMatrix::Negate(GeneralMatrix* gm1)
00425 {
00426    // change sign of elements
00427    REPORT
00428    Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
00429    while (i--)
00430    { *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); }
00431    i = storage & 3; while(i--) *s++ = -(*s1++);
00432 }
00433    
00434 void GeneralMatrix::Negate()
00435 {
00436    REPORT
00437    Real* s=store; int i=(storage >> 2);
00438    while (i--)
00439    { *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; }
00440    i = storage & 3; while(i--) { *s = -(*s); s++; }
00441 }
00442    
00443 void GeneralMatrix::Multiply(GeneralMatrix* gm1, Real f)
00444 {
00445    REPORT
00446    Real* s1=gm1->store; Real* s=store;  int i=(storage >> 2);
00447    while (i--)
00448    { *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; }
00449    i = storage & 3; while (i--) *s++ = *s1++ * f;
00450 }
00451    
00452 void GeneralMatrix::Multiply(Real f)
00453 {
00454    REPORT
00455    Real* s=store; int i=(storage >> 2);
00456    while (i--) { *s++ *= f; *s++ *= f; *s++ *= f; *s++ *= f; }
00457    i = storage & 3; while (i--) *s++ *= f;
00458 }
00459    
00460 
00461 /************************ MatrixInput routines ****************************/
00462 
00463 // int MatrixInput::n;          // number values still to be read
00464 // Real* MatrixInput::r;        // pointer to next location to be read to
00465 
00466 MatrixInput MatrixInput::operator<<(Real f)
00467 {
00468    REPORT
00469    Tracer et("MatrixInput");
00470    if (n<=0) Throw(ProgramException("List of values too long"));
00471    *r = f; int n1 = n-1; n=0;   // n=0 so we won't trigger exception
00472    return MatrixInput(n1, r+1);
00473 }
00474 
00475 
00476 MatrixInput GeneralMatrix::operator<<(Real f)
00477 {
00478    REPORT
00479    Tracer et("MatrixInput");
00480    int n = Storage();
00481    if (n<=0) Throw(ProgramException("Loading data to zero length matrix"));
00482    Real* r; r = Store(); *r = f; n--;
00483    return MatrixInput(n, r+1);
00484 }
00485 
00486 MatrixInput GetSubMatrix::operator<<(Real f)
00487 {
00488    REPORT
00489    Tracer et("MatrixInput (GetSubMatrix)");
00490    SetUpLHS();
00491    if (row_number != 1 || col_skip != 0 || col_number != gm->Ncols())
00492    {
00493 #ifdef TEMPS_DESTROYED_QUICKLY
00494       delete this;
00495 #endif
00496       Throw(ProgramException("MatrixInput requires complete rows"));
00497    }
00498    MatrixRow mr(gm, DirectPart, row_skip);  // to pick up location and length
00499    int n = mr.Storage();
00500    if (n<=0)
00501    {
00502 #ifdef TEMPS_DESTROYED_QUICKLY
00503       delete this;
00504 #endif
00505       Throw(ProgramException("Loading data to zero length row"));
00506    }
00507    Real* r; r = mr.Data(); *r = f; n--;
00508    if (+(mr.cw*HaveStore))
00509    {
00510 #ifdef TEMPS_DESTROYED_QUICKLY
00511       delete this;
00512 #endif
00513       Throw(ProgramException("Fails with this matrix type"));
00514    }
00515 #ifdef TEMPS_DESTROYED_QUICKLY
00516    delete this;
00517 #endif
00518    return MatrixInput(n, r+1);
00519 }
00520 
00521 MatrixInput::~MatrixInput()
00522 {
00523    REPORT
00524    Tracer et("MatrixInput");
00525    if (n!=0) Throw(ProgramException("A list of values was too short"));
00526 }
00527 
00528 MatrixInput BandMatrix::operator<<(Real)
00529 {
00530    Tracer et("MatrixInput");
00531    bool dummy = true;
00532    if (dummy)                                   // get rid of warning message
00533       Throw(ProgramException("Cannot use list read with a BandMatrix"));
00534    return MatrixInput(0, 0);
00535 }
00536 
00537 void BandMatrix::operator<<(const Real*)
00538 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
00539 
00540 // ************************* Reverse order of elements ***********************
00541 
00542 void GeneralMatrix::ReverseElements(GeneralMatrix* gm)
00543 {
00544    // reversing into a new matrix
00545    REPORT
00546    int n = Storage(); Real* rx = Store() + n; Real* x = gm->Store();
00547    while (n--) *(--rx) = *(x++);
00548 }
00549 
00550 void GeneralMatrix::ReverseElements()
00551 {
00552    // reversing in place
00553    REPORT
00554    int n = Storage(); Real* x = Store(); Real* rx = x + n;
00555    n /= 2;
00556    while (n--) { Real t = *(--rx); *rx = *x; *(x++) = t; }
00557 }
00558 
00559 
00560 #ifdef use_namespace
00561 }
00562 #endif
00563 


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