00001
00002
00003
00004
00005
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
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);
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);
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
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
00462
00463
00464
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;
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);
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)
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
00541
00542 void GeneralMatrix::ReverseElements(GeneralMatrix* gm)
00543 {
00544
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
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