newmat3.cc
Go to the documentation of this file.
00001 //$$ newmat3.cpp        Matrix get and restore rows and columns
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__,3); ++ExeCount; }
00019 #else
00020 #define REPORT {}
00021 #endif
00022 
00023 //#define MONITOR(what,storage,store)
00024 //   { cout << what << " " << storage << " at " << (long)store << "\n"; }
00025 
00026 #define MONITOR(what,store,storage) {}
00027 
00028 
00029 // Control bits codes for GetRow, GetCol, RestoreRow, RestoreCol
00030 //
00031 // LoadOnEntry:
00032 //    Load data into MatrixRow or Col dummy array under GetRow or GetCol
00033 // StoreOnExit:
00034 //    Restore data to original matrix under RestoreRow or RestoreCol
00035 // DirectPart:
00036 //    Load or restore only part directly stored; must be set with StoreOnExit
00037 //    Still have decide how to handle this with symmetric
00038 // StoreHere:
00039 //    used in columns only - store data at supplied storage address;
00040 //    used for GetCol, NextCol & RestoreCol. No need to fill out zeros
00041 // HaveStore:
00042 //    dummy array has been assigned (internal use only).
00043 
00044 // For symmetric matrices, treat columns as rows unless StoreHere is set;
00045 // then stick to columns as this will give better performance for doing
00046 // inverses
00047 
00048 // How components are used:
00049 
00050 // Use rows wherever possible in preference to columns
00051 
00052 // Columns without StoreHere are used in in-exact transpose, sum column,
00053 // multiply a column vector, and maybe in future access to column,
00054 // additional multiply functions, add transpose
00055 
00056 // Columns with StoreHere are used in exact transpose (not symmetric matrices
00057 // or vectors, load only)
00058 
00059 // Columns with MatrixColX (Store to full column) are used in inverse and solve
00060 
00061 // Functions required for each matrix class
00062 
00063 // GetRow(MatrixRowCol& mrc)
00064 // GetCol(MatrixRowCol& mrc)
00065 // GetCol(MatrixColX& mrc)
00066 // RestoreRow(MatrixRowCol& mrc)
00067 // RestoreCol(MatrixRowCol& mrc)
00068 // RestoreCol(MatrixColX& mrc)
00069 // NextRow(MatrixRowCol& mrc)
00070 // NextCol(MatrixRowCol& mrc)
00071 // NextCol(MatrixColX& mrc)
00072 
00073 // The Restore routines assume StoreOnExit has already been checked
00074 // Defaults for the Next routines are given below
00075 // Assume cannot have both !DirectPart && StoreHere for MatrixRowCol routines
00076 
00077 
00078 // Default NextRow and NextCol:
00079 // will work as a default but need to override NextRow for efficiency
00080 
00081 void GeneralMatrix::NextRow(MatrixRowCol& mrc)
00082 {
00083    REPORT
00084    if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreRow(mrc); }
00085    mrc.rowcol++;
00086    if (mrc.rowcol<nrows) { REPORT this->GetRow(mrc); }
00087    else { REPORT mrc.cw -= StoreOnExit; }
00088 }
00089 
00090 void GeneralMatrix::NextCol(MatrixRowCol& mrc)
00091 {
00092    REPORT                                                // 423
00093    if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
00094    mrc.rowcol++;
00095    if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
00096    else { REPORT mrc.cw -= StoreOnExit; }
00097 }
00098 
00099 void GeneralMatrix::NextCol(MatrixColX& mrc)
00100 {
00101    REPORT                                                // 423
00102    if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
00103    mrc.rowcol++;
00104    if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
00105    else { REPORT mrc.cw -= StoreOnExit; }
00106 }
00107 
00108 
00109 // routines for matrix
00110 
00111 void Matrix::GetRow(MatrixRowCol& mrc)
00112 {
00113    REPORT
00114    mrc.skip=0; mrc.storage=mrc.length=ncols; mrc.data=store+mrc.rowcol*ncols;
00115 }
00116 
00117 
00118 void Matrix::GetCol(MatrixRowCol& mrc)
00119 {
00120    REPORT
00121    mrc.skip=0; mrc.storage=mrc.length=nrows;
00122    if ( ncols==1 && !(mrc.cw*StoreHere) )      // ColumnVector
00123       { REPORT mrc.data=store; }
00124    else
00125    {
00126       Real* ColCopy;
00127       if ( !(mrc.cw*(HaveStore+StoreHere)) )
00128       {
00129          REPORT
00130          ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
00131          MONITOR_REAL_NEW("Make (MatGetCol)",nrows,ColCopy)
00132          mrc.data = ColCopy; mrc.cw += HaveStore;
00133       }
00134       else { REPORT ColCopy = mrc.data; }
00135       if (+(mrc.cw*LoadOnEntry))
00136       {
00137          REPORT
00138          Real* Mstore = store+mrc.rowcol; int i=nrows;
00139          //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
00140          if (i) for (;;)
00141             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
00142       }
00143    }
00144 }
00145 
00146 void Matrix::GetCol(MatrixColX& mrc)
00147 {
00148    REPORT
00149    mrc.skip=0; mrc.storage=nrows; mrc.length=nrows;
00150    if (+(mrc.cw*LoadOnEntry))
00151    {
00152       REPORT  Real* ColCopy = mrc.data;
00153       Real* Mstore = store+mrc.rowcol; int i=nrows;
00154       //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
00155       if (i) for (;;)
00156           { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
00157    }
00158 }
00159 
00160 void Matrix::RestoreCol(MatrixRowCol& mrc)
00161 {
00162    // always check StoreOnExit before calling RestoreCol
00163    REPORT                                   // 429
00164    if (+(mrc.cw*HaveStore))
00165    {
00166       REPORT                                // 426
00167       Real* Mstore = store+mrc.rowcol; int i=nrows;
00168       Real* Cstore = mrc.data;
00169       // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
00170       if (i) for (;;)
00171           { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
00172    }
00173 }
00174 
00175 void Matrix::RestoreCol(MatrixColX& mrc)
00176 {
00177    REPORT
00178    Real* Mstore = store+mrc.rowcol; int i=nrows; Real* Cstore = mrc.data;
00179    // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
00180    if (i) for (;;)
00181       { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
00182 }
00183 
00184 void Matrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrMat(); }  // 1808
00185 
00186 void Matrix::NextCol(MatrixRowCol& mrc)
00187 {
00188    REPORT                                        // 632
00189    if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
00190    mrc.rowcol++;
00191    if (mrc.rowcol<ncols)
00192    {
00193       if (+(mrc.cw*LoadOnEntry))
00194       {
00195          REPORT
00196          Real* ColCopy = mrc.data;
00197          Real* Mstore = store+mrc.rowcol; int i=nrows;
00198          //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
00199          if (i) for (;;)
00200             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
00201       }
00202    }
00203    else { REPORT mrc.cw -= StoreOnExit; }
00204 }
00205 
00206 void Matrix::NextCol(MatrixColX& mrc)
00207 {
00208    REPORT
00209    if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
00210    mrc.rowcol++;
00211    if (mrc.rowcol<ncols)
00212    {
00213       if (+(mrc.cw*LoadOnEntry))
00214       {
00215          REPORT
00216          Real* ColCopy = mrc.data;
00217          Real* Mstore = store+mrc.rowcol; int i=nrows;
00218          // while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
00219          if (i) for (;;)
00220             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
00221       }
00222    }
00223    else { REPORT mrc.cw -= StoreOnExit; }
00224 }
00225 
00226 // routines for diagonal matrix
00227 
00228 void DiagonalMatrix::GetRow(MatrixRowCol& mrc)
00229 {
00230    REPORT
00231    mrc.skip=mrc.rowcol; mrc.storage=1;
00232    mrc.data=store+mrc.skip; mrc.length=ncols;
00233 }
00234 
00235 void DiagonalMatrix::GetCol(MatrixRowCol& mrc)
00236 {
00237    REPORT
00238    mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
00239    if (+(mrc.cw*StoreHere))              // should not happen
00240       Throw(InternalException("DiagonalMatrix::GetCol(MatrixRowCol&)"));
00241    else  { REPORT mrc.data=store+mrc.skip; }
00242                                                       // not accessed
00243 }
00244 
00245 void DiagonalMatrix::GetCol(MatrixColX& mrc)
00246 {
00247    REPORT
00248    mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
00249    mrc.data = mrc.store+mrc.skip;
00250    *(mrc.data)=*(store+mrc.skip);
00251 }
00252 
00253 void DiagonalMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
00254                                                       // 800
00255 
00256 void DiagonalMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
00257                         // not accessed
00258 
00259 void DiagonalMatrix::NextCol(MatrixColX& mrc)
00260 {
00261    REPORT
00262    if (+(mrc.cw*StoreOnExit))
00263       { REPORT *(store+mrc.rowcol)=*(mrc.data); }
00264    mrc.IncrDiag();
00265    int t1 = +(mrc.cw*LoadOnEntry);
00266    if (t1 && mrc.rowcol < ncols)
00267       { REPORT *(mrc.data)=*(store+mrc.rowcol); }
00268 }
00269 
00270 // routines for upper triangular matrix
00271 
00272 void UpperTriangularMatrix::GetRow(MatrixRowCol& mrc)
00273 {
00274    REPORT
00275    int row = mrc.rowcol; mrc.skip=row; mrc.length=ncols;
00276    mrc.storage=ncols-row; mrc.data=store+(row*(2*ncols-row+1))/2;
00277 }
00278 
00279 
00280 void UpperTriangularMatrix::GetCol(MatrixRowCol& mrc)
00281 {
00282    REPORT
00283    mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
00284    mrc.length=nrows; Real* ColCopy;
00285    if ( !(mrc.cw*(StoreHere+HaveStore)) )
00286    {
00287       REPORT                                              // not accessed
00288       ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
00289       MONITOR_REAL_NEW("Make (UT GetCol)",nrows,ColCopy)
00290       mrc.data = ColCopy; mrc.cw += HaveStore;
00291    }
00292    else { REPORT ColCopy = mrc.data; }
00293    if (+(mrc.cw*LoadOnEntry))
00294    {
00295       REPORT
00296       Real* Mstore = store+mrc.rowcol; int j = ncols;
00297       // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
00298       if (i) for (;;)
00299          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
00300    }
00301 }
00302 
00303 void UpperTriangularMatrix::GetCol(MatrixColX& mrc)
00304 {
00305    REPORT
00306    mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
00307    mrc.length=nrows;
00308    if (+(mrc.cw*LoadOnEntry))
00309    {
00310       REPORT
00311       Real* ColCopy = mrc.data;
00312       Real* Mstore = store+mrc.rowcol; int j = ncols;
00313       // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
00314       if (i) for (;;)
00315          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
00316    }
00317 }
00318 
00319 void UpperTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
00320 {
00321   REPORT
00322   Real* Mstore = store+mrc.rowcol; int i=mrc.rowcol+1; int j = ncols;
00323   Real* Cstore = mrc.data;
00324   // while (i--) { *Mstore = *Cstore++; Mstore += --j; }
00325   if (i) for (;;)
00326      { *Mstore = *Cstore++; if (!(--i)) break; Mstore += --j; }
00327 }
00328 
00329 void UpperTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrUT(); }
00330                                                       // 722
00331 
00332 // routines for lower triangular matrix
00333 
00334 void LowerTriangularMatrix::GetRow(MatrixRowCol& mrc)
00335 {
00336    REPORT
00337    int row=mrc.rowcol; mrc.skip=0; mrc.storage=row+1; mrc.length=ncols;
00338    mrc.data=store+(row*(row+1))/2;
00339 }
00340 
00341 void LowerTriangularMatrix::GetCol(MatrixRowCol& mrc)
00342 {
00343    REPORT
00344    int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
00345    int i=nrows-col; mrc.storage=i; Real* ColCopy;
00346    if ( +(mrc.cw*(StoreHere+HaveStore)) )
00347       { REPORT  ColCopy = mrc.data; }
00348    else
00349    {
00350       REPORT                                            // not accessed
00351       ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
00352       MONITOR_REAL_NEW("Make (LT GetCol)",nrows,ColCopy)
00353       mrc.cw += HaveStore; mrc.data = ColCopy;
00354    }
00355 
00356    if (+(mrc.cw*LoadOnEntry))
00357    {
00358       REPORT
00359       Real* Mstore = store+(col*(col+3))/2;
00360       // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
00361       if (i) for (;;)
00362          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
00363    }
00364 }
00365 
00366 void LowerTriangularMatrix::GetCol(MatrixColX& mrc)
00367 {
00368    REPORT
00369    int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
00370    int i=nrows-col; mrc.storage=i; mrc.data = mrc.store + col;
00371 
00372    if (+(mrc.cw*LoadOnEntry))
00373    {
00374       REPORT  Real* ColCopy = mrc.data;
00375       Real* Mstore = store+(col*(col+3))/2;
00376       // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
00377       if (i) for (;;)
00378          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
00379    }
00380 }
00381 
00382 void LowerTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
00383 {
00384    REPORT
00385    int col=mrc.rowcol; Real* Cstore = mrc.data;
00386    Real* Mstore = store+(col*(col+3))/2; int i=nrows-col;
00387    //while (i--) { *Mstore = *Cstore++; Mstore += ++col; }
00388    if (i) for (;;)
00389       { *Mstore = *Cstore++; if (!(--i)) break; Mstore += ++col; }
00390 }
00391 
00392 void LowerTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrLT(); }
00393                                                          //712
00394 
00395 // routines for symmetric matrix
00396 
00397 void SymmetricMatrix::GetRow(MatrixRowCol& mrc)
00398 {
00399    REPORT                                                //571
00400    mrc.skip=0; int row=mrc.rowcol; mrc.length=ncols;
00401    if (+(mrc.cw*DirectPart))
00402       { REPORT mrc.storage=row+1; mrc.data=store+(row*(row+1))/2; }
00403    else
00404    {
00405       // do not allow StoreOnExit and !DirectPart
00406       if (+(mrc.cw*StoreOnExit))
00407          Throw(InternalException("SymmetricMatrix::GetRow(MatrixRowCol&)"));
00408       mrc.storage=ncols; Real* RowCopy;
00409       if (!(mrc.cw*HaveStore))
00410       {
00411          REPORT
00412          RowCopy = new Real [ncols]; MatrixErrorNoSpace(RowCopy);
00413          MONITOR_REAL_NEW("Make (SymGetRow)",ncols,RowCopy)
00414          mrc.cw += HaveStore; mrc.data = RowCopy;
00415       }
00416       else { REPORT RowCopy = mrc.data; }
00417       if (+(mrc.cw*LoadOnEntry))
00418       {
00419          REPORT                                         // 544
00420          Real* Mstore = store+(row*(row+1))/2; int i = row;
00421          while (i--) *RowCopy++ = *Mstore++;
00422          i = ncols-row;
00423          // while (i--) { *RowCopy++ = *Mstore; Mstore += ++row; }
00424          if (i) for (;;)
00425             { *RowCopy++ = *Mstore; if (!(--i)) break; Mstore += ++row; }
00426       }
00427    }
00428 }
00429 
00430 void SymmetricMatrix::GetCol(MatrixRowCol& mrc)
00431 {
00432    // do not allow StoreHere
00433    if (+(mrc.cw*StoreHere))
00434       Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
00435 
00436    int col=mrc.rowcol; mrc.length=nrows;
00437    REPORT
00438    mrc.skip=0;
00439    if (+(mrc.cw*DirectPart))    // actually get row ??
00440       { REPORT mrc.storage=col+1; mrc.data=store+(col*(col+1))/2; }
00441    else
00442    {
00443       // do not allow StoreOnExit and !DirectPart
00444       if (+(mrc.cw*StoreOnExit))
00445          Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
00446 
00447       mrc.storage=ncols; Real* ColCopy;
00448       if ( +(mrc.cw*HaveStore)) { REPORT ColCopy = mrc.data; }
00449       else
00450       {
00451          REPORT                                      // not accessed
00452          ColCopy = new Real [ncols]; MatrixErrorNoSpace(ColCopy);
00453          MONITOR_REAL_NEW("Make (SymGetCol)",ncols,ColCopy)
00454          mrc.cw += HaveStore; mrc.data = ColCopy;
00455       }
00456       if (+(mrc.cw*LoadOnEntry))
00457       {
00458          REPORT
00459          Real* Mstore = store+(col*(col+1))/2; int i = col;
00460          while (i--) *ColCopy++ = *Mstore++;
00461          i = ncols-col;
00462          // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
00463          if (i) for (;;)
00464             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
00465       }
00466    }
00467 }
00468 
00469 void SymmetricMatrix::GetCol(MatrixColX& mrc)
00470 {
00471    int col=mrc.rowcol; mrc.length=nrows;
00472    if (+(mrc.cw*DirectPart))
00473    {
00474       REPORT
00475       mrc.skip=col; int i=nrows-col; mrc.storage=i;
00476       mrc.data = mrc.store+col;
00477       if (+(mrc.cw*LoadOnEntry))
00478       {
00479          REPORT                           // not accessed
00480          Real* ColCopy = mrc.data;
00481          Real* Mstore = store+(col*(col+3))/2;
00482          // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
00483          if (i) for (;;)
00484             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
00485       }
00486    }
00487    else
00488    {
00489       REPORT
00490       // do not allow StoreOnExit and !DirectPart
00491       if (+(mrc.cw*StoreOnExit))
00492          Throw(InternalException("SymmetricMatrix::GetCol(MatrixColX&)"));
00493 
00494       mrc.skip=0; mrc.storage=ncols;
00495       if (+(mrc.cw*LoadOnEntry))
00496       {
00497          REPORT
00498          Real* ColCopy = mrc.data;
00499          Real* Mstore = store+(col*(col+1))/2; int i = col;
00500          while (i--) *ColCopy++ = *Mstore++;
00501          i = ncols-col;
00502          // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
00503          if (i) for (;;)
00504             { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
00505       }
00506    }
00507 }
00508 
00509 // Do not need RestoreRow because we do not allow !DirectPart && StoreOnExit
00510 
00511 void SymmetricMatrix::RestoreCol(MatrixColX& mrc)
00512 {
00513    REPORT
00514    // Really do restore column
00515    int col=mrc.rowcol; Real* Cstore = mrc.data;
00516    Real* Mstore = store+(col*(col+3))/2; int i = nrows-col;
00517    // while (i--) { *Mstore = *Cstore++; Mstore+= ++col; }
00518    if (i) for (;;)
00519       { *Mstore = *Cstore++; if (!(--i)) break; Mstore+= ++col; }
00520 
00521 }
00522 
00523 // routines for row vector
00524 
00525 void RowVector::GetCol(MatrixRowCol& mrc)
00526 {
00527    REPORT
00528    // do not allow StoreHere
00529    if (+(mrc.cw*StoreHere))
00530       Throw(InternalException("RowVector::GetCol(MatrixRowCol&)"));
00531 
00532    mrc.skip=0; mrc.storage=1; mrc.length=nrows; mrc.data = store+mrc.rowcol;
00533 
00534 }
00535 
00536 void RowVector::GetCol(MatrixColX& mrc)
00537 {
00538    REPORT
00539    mrc.skip=0; mrc.storage=1; mrc.length=nrows;
00540    if (mrc.cw >= LoadOnEntry)
00541       { REPORT *(mrc.data) = *(store+mrc.rowcol); }
00542 
00543 }
00544 
00545 void RowVector::NextCol(MatrixRowCol& mrc)
00546 { REPORT mrc.rowcol++; mrc.data++; }
00547 
00548 void RowVector::NextCol(MatrixColX& mrc)
00549 {
00550    if (+(mrc.cw*StoreOnExit)) { REPORT *(store+mrc.rowcol)=*(mrc.data); }
00551 
00552    mrc.rowcol++;
00553    if (mrc.rowcol < ncols)
00554    {
00555       if (+(mrc.cw*LoadOnEntry)) { REPORT *(mrc.data)=*(store+mrc.rowcol); }
00556    }
00557    else { REPORT mrc.cw -= StoreOnExit; }
00558 }
00559 
00560 void RowVector::RestoreCol(MatrixColX& mrc)
00561    { REPORT *(store+mrc.rowcol)=*(mrc.data); }           // not accessed
00562 
00563 
00564 // routines for band matrices
00565 
00566 void BandMatrix::GetRow(MatrixRowCol& mrc)
00567 {
00568    REPORT
00569    int r = mrc.rowcol; int w = lower+1+upper; mrc.length=ncols;
00570    int s = r-lower;
00571    if (s<0) { mrc.data = store+(r*w-s); w += s; s = 0; }
00572    else mrc.data = store+r*w;
00573    mrc.skip = s; s += w-ncols; if (s>0) w -= s; mrc.storage = w;
00574 }
00575 
00576 // should make special versions of this for upper and lower band matrices
00577 
00578 void BandMatrix::NextRow(MatrixRowCol& mrc)
00579 {
00580    REPORT
00581    int r = ++mrc.rowcol;
00582    if (r<=lower) { mrc.storage++; mrc.data += lower+upper; }
00583    else  { mrc.skip++; mrc.data += lower+upper+1; }
00584    if (r>=ncols-upper) mrc.storage--;
00585 }
00586 
00587 void BandMatrix::GetCol(MatrixRowCol& mrc)
00588 {
00589    REPORT
00590    int c = mrc.rowcol; int n = lower+upper; int w = n+1;
00591    mrc.length=nrows; Real* ColCopy;
00592    int b; int s = c-upper;
00593    if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
00594    mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
00595    if ( +(mrc.cw*(StoreHere+HaveStore)) )
00596       { REPORT ColCopy = mrc.data; }
00597    else
00598    {
00599       REPORT
00600       ColCopy = new Real [n+1]; MatrixErrorNoSpace(ColCopy);
00601       MONITOR_REAL_NEW("Make (BMGetCol)",n+1,ColCopy)
00602       mrc.cw += HaveStore; mrc.data = ColCopy;
00603    }
00604 
00605    if (+(mrc.cw*LoadOnEntry))
00606    {
00607       REPORT
00608       Real* Mstore = store+b;
00609       // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
00610       if (w) for (;;)
00611          { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
00612    }
00613 }
00614 
00615 void BandMatrix::GetCol(MatrixColX& mrc)
00616 {
00617    REPORT
00618    int c = mrc.rowcol; int n = lower+upper; int w = n+1;
00619    mrc.length=nrows; int b; int s = c-upper;
00620    if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
00621    mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
00622    mrc.data = mrc.store+mrc.skip;
00623 
00624    if (+(mrc.cw*LoadOnEntry))
00625    {
00626       REPORT
00627       Real* ColCopy = mrc.data; Real* Mstore = store+b;
00628       // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
00629       if (w) for (;;)
00630          { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
00631    }
00632 }
00633 
00634 void BandMatrix::RestoreCol(MatrixRowCol& mrc)
00635 {
00636    REPORT
00637    int c = mrc.rowcol; int n = lower+upper; int s = c-upper;
00638    Real* Mstore = store + ((s<=0) ? c+lower : s*n+s+n);
00639    Real* Cstore = mrc.data;
00640    int w = mrc.storage;
00641    // while (w--) { *Mstore = *Cstore++; Mstore += n; }
00642    if (w) for (;;)
00643       { *Mstore = *Cstore++; if (!(--w)) break; Mstore += n; }
00644 }
00645 
00646 // routines for symmetric band matrix
00647 
00648 void SymmetricBandMatrix::GetRow(MatrixRowCol& mrc)
00649 {
00650    REPORT
00651    int r=mrc.rowcol; int s = r-lower; int w1 = lower+1; int o = r*w1;
00652    mrc.length = ncols;
00653    if (s<0) { w1 += s; o -= s; s = 0; }
00654    mrc.skip = s;
00655 
00656    if (+(mrc.cw*DirectPart))
00657       { REPORT  mrc.data = store+o; mrc.storage = w1; }
00658    else
00659    {
00660       // do not allow StoreOnExit and !DirectPart
00661       if (+(mrc.cw*StoreOnExit))
00662          Throw(InternalException("SymmetricBandMatrix::GetRow(MatrixRowCol&)"));
00663       int w = w1+lower; s += w-ncols; Real* RowCopy;
00664       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
00665       if (!(mrc.cw*HaveStore))
00666       {
00667          REPORT
00668          RowCopy = new Real [2*lower+1]; MatrixErrorNoSpace(RowCopy);
00669          MONITOR_REAL_NEW("Make (SmBGetRow)",2*lower+1,RowCopy)
00670          mrc.cw += HaveStore; mrc.data = RowCopy;
00671       }
00672       else { REPORT  RowCopy = mrc.data; }
00673 
00674       if (+(mrc.cw*LoadOnEntry))
00675       {
00676               REPORT
00677          Real* Mstore = store+o;
00678          while (w1--) *RowCopy++ = *Mstore++;
00679          Mstore--;
00680          while (w2--) { Mstore += lower; *RowCopy++ = *Mstore; }
00681       }
00682    }
00683 }
00684 
00685 void SymmetricBandMatrix::GetCol(MatrixRowCol& mrc)
00686 {
00687    // do not allow StoreHere
00688    if (+(mrc.cw*StoreHere))
00689       Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
00690 
00691    int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
00692    REPORT
00693    int s = c-lower; int o = c*w1;
00694    if (s<0) { w1 += s; o -= s; s = 0; }
00695    mrc.skip = s;
00696 
00697    if (+(mrc.cw*DirectPart))
00698    { REPORT  mrc.data = store+o; mrc.storage = w1; }
00699    else
00700    {
00701       // do not allow StoreOnExit and !DirectPart
00702       if (+(mrc.cw*StoreOnExit))
00703          Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
00704       int w = w1+lower; s += w-ncols; Real* ColCopy;
00705       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
00706 
00707       if ( +(mrc.cw*HaveStore) ) { REPORT ColCopy = mrc.data; }
00708       else
00709       {
00710          REPORT ColCopy = new Real [2*lower+1]; MatrixErrorNoSpace(ColCopy);
00711          MONITOR_REAL_NEW("Make (SmBGetCol)",2*lower+1,ColCopy)
00712          mrc.cw += HaveStore; mrc.data = ColCopy;
00713       }
00714 
00715       if (+(mrc.cw*LoadOnEntry))
00716       {
00717          REPORT
00718          Real* Mstore = store+o;
00719          while (w1--) *ColCopy++ = *Mstore++;
00720          Mstore--;
00721          while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
00722       }
00723    }
00724 }
00725 
00726 void SymmetricBandMatrix::GetCol(MatrixColX& mrc)
00727 {
00728    int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
00729    if (+(mrc.cw*DirectPart))
00730    {
00731       REPORT
00732       int b = c*w1+lower;
00733       mrc.skip = c; c += w1-nrows; w1 -= c; mrc.storage = w1;
00734       Real* ColCopy = mrc.data = mrc.store+mrc.skip;
00735       if (+(mrc.cw*LoadOnEntry))
00736       {
00737          REPORT
00738          Real* Mstore = store+b;
00739          // while (w1--) { *ColCopy++ = *Mstore; Mstore += lower; }
00740          if (w1) for (;;)
00741             { *ColCopy++ = *Mstore; if (!(--w1)) break; Mstore += lower; }
00742       }
00743    }
00744    else
00745    {
00746       REPORT
00747       // do not allow StoreOnExit and !DirectPart
00748       if (+(mrc.cw*StoreOnExit))
00749          Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixColX&)"));
00750       int s = c-lower; int o = c*w1;
00751       if (s<0) { w1 += s; o -= s; s = 0; }
00752       mrc.skip = s;
00753 
00754       int w = w1+lower; s += w-ncols;
00755       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
00756 
00757       Real* ColCopy = mrc.data = mrc.store+mrc.skip;
00758 
00759       if (+(mrc.cw*LoadOnEntry))
00760       {
00761          REPORT
00762          Real* Mstore = store+o;
00763          while (w1--) *ColCopy++ = *Mstore++;
00764          Mstore--;
00765          while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
00766       }
00767 
00768    }
00769 }
00770 
00771 void SymmetricBandMatrix::RestoreCol(MatrixColX& mrc)
00772 {
00773    REPORT
00774    int c = mrc.rowcol;
00775    Real* Mstore = store + c*lower+c+lower;
00776    Real* Cstore = mrc.data; int w = mrc.storage;
00777    // while (w--) { *Mstore = *Cstore++; Mstore += lower; }
00778    if (w) for (;;)
00779       { *Mstore = *Cstore++; if (!(--w)) break; Mstore += lower; }
00780 }
00781 
00782 // routines for identity matrix
00783 
00784 void IdentityMatrix::GetRow(MatrixRowCol& mrc)
00785 {
00786    REPORT
00787    mrc.skip=mrc.rowcol; mrc.storage=1; mrc.data=store; mrc.length=ncols;
00788 }
00789 
00790 void IdentityMatrix::GetCol(MatrixRowCol& mrc)
00791 {
00792    REPORT
00793    mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
00794    if (+(mrc.cw*StoreHere))              // should not happen
00795       Throw(InternalException("IdentityMatrix::GetCol(MatrixRowCol&)"));
00796    else  { REPORT mrc.data=store; }
00797 }
00798 
00799 void IdentityMatrix::GetCol(MatrixColX& mrc)
00800 {
00801    REPORT
00802    mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
00803    mrc.data = mrc.store+mrc.skip; *(mrc.data)=*store;
00804 }
00805 
00806 void IdentityMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
00807 
00808 void IdentityMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
00809 
00810 void IdentityMatrix::NextCol(MatrixColX& mrc)
00811 {
00812    REPORT
00813    if (+(mrc.cw*StoreOnExit)) { REPORT *store=*(mrc.data); }
00814    mrc.IncrDiag();            // must increase mrc.data so need IncrDiag
00815    int t1 = +(mrc.cw*LoadOnEntry);
00816    if (t1 && mrc.rowcol < ncols) { REPORT *(mrc.data)=*store; }
00817 }
00818 
00819 
00820 
00821 
00822 // *************************** destructors *******************************
00823 
00824 MatrixRowCol::~MatrixRowCol()
00825 {
00826    if (+(cw*HaveStore))
00827    {
00828       MONITOR_REAL_DELETE("Free    (RowCol)",-1,data)  // do not know length
00829       delete [] data;
00830    }
00831 }
00832 
00833 MatrixRow::~MatrixRow() { if (+(cw*StoreOnExit)) gm->RestoreRow(*this); }
00834 
00835 MatrixCol::~MatrixCol() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
00836 
00837 MatrixColX::~MatrixColX() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
00838 
00839 #ifdef use_namespace
00840 }
00841 #endif
00842 


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