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