MOOS 0.2375
|
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