MOOS 0.2375
|
00001 //$$ submat.cpp submatrices 00002 00003 // Copyright (C) 1991,2,3,4: 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 #ifdef DO_REPORT 00015 #define REPORT { static ExeCounter ExeCount(__LINE__,11); ++ExeCount; } 00016 #else 00017 #define REPORT {} 00018 #endif 00019 00020 00021 /****************************** submatrices *********************************/ 00022 00023 #ifdef TEMPS_DESTROYED_QUICKLY 00024 GetSubMatrix& BaseMatrix::SubMatrix(int first_row, int last_row, int first_col, 00025 int last_col) const 00026 #else 00027 GetSubMatrix BaseMatrix::SubMatrix(int first_row, int last_row, int first_col, 00028 int last_col) const 00029 #endif 00030 { 00031 REPORT 00032 Tracer tr("SubMatrix"); 00033 int a = first_row - 1; int b = last_row - first_row + 1; 00034 int c = first_col - 1; int d = last_col - first_col + 1; 00035 if (a<0 || b<0 || c<0 || d<0) Throw(SubMatrixDimensionException()); 00036 // allow zero rows or columns 00037 #ifdef TEMPS_DESTROYED_QUICKLY 00038 GetSubMatrix* x = new GetSubMatrix(this, a, b, c, d, false); 00039 MatrixErrorNoSpace(x); 00040 return *x; 00041 #else 00042 return GetSubMatrix(this, a, b, c, d, false); 00043 #endif 00044 } 00045 00046 #ifdef TEMPS_DESTROYED_QUICKLY 00047 GetSubMatrix& BaseMatrix::SymSubMatrix(int first_row, int last_row) const 00048 #else 00049 GetSubMatrix BaseMatrix::SymSubMatrix(int first_row, int last_row) const 00050 #endif 00051 { 00052 REPORT 00053 Tracer tr("SubMatrix(symmetric)"); 00054 int a = first_row - 1; int b = last_row - first_row + 1; 00055 if (a<0 || b<0) Throw(SubMatrixDimensionException()); 00056 // allow zero rows or columns 00057 #ifdef TEMPS_DESTROYED_QUICKLY 00058 GetSubMatrix* x = new GetSubMatrix(this, a, b, a, b, true); 00059 MatrixErrorNoSpace(x); 00060 return *x; 00061 #else 00062 return GetSubMatrix( this, a, b, a, b, true); 00063 #endif 00064 } 00065 00066 #ifdef TEMPS_DESTROYED_QUICKLY 00067 GetSubMatrix& BaseMatrix::Row(int first_row) const 00068 #else 00069 GetSubMatrix BaseMatrix::Row(int first_row) const 00070 #endif 00071 { 00072 REPORT 00073 Tracer tr("SubMatrix(row)"); 00074 int a = first_row - 1; 00075 if (a<0) Throw(SubMatrixDimensionException()); 00076 #ifdef TEMPS_DESTROYED_QUICKLY 00077 GetSubMatrix* x = new GetSubMatrix(this, a, 1, 0, -1, false); 00078 MatrixErrorNoSpace(x); 00079 return *x; 00080 #else 00081 return GetSubMatrix(this, a, 1, 0, -1, false); 00082 #endif 00083 } 00084 00085 #ifdef TEMPS_DESTROYED_QUICKLY 00086 GetSubMatrix& BaseMatrix::Rows(int first_row, int last_row) const 00087 #else 00088 GetSubMatrix BaseMatrix::Rows(int first_row, int last_row) const 00089 #endif 00090 { 00091 REPORT 00092 Tracer tr("SubMatrix(rows)"); 00093 int a = first_row - 1; int b = last_row - first_row + 1; 00094 if (a<0 || b<0) Throw(SubMatrixDimensionException()); 00095 // allow zero rows or columns 00096 #ifdef TEMPS_DESTROYED_QUICKLY 00097 GetSubMatrix* x = new GetSubMatrix(this, a, b, 0, -1, false); 00098 MatrixErrorNoSpace(x); 00099 return *x; 00100 #else 00101 return GetSubMatrix(this, a, b, 0, -1, false); 00102 #endif 00103 } 00104 00105 #ifdef TEMPS_DESTROYED_QUICKLY 00106 GetSubMatrix& BaseMatrix::Column(int first_col) const 00107 #else 00108 GetSubMatrix BaseMatrix::Column(int first_col) const 00109 #endif 00110 { 00111 REPORT 00112 Tracer tr("SubMatrix(column)"); 00113 int c = first_col - 1; 00114 if (c<0) Throw(SubMatrixDimensionException()); 00115 #ifdef TEMPS_DESTROYED_QUICKLY 00116 GetSubMatrix* x = new GetSubMatrix(this, 0, -1, c, 1, false); 00117 MatrixErrorNoSpace(x); 00118 return *x; 00119 #else 00120 return GetSubMatrix(this, 0, -1, c, 1, false); 00121 #endif 00122 } 00123 00124 #ifdef TEMPS_DESTROYED_QUICKLY 00125 GetSubMatrix& BaseMatrix::Columns(int first_col, int last_col) const 00126 #else 00127 GetSubMatrix BaseMatrix::Columns(int first_col, int last_col) const 00128 #endif 00129 { 00130 REPORT 00131 Tracer tr("SubMatrix(columns)"); 00132 int c = first_col - 1; int d = last_col - first_col + 1; 00133 if (c<0 || d<0) Throw(SubMatrixDimensionException()); 00134 // allow zero rows or columns 00135 #ifdef TEMPS_DESTROYED_QUICKLY 00136 GetSubMatrix* x = new GetSubMatrix(this, 0, -1, c, d, false); 00137 MatrixErrorNoSpace(x); 00138 return *x; 00139 #else 00140 return GetSubMatrix(this, 0, -1, c, d, false); 00141 #endif 00142 } 00143 00144 void GetSubMatrix::SetUpLHS() 00145 { 00146 REPORT 00147 Tracer tr("SubMatrix(LHS)"); 00148 const BaseMatrix* bm1 = bm; 00149 GeneralMatrix* gm1 = ((BaseMatrix*&)bm)->Evaluate(); 00150 if ((BaseMatrix*)gm1!=bm1) 00151 Throw(ProgramException("Invalid LHS")); 00152 if (row_number < 0) row_number = gm1->Nrows(); 00153 if (col_number < 0) col_number = gm1->Ncols(); 00154 if (row_skip+row_number > gm1->Nrows() 00155 || col_skip+col_number > gm1->Ncols()) 00156 Throw(SubMatrixDimensionException()); 00157 } 00158 00159 void GetSubMatrix::operator<<(const BaseMatrix& bmx) 00160 { 00161 REPORT 00162 Tracer tr("SubMatrix(<<)"); GeneralMatrix* gmx = 0; 00163 Try 00164 { 00165 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); 00166 if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) 00167 Throw(IncompatibleDimensionsException()); 00168 MatrixRow mrx(gmx, LoadOnEntry); 00169 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00170 // do need LoadOnEntry 00171 MatrixRowCol sub; int i = row_number; 00172 while (i--) 00173 { 00174 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00175 sub.Copy(mrx); mr.Next(); mrx.Next(); 00176 } 00177 gmx->tDelete(); 00178 #ifdef TEMPS_DESTROYED_QUICKLY 00179 delete this; 00180 #endif 00181 } 00182 00183 CatchAll 00184 { 00185 if (gmx) gmx->tDelete(); 00186 #ifdef TEMPS_DESTROYED_QUICKLY 00187 delete this; 00188 #endif 00189 ReThrow; 00190 } 00191 } 00192 00193 void GetSubMatrix::operator=(const BaseMatrix& bmx) 00194 { 00195 REPORT 00196 Tracer tr("SubMatrix(=)"); GeneralMatrix* gmx = 0; 00197 // MatrixConversionCheck mcc; // Check for loss of info 00198 Try 00199 { 00200 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); 00201 if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) 00202 Throw(IncompatibleDimensionsException()); 00203 LoadAndStoreFlag lasf = 00204 ( row_skip == col_skip 00205 && gm->Type().IsSymmetric() 00206 && gmx->Type().IsSymmetric() ) 00207 ? LoadOnEntry+DirectPart 00208 : LoadOnEntry; 00209 MatrixRow mrx(gmx, lasf); 00210 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00211 // do need LoadOnEntry 00212 MatrixRowCol sub; int i = row_number; 00213 while (i--) 00214 { 00215 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00216 sub.CopyCheck(mrx); mr.Next(); mrx.Next(); 00217 } 00218 gmx->tDelete(); 00219 #ifdef TEMPS_DESTROYED_QUICKLY 00220 delete this; 00221 #endif 00222 } 00223 00224 CatchAll 00225 { 00226 if (gmx) gmx->tDelete(); 00227 #ifdef TEMPS_DESTROYED_QUICKLY 00228 delete this; 00229 #endif 00230 ReThrow; 00231 } 00232 } 00233 00234 void GetSubMatrix::operator<<(const Real* r) 00235 { 00236 REPORT 00237 Tracer tr("SubMatrix(<<Real*)"); 00238 SetUpLHS(); 00239 if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols()) 00240 Throw(SubMatrixDimensionException()); 00241 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00242 // do need LoadOnEntry 00243 MatrixRowCol sub; int i = row_number; 00244 while (i--) 00245 { 00246 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00247 sub.Copy(r); mr.Next(); 00248 } 00249 #ifdef TEMPS_DESTROYED_QUICKLY 00250 delete this; 00251 #endif 00252 } 00253 00254 void GetSubMatrix::operator=(Real r) 00255 { 00256 REPORT 00257 Tracer tr("SubMatrix(=Real)"); 00258 SetUpLHS(); 00259 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00260 // do need LoadOnEntry 00261 MatrixRowCol sub; int i = row_number; 00262 while (i--) 00263 { 00264 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00265 sub.Copy(r); mr.Next(); 00266 } 00267 #ifdef TEMPS_DESTROYED_QUICKLY 00268 delete this; 00269 #endif 00270 } 00271 00272 void GetSubMatrix::Inject(const GeneralMatrix& gmx) 00273 { 00274 REPORT 00275 Tracer tr("SubMatrix(inject)"); 00276 SetUpLHS(); 00277 if (row_number != gmx.Nrows() || col_number != gmx.Ncols()) 00278 Throw(IncompatibleDimensionsException()); 00279 MatrixRow mrx((GeneralMatrix*)(&gmx), LoadOnEntry); 00280 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00281 // do need LoadOnEntry 00282 MatrixRowCol sub; int i = row_number; 00283 while (i--) 00284 { 00285 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00286 sub.Inject(mrx); mr.Next(); mrx.Next(); 00287 } 00288 #ifdef TEMPS_DESTROYED_QUICKLY 00289 delete this; 00290 #endif 00291 } 00292 00293 void GetSubMatrix::operator+=(const BaseMatrix& bmx) 00294 { 00295 REPORT 00296 Tracer tr("SubMatrix(+=)"); GeneralMatrix* gmx = 0; 00297 // MatrixConversionCheck mcc; // Check for loss of info 00298 Try 00299 { 00300 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); 00301 if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) 00302 Throw(IncompatibleDimensionsException()); 00303 MatrixRow mrx(gmx, LoadOnEntry); 00304 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00305 // do need LoadOnEntry 00306 MatrixRowCol sub; int i = row_number; 00307 while (i--) 00308 { 00309 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00310 sub.Check(mrx); // check for loss of info 00311 sub.Add(mrx); mr.Next(); mrx.Next(); 00312 } 00313 gmx->tDelete(); 00314 #ifdef TEMPS_DESTROYED_QUICKLY 00315 delete this; 00316 #endif 00317 } 00318 00319 CatchAll 00320 { 00321 if (gmx) gmx->tDelete(); 00322 #ifdef TEMPS_DESTROYED_QUICKLY 00323 delete this; 00324 #endif 00325 ReThrow; 00326 } 00327 } 00328 00329 void GetSubMatrix::operator-=(const BaseMatrix& bmx) 00330 { 00331 REPORT 00332 Tracer tr("SubMatrix(-=)"); GeneralMatrix* gmx = 0; 00333 // MatrixConversionCheck mcc; // Check for loss of info 00334 Try 00335 { 00336 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); 00337 if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) 00338 Throw(IncompatibleDimensionsException()); 00339 MatrixRow mrx(gmx, LoadOnEntry); 00340 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00341 // do need LoadOnEntry 00342 MatrixRowCol sub; int i = row_number; 00343 while (i--) 00344 { 00345 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00346 sub.Check(mrx); // check for loss of info 00347 sub.Sub(mrx); mr.Next(); mrx.Next(); 00348 } 00349 gmx->tDelete(); 00350 #ifdef TEMPS_DESTROYED_QUICKLY 00351 delete this; 00352 #endif 00353 } 00354 00355 CatchAll 00356 { 00357 if (gmx) gmx->tDelete(); 00358 #ifdef TEMPS_DESTROYED_QUICKLY 00359 delete this; 00360 #endif 00361 ReThrow; 00362 } 00363 } 00364 00365 void GetSubMatrix::operator+=(Real r) 00366 { 00367 REPORT 00368 Tracer tr("SubMatrix(+= or -= Real)"); 00369 // MatrixConversionCheck mcc; // Check for loss of info 00370 Try 00371 { 00372 SetUpLHS(); 00373 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00374 // do need LoadOnEntry 00375 MatrixRowCol sub; int i = row_number; 00376 while (i--) 00377 { 00378 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00379 sub.Check(); // check for loss of info 00380 sub.Add(r); mr.Next(); 00381 } 00382 #ifdef TEMPS_DESTROYED_QUICKLY 00383 delete this; 00384 #endif 00385 } 00386 00387 CatchAll 00388 { 00389 #ifdef TEMPS_DESTROYED_QUICKLY 00390 delete this; 00391 #endif 00392 ReThrow; 00393 } 00394 } 00395 00396 void GetSubMatrix::operator*=(Real r) 00397 { 00398 REPORT 00399 Tracer tr("SubMatrix(*= or /= Real)"); 00400 // MatrixConversionCheck mcc; // Check for loss of info 00401 Try 00402 { 00403 SetUpLHS(); 00404 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); 00405 // do need LoadOnEntry 00406 MatrixRowCol sub; int i = row_number; 00407 while (i--) 00408 { 00409 mr.SubRowCol(sub, col_skip, col_number); // put values in sub 00410 sub.Multiply(r); mr.Next(); 00411 } 00412 #ifdef TEMPS_DESTROYED_QUICKLY 00413 delete this; 00414 #endif 00415 } 00416 00417 CatchAll 00418 { 00419 #ifdef TEMPS_DESTROYED_QUICKLY 00420 delete this; 00421 #endif 00422 ReThrow; 00423 } 00424 } 00425 00426 #ifdef use_namespace 00427 } 00428 #endif 00429