00001
00002
00003
00008
00009
00010
00011
00012
00013 #include "lo/NewMatExhaustive.h"
00017 Real fourbyfourident[] = {1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0};
00018
00020 Real threebythreeident[] ={1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0};
00021
00024
00025
00026
00027 #ifndef NEWMATRC_LIB
00028 #define NEWMATRC_LIB 0
00029
00030 #ifdef use_namespace
00031 namespace NEWMAT {
00032 #endif
00033
00036
00040
00041
00042 #ifndef CONTROL_WORD_LIB
00043 #define CONTROL_WORD_LIB 0
00044
00047 class ControlWord
00048 {
00049 protected:
00050 int cw;
00051 public:
00052 ControlWord() : cw(0) {}
00053 ControlWord(int i) : cw(i) {}
00054
00055
00056 ControlWord operator*(ControlWord i) const
00057 { return ControlWord(cw & i.cw); }
00058 void operator*=(ControlWord i) { cw &= i.cw; }
00059
00060
00061 ControlWord operator+(ControlWord i) const
00062 { return ControlWord(cw | i.cw); }
00063 void operator+=(ControlWord i) { cw |= i.cw; }
00064
00065
00066 ControlWord operator-(ControlWord i) const
00067 { return ControlWord(cw - (cw & i.cw)); }
00068 void operator-=(ControlWord i) { cw -= (cw & i.cw); }
00069
00070
00071 bool operator>=(ControlWord i) const { return (cw & i.cw) == i.cw; }
00072 bool operator<=(ControlWord i) const { return (cw & i.cw) == cw; }
00073
00074
00075 ControlWord operator^(ControlWord i) const
00076 { return ControlWord(cw ^ i.cw); }
00077 ControlWord operator~() const { return ControlWord(~cw); }
00078
00079
00080 int operator+() const { return cw; }
00081 int operator!() const { return cw==0; }
00082 FREE_CHECK(ControlWord)
00083 };
00084
00085
00086 #endif
00087
00089
00092
00095
00096
00097
00098 #define WANT_MATH
00099
00100
00101 #ifdef use_namespace
00102 namespace NEWMAT {
00103 #endif
00104
00105 #ifdef DO_REPORT
00106 #define REPORT { static ExeCounter ExeCount(__LINE__,12); ++ExeCount; }
00107 #else
00108 #define REPORT {}
00109 #endif
00110
00111
00112
00113
00114
00115 void RectMatrixRow::Reset (const Matrix& M, int row, int skip, int length)
00116 {
00117 REPORT
00118 RectMatrixRowCol::Reset
00119 ( M.Store()+row*M.Ncols()+skip, length, 1, M.Ncols() );
00120 }
00121
00122 void RectMatrixRow::Reset (const Matrix& M, int row)
00123 {
00124 REPORT
00125 RectMatrixRowCol::Reset( M.Store()+row*M.Ncols(), M.Ncols(), 1, M.Ncols() );
00126 }
00127
00128 void RectMatrixCol::Reset (const Matrix& M, int skip, int col, int length)
00129 {
00130 REPORT
00131 RectMatrixRowCol::Reset
00132 ( M.Store()+col+skip*M.Ncols(), length, M.Ncols(), 1 );
00133 }
00134
00135 void RectMatrixCol::Reset (const Matrix& M, int col)
00136 {
00137 REPORT
00138 RectMatrixRowCol::Reset( M.Store()+col, M.Nrows(), M.Ncols(), 1 );
00139 }
00140
00141
00142 Real RectMatrixRowCol::SumSquare() const
00143 {
00144 REPORT
00145 long_Real sum = 0.0; int i = n; Real* s = store; int d = spacing;
00146
00147 if (i) for(;;)
00148 { sum += (long_Real)*s * *s; if (!(--i)) break; s += d; }
00149 return (Real)sum;
00150 }
00151
00152 Real RectMatrixRowCol::operator*(const RectMatrixRowCol& rmrc) const
00153 {
00154 REPORT
00155 long_Real sum = 0.0; int i = n;
00156 Real* s = store; int d = spacing;
00157 Real* s1 = rmrc.store; int d1 = rmrc.spacing;
00158 if (i!=rmrc.n)
00159 {
00160 Tracer tr("newmatrm");
00161 Throw(InternalException("Dimensions differ in *"));
00162 }
00163
00164 if (i) for(;;)
00165 { sum += (long_Real)*s * *s1; if (!(--i)) break; s += d; s1 += d1; }
00166 return (Real)sum;
00167 }
00168
00169 void RectMatrixRowCol::AddScaled(const RectMatrixRowCol& rmrc, Real r)
00170 {
00171 REPORT
00172 int i = n; Real* s = store; int d = spacing;
00173 Real* s1 = rmrc.store; int d1 = rmrc.spacing;
00174 if (i!=rmrc.n)
00175 {
00176 Tracer tr("newmatrm");
00177 Throw(InternalException("Dimensions differ in AddScaled"));
00178 }
00179
00180 if (i) for (;;)
00181 { *s += *s1 * r; if (!(--i)) break; s += d; s1 += d1; }
00182 }
00183
00184 void RectMatrixRowCol::Divide(const RectMatrixRowCol& rmrc, Real r)
00185 {
00186 REPORT
00187 int i = n; Real* s = store; int d = spacing;
00188 Real* s1 = rmrc.store; int d1 = rmrc.spacing;
00189 if (i!=rmrc.n)
00190 {
00191 Tracer tr("newmatrm");
00192 Throw(InternalException("Dimensions differ in Divide"));
00193 }
00194
00195 if (i) for (;;) { *s = *s1 / r; if (!(--i)) break; s += d; s1 += d1; }
00196 }
00197
00198 void RectMatrixRowCol::Divide(Real r)
00199 {
00200 REPORT
00201 int i = n; Real* s = store; int d = spacing;
00202
00203 if (i) for (;;) { *s /= r; if (!(--i)) break; s += d; }
00204 }
00205
00206 void RectMatrixRowCol::Negate()
00207 {
00208 REPORT
00209 int i = n; Real* s = store; int d = spacing;
00210
00211 if (i) for (;;) { *s = - *s; if (!(--i)) break; s += d; }
00212 }
00213
00214 void RectMatrixRowCol::Zero()
00215 {
00216 REPORT
00217 int i = n; Real* s = store; int d = spacing;
00218
00219 if (i) for (;;) { *s = 0.0; if (!(--i)) break; s += d; }
00220 }
00221
00222 void ComplexScale(RectMatrixCol& U, RectMatrixCol& V, Real x, Real y)
00223 {
00224 REPORT
00225 int n = U.n;
00226 if (n != V.n)
00227 {
00228 Tracer tr("newmatrm");
00229 Throw(InternalException("Dimensions differ in ComplexScale"));
00230 }
00231 Real* u = U.store; Real* v = V.store;
00232 int su = U.spacing; int sv = V.spacing;
00233
00234
00235
00236
00237
00238 if (n) for (;;)
00239 {
00240 Real z = *u * x - *v * y; *v = *u * y + *v * x; *u = z;
00241 if (!(--n)) break;
00242 u += su; v += sv;
00243 }
00244 }
00245
00246 void Rotate(RectMatrixCol& U, RectMatrixCol& V, Real tau, Real s)
00247 {
00248 REPORT
00249
00250 int n = U.n;
00251 if (n != V.n)
00252 {
00253 Tracer tr("newmatrm");
00254 Throw(InternalException("Dimensions differ in Rotate"));
00255 }
00256 Real* u = U.store; Real* v = V.store;
00257 int su = U.spacing; int sv = V.spacing;
00258
00259
00260
00261
00262
00263
00264 if (n) for(;;)
00265 {
00266 Real zu = *u; Real zv = *v;
00267 *u -= s * (zv + zu * tau); *v += s * (zu - zv * tau);
00268 if (!(--n)) break;
00269 u += su; v += sv;
00270 }
00271 }
00272
00273
00274
00275
00276 Real pythag(Real f, Real g, Real& c, Real& s)
00277
00278
00279
00280 {
00281 if (f==0 && g==0) { c=1.0; s=0.0; return 0.0; }
00282 Real af = f>=0 ? f : -f;
00283 Real ag = g>=0 ? g : -g;
00284 if (ag<af)
00285 {
00286 REPORT
00287 Real h = g/f; Real sq = sqrt(1.0+h*h);
00288 if (f<0) sq = -sq;
00289 c = 1.0/sq; s = h/sq; return sq*f;
00290 }
00291 else
00292 {
00293 REPORT
00294 Real h = f/g; Real sq = sqrt(1.0+h*h);
00295 if (g<0) sq = -sq;
00296 s = 1.0/sq; c = h/sq; return sq*g;
00297 }
00298 }
00299
00300
00301
00302
00303 #ifdef use_namespace
00304 }
00305 #endif
00306
00307
00309
00310
00311
00312
00313
00314
00315
00316
00317 enum LSF { LoadOnEntry=1,StoreOnExit=2,DirectPart=4,StoreHere=8,HaveStore=16 };
00318
00319
00322 class LoadAndStoreFlag : public ControlWord
00323 {
00324 public:
00325 LoadAndStoreFlag() {}
00326 LoadAndStoreFlag(int i) : ControlWord(i) {}
00327 LoadAndStoreFlag(LSF lsf) : ControlWord(lsf) {}
00328 LoadAndStoreFlag(const ControlWord& cwx) : ControlWord(cwx) {}
00329 };
00330
00331
00334 class MatrixRowCol
00335 {
00336 public:
00337
00338 int length;
00339 int skip;
00340 int storage;
00341 int rowcol;
00342 GeneralMatrix* gm;
00343 Real* data;
00344 LoadAndStoreFlag cw;
00345 void IncrMat() { rowcol++; data += storage; }
00346 void IncrDiag() { rowcol++; skip++; data++; }
00347 void IncrId() { rowcol++; skip++; }
00348 void IncrUT() { rowcol++; data += storage; storage--; skip++; }
00349 void IncrLT() { rowcol++; data += storage; storage++; }
00350
00351 public:
00352 void Zero();
00353 void Add(const MatrixRowCol&);
00354 void AddScaled(const MatrixRowCol&, Real);
00355 void Add(const MatrixRowCol&, const MatrixRowCol&);
00356
00357 void Add(const MatrixRowCol&, Real);
00358 void NegAdd(const MatrixRowCol&, Real);
00359 void Sub(const MatrixRowCol&);
00360 void Sub(const MatrixRowCol&, const MatrixRowCol&);
00361
00362 void RevSub(const MatrixRowCol&);
00363 void ConCat(const MatrixRowCol&, const MatrixRowCol&);
00364
00365 void Multiply(const MatrixRowCol&);
00366 void Multiply(const MatrixRowCol&, const MatrixRowCol&);
00367
00368 void KP(const MatrixRowCol&, const MatrixRowCol&);
00369
00370 void Copy(const MatrixRowCol&);
00371 void CopyCheck(const MatrixRowCol&);
00372 void Check(const MatrixRowCol&);
00373 void Check();
00374 void Copy(const double*&);
00375 void Copy(const float*&);
00376 void Copy(const int*&);
00377 void Copy(Real);
00378 void Add(Real);
00379 void Multiply(Real);
00380 Real SumAbsoluteValue();
00381 Real MaximumAbsoluteValue1(Real r, int& i);
00382 Real MinimumAbsoluteValue1(Real r, int& i);
00383 Real Maximum1(Real r, int& i);
00384 Real Minimum1(Real r, int& i);
00385 Real Sum();
00386 void Inject(const MatrixRowCol&);
00387 void Negate(const MatrixRowCol&);
00388 void Multiply(const MatrixRowCol&, Real);
00389 friend Real DotProd(const MatrixRowCol&, const MatrixRowCol&);
00390
00391 Real* Data() { return data; }
00392 int Skip() { return skip; }
00393 int Storage() { return storage; }
00394 int Length() { return length; }
00395 void Skip(int i) { skip=i; }
00396 void Storage(int i) { storage=i; }
00397 void Length(int i) { length=i; }
00398 void SubRowCol(MatrixRowCol&, int, int) const;
00399
00400 MatrixRowCol() {}
00401 ~MatrixRowCol();
00402 FREE_CHECK(MatrixRowCol)
00403 };
00404
00407 class MatrixRow : public MatrixRowCol
00408 {
00409 public:
00410
00411 MatrixRow(GeneralMatrix*, LoadAndStoreFlag, int=0);
00412
00413 ~MatrixRow();
00414 void Next();
00415 FREE_CHECK(MatrixRow)
00416 };
00417
00420 class MatrixCol : public MatrixRowCol
00421 {
00422 public:
00423
00424 MatrixCol(GeneralMatrix*, LoadAndStoreFlag, int=0);
00425
00426 MatrixCol(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0);
00427
00428 ~MatrixCol();
00429 void Next();
00430 FREE_CHECK(MatrixCol)
00431 };
00432
00435 class MatrixColX : public MatrixRowCol
00436 {
00437 public:
00438
00439 MatrixColX(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0);
00440
00441 ~MatrixColX();
00442 void Next();
00443 Real* store;
00444
00445 FREE_CHECK(MatrixColX)
00446 };
00447
00448
00449
00450 inline MatrixRow::MatrixRow(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int row)
00451 { gm=gmx; cw=cwx; rowcol=row; gm->GetRow(*this); }
00452
00453 inline void MatrixRow::Next() { gm->NextRow(*this); }
00454
00455 inline MatrixCol::MatrixCol(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int col)
00456 { gm=gmx; cw=cwx; rowcol=col; gm->GetCol(*this); }
00457
00458 inline MatrixCol::MatrixCol(GeneralMatrix* gmx, Real* r,
00459 LoadAndStoreFlag cwx, int col)
00460 { gm=gmx; data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); }
00461
00462 inline MatrixColX::MatrixColX(GeneralMatrix* gmx, Real* r,
00463 LoadAndStoreFlag cwx, int col)
00464 { gm=gmx; store=data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); }
00465
00466
00467 inline void MatrixCol::Next() { gm->NextCol(*this); }
00468
00469 inline void MatrixColX::Next() { gm->NextCol(*this); }
00470
00471 #ifdef use_namespace
00472 }
00473 #endif
00474
00475 #endif
00476
00477
00479
00480 #ifdef use_namespace
00481 namespace NEWMAT {
00482 #endif
00483
00484 #ifdef DO_REPORT
00485 #define REPORT { static ExeCounter ExeCount(__LINE__,1); ++ExeCount; }
00486 #else
00487 #define REPORT {}
00488 #endif
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 MatrixType MatrixType::operator*(const MatrixType& mt) const
00503 {
00504 REPORT
00505 int a = attribute & mt.attribute & ~(Symmetric | Skew);
00506 a |= (a & Diagonal) * 63;
00507 return MatrixType(a);
00508 }
00509
00510 MatrixType MatrixType::SP(const MatrixType& mt) const
00511
00512
00513
00514
00515
00516 {
00517 REPORT
00518 int a = ((attribute | mt.attribute) & ~(Symmetric + Skew + Valid + Ones))
00519 | (attribute & mt.attribute);
00520 if ((a & Lower) != 0 && (a & Upper) != 0) a |= Diagonal;
00521 if ((attribute & Skew) != 0)
00522 {
00523 if ((mt.attribute & Symmetric) != 0) a |= Skew;
00524 if ((mt.attribute & Skew) != 0) { a &= ~Skew; a |= Symmetric; }
00525 }
00526 else if ((mt.attribute & Skew) != 0 && (attribute & Symmetric) != 0)
00527 a |= Skew;
00528 a |= (a & Diagonal) * 63;
00529 return MatrixType(a);
00530 }
00531
00532 MatrixType MatrixType::KP(const MatrixType& mt) const
00533
00534
00535
00536
00537 {
00538 REPORT
00539 int a = (attribute & mt.attribute) & ~Ones;
00540 if ((attribute & Band) != 0 && (mt.attribute & Square) != 0)
00541 a |= Band;
00542
00543
00544 return MatrixType(a);
00545 }
00546
00547 MatrixType MatrixType::i() const
00548 {
00549 REPORT
00550 int a = attribute & ~(Band+LUDeco);
00551 a |= (a & Diagonal) * 63;
00552 return MatrixType(a);
00553 }
00554
00555 MatrixType MatrixType::t() const
00556
00557
00558 {
00559 REPORT
00560 int a = attribute;
00561 a ^= (((a >> 1) ^ a) & Lower) * 3;
00562 return MatrixType(a);
00563 }
00564
00565 MatrixType MatrixType::MultRHS() const
00566 {
00567 REPORT
00568
00569 return (attribute >= Dg) ? attribute : (attribute & ~Symmetric);
00570 }
00571
00572
00573 bool Rectangular(MatrixType a, MatrixType b, MatrixType c)
00574 {
00575 REPORT
00576 return
00577 ((a.attribute | b.attribute | c.attribute)
00578 & ~(MatrixType::Valid | MatrixType::Square)) == 0;
00579 }
00580
00581 const char* MatrixType::value() const
00582 {
00583
00584 switch (attribute)
00585 {
00586 case Valid: REPORT return "Rect ";
00587 case Valid+Square: REPORT return "Squ ";
00588 case Valid+Symmetric+Square: REPORT return "Sym ";
00589 case Valid+Skew+Square: REPORT return "Skew ";
00590 case Valid+Band+Square: REPORT return "Band ";
00591 case Valid+Symmetric+Band+Square: REPORT return "SmBnd";
00592 case Valid+Skew+Band+Square: REPORT return "SkBnd";
00593 case Valid+Upper+Square: REPORT return "UT ";
00594 case Valid+Diagonal+Symmetric+Band+Upper+Lower+Square:
00595 REPORT return "Diag ";
00596 case Valid+Diagonal+Symmetric+Band+Upper+Lower+Ones+Square:
00597 REPORT return "Ident";
00598 case Valid+Band+Upper+Square: REPORT return "UpBnd";
00599 case Valid+Lower+Square: REPORT return "LT ";
00600 case Valid+Band+Lower+Square: REPORT return "LwBnd";
00601 default:
00602 REPORT
00603 if (!(attribute & Valid)) return "UnSp ";
00604 if (attribute & LUDeco)
00605 return (attribute & Band) ? "BndLU" : "Crout";
00606 return "?????";
00607 }
00608 }
00609
00610
00611 GeneralMatrix* MatrixType::New(int nr, int nc, BaseMatrix* bm) const
00612 {
00613
00614
00615 Tracer tr("New"); GeneralMatrix* gm=0;
00616 switch (attribute)
00617 {
00618 case Valid:
00619 REPORT
00620 if (nc==1) { gm = new ColumnVector(nr); break; }
00621 if (nr==1) { gm = new RowVector(nc); break; }
00622 gm = new Matrix(nr, nc); break;
00623
00624 case Valid+Square:
00625 REPORT
00626 if (nc!=nr) { Throw(NotSquareException()); }
00627 gm = new SquareMatrix(nr); break;
00628
00629 case Valid+Symmetric+Square:
00630 REPORT gm = new SymmetricMatrix(nr); break;
00631
00632 case Valid+Band+Square:
00633 {
00634 REPORT
00635 MatrixBandWidth bw = bm->bandwidth();
00636 gm = new BandMatrix(nr,bw.lower_val,bw.upper_val); break;
00637 }
00638
00639 case Valid+Symmetric+Band+Square:
00640 REPORT gm = new SymmetricBandMatrix(nr,bm->bandwidth().lower_val); break;
00641
00642 case Valid+Upper+Square:
00643 REPORT gm = new UpperTriangularMatrix(nr); break;
00644
00645 case Valid+Diagonal+Symmetric+Band+Upper+Lower+Square:
00646 REPORT gm = new DiagonalMatrix(nr); break;
00647
00648 case Valid+Band+Upper+Square:
00649 REPORT gm = new UpperBandMatrix(nr,bm->bandwidth().upper_val); break;
00650
00651 case Valid+Lower+Square:
00652 REPORT gm = new LowerTriangularMatrix(nr); break;
00653
00654 case Valid+Band+Lower+Square:
00655 REPORT gm = new LowerBandMatrix(nr,bm->bandwidth().lower_val); break;
00656
00657 case Valid+Diagonal+Symmetric+Band+Upper+Lower+Ones+Square:
00658 REPORT gm = new IdentityMatrix(nr); break;
00659
00660 default:
00661 Throw(ProgramException("Invalid matrix type"));
00662 }
00663
00664 MatrixErrorNoSpace(gm); gm->Protect(); return gm;
00665 }
00666
00667
00668 #ifdef use_namespace
00669 }
00670 #endif
00671
00672
00673
00677
00680
00681
00682
00683
00684
00685
00686
00687 #ifdef use_namespace
00688 namespace NEWMAT {
00689 #endif
00690
00691
00692
00693 #ifdef DO_REPORT
00694 #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; }
00695 #else
00696 #define REPORT {}
00697 #endif
00698
00699
00700 #define DO_SEARCH // search for LHS of = in RHS
00701
00702
00703
00704 static int tristore(int n)
00705 { return (n*(n+1))/2; }
00706
00707
00708
00709
00710 GeneralMatrix::GeneralMatrix()
00711 { store=0; storage=0; nrows_val=0; ncols_val=0; tag_val=-1; }
00712
00713 GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s)
00714 {
00715 REPORT
00716 storage=s.Value(); tag_val=-1;
00717 if (storage)
00718 {
00719 store = new Real [storage]; MatrixErrorNoSpace(store);
00720 MONITOR_REAL_NEW("Make (GenMatrix)",storage,store)
00721 }
00722 else store = 0;
00723 }
00724
00725 Matrix::Matrix(int m, int n) : GeneralMatrix(m*n)
00726 { REPORT nrows_val=m; ncols_val=n; }
00727
00728 SquareMatrix::SquareMatrix(ArrayLengthSpecifier n)
00729 : Matrix(n.Value(),n.Value())
00730 { REPORT }
00731
00732 SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n)
00733 : GeneralMatrix(tristore(n.Value()))
00734 { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
00735
00736 UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n)
00737 : GeneralMatrix(tristore(n.Value()))
00738 { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
00739
00740 LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n)
00741 : GeneralMatrix(tristore(n.Value()))
00742 { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
00743
00744 DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m)
00745 { REPORT nrows_val=m.Value(); ncols_val=m.Value(); }
00746
00747 Matrix::Matrix(const BaseMatrix& M)
00748 {
00749 REPORT
00750
00751 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt);
00752 GetMatrix(gmx);
00753 }
00754
00755 SquareMatrix::SquareMatrix(const BaseMatrix& M) : Matrix(M)
00756 {
00757 REPORT
00758 if (ncols_val != nrows_val)
00759 {
00760 Tracer tr("SquareMatrix");
00761 Throw(NotSquareException(*this));
00762 }
00763 }
00764
00765
00766 SquareMatrix::SquareMatrix(const Matrix& gm)
00767 {
00768 REPORT
00769 if (gm.ncols_val != gm.nrows_val)
00770 {
00771 Tracer tr("SquareMatrix(Matrix)");
00772 Throw(NotSquareException(gm));
00773 }
00774 GetMatrix(&gm);
00775 }
00776
00777
00778 RowVector::RowVector(const BaseMatrix& M) : Matrix(M)
00779 {
00780 REPORT
00781 if (nrows_val!=1)
00782 {
00783 Tracer tr("RowVector");
00784 Throw(VectorException(*this));
00785 }
00786 }
00787
00788 ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M)
00789 {
00790 REPORT
00791 if (ncols_val!=1)
00792 {
00793 Tracer tr("ColumnVector");
00794 Throw(VectorException(*this));
00795 }
00796 }
00797
00798 SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M)
00799 {
00800 REPORT
00801
00802 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm);
00803 GetMatrix(gmx);
00804 }
00805
00806 UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M)
00807 {
00808 REPORT
00809
00810 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT);
00811 GetMatrix(gmx);
00812 }
00813
00814 LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M)
00815 {
00816 REPORT
00817
00818 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT);
00819 GetMatrix(gmx);
00820 }
00821
00822 DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M)
00823 {
00824 REPORT
00825
00826 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg);
00827 GetMatrix(gmx);
00828 }
00829
00830 IdentityMatrix::IdentityMatrix(const BaseMatrix& M)
00831 {
00832 REPORT
00833
00834 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id);
00835 GetMatrix(gmx);
00836 }
00837
00838 GeneralMatrix::~GeneralMatrix()
00839 {
00840 if (store)
00841 {
00842 MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store)
00843 delete [] store;
00844 }
00845 }
00846
00847 CroutMatrix::CroutMatrix(const BaseMatrix& m)
00848 {
00849 REPORT
00850 Tracer tr("CroutMatrix");
00851 indx = 0;
00852 GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate();
00853 if (gm->nrows_val!=gm->ncols_val)
00854 { gm->tDelete(); Throw(NotSquareException(*gm)); }
00855 if (gm->type() == MatrixType::Ct)
00856 { REPORT ((CroutMatrix*)gm)->get_aux(*this); GetMatrix(gm); }
00857 else
00858 {
00859 REPORT
00860 GeneralMatrix* gm1 = gm->Evaluate(MatrixType::Rt);
00861 GetMatrix(gm1);
00862 d=true; sing=false;
00863 indx=new int [nrows_val]; MatrixErrorNoSpace(indx);
00864 MONITOR_INT_NEW("Index (CroutMat)",nrows_val,indx)
00865 ludcmp();
00866 }
00867 }
00868
00869
00870 void CroutMatrix::get_aux(CroutMatrix& X)
00871 {
00872 X.d = d; X.sing = sing;
00873 if (tag_val == 0 || tag_val == 1)
00874 { REPORT X.indx = indx; indx = 0; d = true; sing = true; return; }
00875 else if (nrows_val == 0)
00876 { REPORT indx = 0; d = true; sing = true; return; }
00877 else
00878 {
00879 REPORT
00880 Tracer tr("CroutMatrix::get_aux");
00881 int *ix = new int [nrows_val]; MatrixErrorNoSpace(ix);
00882 MONITOR_INT_NEW("Index (CM::get_aux)", nrows_val, ix)
00883 int n = nrows_val; int* i = ix; int* j = indx;
00884 while(n--) *i++ = *j++;
00885 X.indx = ix;
00886 }
00887 }
00888
00889 CroutMatrix::CroutMatrix(const CroutMatrix& gm) : GeneralMatrix()
00890 {
00891 REPORT
00892 Tracer tr("CroutMatrix(const CroutMatrix&)");
00893 ((CroutMatrix&)gm).get_aux(*this);
00894 GetMatrix(&gm);
00895 }
00896
00897 CroutMatrix::~CroutMatrix()
00898 {
00899 MONITOR_INT_DELETE("Index (CroutMat)",nrows_val,indx)
00900 delete [] indx;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910 GeneralMatrix::operator ReturnMatrix() const
00911 {
00912 REPORT
00913 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00914 return ReturnMatrix(gm);
00915 }
00916
00917
00918
00919 ReturnMatrix GeneralMatrix::for_return() const
00920 {
00921 REPORT
00922 GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
00923 return ReturnMatrix(gm);
00924 }
00925
00926
00927
00928 #ifdef SETUP_C_SUBSCRIPTS
00929
00930 Matrix::Matrix(Real a, int m, int n) : GeneralMatrix(m * n)
00931 { REPORT nrows_val=m; ncols_val=n; operator=(a); }
00932
00933 Matrix::Matrix(const Real* a, int m, int n) : GeneralMatrix(m * n)
00934 { REPORT nrows_val=m; ncols_val=n; *this << a; }
00935
00936 #endif
00937
00938
00939
00940
00941
00942 void GeneralMatrix::resize(int nr, int nc, int s)
00943 {
00944 REPORT
00945 if (store)
00946 {
00947 MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store)
00948 delete [] store;
00949 }
00950 storage=s; nrows_val=nr; ncols_val=nc; tag_val=-1;
00951 if (s)
00952 {
00953 store = new Real [storage]; MatrixErrorNoSpace(store);
00954 MONITOR_REAL_NEW("Make (ReDimensi)",storage,store)
00955 }
00956 else store = 0;
00957 }
00958
00959 void Matrix::resize(int nr, int nc)
00960 { REPORT GeneralMatrix::resize(nr,nc,nr*nc); }
00961
00962 void SquareMatrix::resize(int n)
00963 { REPORT GeneralMatrix::resize(n,n,n*n); }
00964
00965 void SquareMatrix::resize(int nr, int nc)
00966 {
00967 REPORT
00968 Tracer tr("SquareMatrix::resize");
00969 if (nc != nr) Throw(NotSquareException(*this));
00970 GeneralMatrix::resize(nr,nc,nr*nc);
00971 }
00972
00973 void SymmetricMatrix::resize(int nr)
00974 { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
00975
00976 void UpperTriangularMatrix::resize(int nr)
00977 { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
00978
00979 void LowerTriangularMatrix::resize(int nr)
00980 { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
00981
00982 void DiagonalMatrix::resize(int nr)
00983 { REPORT GeneralMatrix::resize(nr,nr,nr); }
00984
00985 void RowVector::resize(int nc)
00986 { REPORT GeneralMatrix::resize(1,nc,nc); }
00987
00988 void ColumnVector::resize(int nr)
00989 { REPORT GeneralMatrix::resize(nr,1,nr); }
00990
00991 void RowVector::resize(int nr, int nc)
00992 {
00993 Tracer tr("RowVector::resize");
00994 if (nr != 1) Throw(VectorException(*this));
00995 REPORT GeneralMatrix::resize(1,nc,nc);
00996 }
00997
00998 void ColumnVector::resize(int nr, int nc)
00999 {
01000 Tracer tr("ColumnVector::resize");
01001 if (nc != 1) Throw(VectorException(*this));
01002 REPORT GeneralMatrix::resize(nr,1,nr);
01003 }
01004
01005 void IdentityMatrix::resize(int nr)
01006 { REPORT GeneralMatrix::resize(nr,nr,1); *store = 1; }
01007
01008
01009 void Matrix::resize(const GeneralMatrix& A)
01010 { REPORT resize(A.Nrows(), A.Ncols()); }
01011
01012 void SquareMatrix::resize(const GeneralMatrix& A)
01013 {
01014 REPORT
01015 int n = A.Nrows();
01016 if (n != A.Ncols())
01017 {
01018 Tracer tr("SquareMatrix::resize(GM)");
01019 Throw(NotSquareException(*this));
01020 }
01021 resize(n);
01022 }
01023
01024 void nricMatrix::resize(const GeneralMatrix& A)
01025 { REPORT resize(A.Nrows(), A.Ncols()); }
01026
01027 void ColumnVector::resize(const GeneralMatrix& A)
01028 { REPORT resize(A.Nrows(), A.Ncols()); }
01029
01030 void RowVector::resize(const GeneralMatrix& A)
01031 { REPORT resize(A.Nrows(), A.Ncols()); }
01032
01033 void SymmetricMatrix::resize(const GeneralMatrix& A)
01034 {
01035 REPORT
01036 int n = A.Nrows();
01037 if (n != A.Ncols())
01038 {
01039 Tracer tr("SymmetricMatrix::resize(GM)");
01040 Throw(NotSquareException(*this));
01041 }
01042 resize(n);
01043 }
01044
01045 void DiagonalMatrix::resize(const GeneralMatrix& A)
01046 {
01047 REPORT
01048 int n = A.Nrows();
01049 if (n != A.Ncols())
01050 {
01051 Tracer tr("DiagonalMatrix::resize(GM)");
01052 Throw(NotSquareException(*this));
01053 }
01054 resize(n);
01055 }
01056
01057 void UpperTriangularMatrix::resize(const GeneralMatrix& A)
01058 {
01059 REPORT
01060 int n = A.Nrows();
01061 if (n != A.Ncols())
01062 {
01063 Tracer tr("UpperTriangularMatrix::resize(GM)");
01064 Throw(NotSquareException(*this));
01065 }
01066 resize(n);
01067 }
01068
01069 void LowerTriangularMatrix::resize(const GeneralMatrix& A)
01070 {
01071 REPORT
01072 int n = A.Nrows();
01073 if (n != A.Ncols())
01074 {
01075 Tracer tr("LowerTriangularMatrix::resize(GM)");
01076 Throw(NotSquareException(*this));
01077 }
01078 resize(n);
01079 }
01080
01081 void IdentityMatrix::resize(const GeneralMatrix& A)
01082 {
01083 REPORT
01084 int n = A.Nrows();
01085 if (n != A.Ncols())
01086 {
01087 Tracer tr("IdentityMatrix::resize(GM)");
01088 Throw(NotSquareException(*this));
01089 }
01090 resize(n);
01091 }
01092
01093 void GeneralMatrix::resize(const GeneralMatrix&)
01094 {
01095 REPORT
01096 Tracer tr("GeneralMatrix::resize(GM)");
01097 Throw(NotDefinedException("resize", "this type of matrix"));
01098 }
01099
01100
01101
01102 void Matrix::resize_keep(int nr, int nc)
01103 {
01104 Tracer tr("Matrix::resize_keep");
01105 if (nr == nrows_val && nc == ncols_val) { REPORT return; }
01106
01107 if (nr <= nrows_val && nc <= ncols_val)
01108 {
01109 REPORT
01110 Matrix X = submatrix(1,nr,1,nc);
01111 swap(X);
01112 }
01113 else if (nr >= nrows_val && nc >= ncols_val)
01114 {
01115 REPORT
01116 Matrix X(nr, nc); X = 0;
01117 X.submatrix(1,nrows_val,1,ncols_val) = *this;
01118 swap(X);
01119 }
01120 else
01121 {
01122 REPORT
01123 Matrix X(nr, nc); X = 0;
01124 if (nr > nrows_val) nr = nrows_val;
01125 if (nc > ncols_val) nc = ncols_val;
01126 X.submatrix(1,nr,1,nc) = submatrix(1,nr,1,nc);
01127 swap(X);
01128 }
01129 }
01130
01131 void SquareMatrix::resize_keep(int nr)
01132 {
01133 Tracer tr("SquareMatrix::resize_keep");
01134 if (nr < nrows_val)
01135 {
01136 REPORT
01137 SquareMatrix X = sym_submatrix(1,nr);
01138 swap(X);
01139 }
01140 else if (nr > nrows_val)
01141 {
01142 REPORT
01143 SquareMatrix X(nr); X = 0;
01144 X.sym_submatrix(1,nrows_val) = *this;
01145 swap(X);
01146 }
01147 }
01148
01149 void SquareMatrix::resize_keep(int nr, int nc)
01150 {
01151 Tracer tr("SquareMatrix::resize_keep 2");
01152 REPORT
01153 if (nr != nc) Throw(NotSquareException(*this));
01154 resize_keep(nr);
01155 }
01156
01157
01158 void SymmetricMatrix::resize_keep(int nr)
01159 {
01160 Tracer tr("SymmetricMatrix::resize_keep");
01161 if (nr < nrows_val)
01162 {
01163 REPORT
01164 SymmetricMatrix X = sym_submatrix(1,nr);
01165 swap(X);
01166 }
01167 else if (nr > nrows_val)
01168 {
01169 REPORT
01170 SymmetricMatrix X(nr); X = 0;
01171 X.sym_submatrix(1,nrows_val) = *this;
01172 swap(X);
01173 }
01174 }
01175
01176 void UpperTriangularMatrix::resize_keep(int nr)
01177 {
01178 Tracer tr("UpperTriangularMatrix::resize_keep");
01179 if (nr < nrows_val)
01180 {
01181 REPORT
01182 UpperTriangularMatrix X = sym_submatrix(1,nr);
01183 swap(X);
01184 }
01185 else if (nr > nrows_val)
01186 {
01187 REPORT
01188 UpperTriangularMatrix X(nr); X = 0;
01189 X.sym_submatrix(1,nrows_val) = *this;
01190 swap(X);
01191 }
01192 }
01193
01194 void LowerTriangularMatrix::resize_keep(int nr)
01195 {
01196 Tracer tr("LowerTriangularMatrix::resize_keep");
01197 if (nr < nrows_val)
01198 {
01199 REPORT
01200 LowerTriangularMatrix X = sym_submatrix(1,nr);
01201 swap(X);
01202 }
01203 else if (nr > nrows_val)
01204 {
01205 REPORT
01206 LowerTriangularMatrix X(nr); X = 0;
01207 X.sym_submatrix(1,nrows_val) = *this;
01208 swap(X);
01209 }
01210 }
01211
01212 void DiagonalMatrix::resize_keep(int nr)
01213 {
01214 Tracer tr("DiagonalMatrix::resize_keep");
01215 if (nr < nrows_val)
01216 {
01217 REPORT
01218 DiagonalMatrix X = sym_submatrix(1,nr);
01219 swap(X);
01220 }
01221 else if (nr > nrows_val)
01222 {
01223 REPORT
01224 DiagonalMatrix X(nr); X = 0;
01225 X.sym_submatrix(1,nrows_val) = *this;
01226 swap(X);
01227 }
01228 }
01229
01230 void RowVector::resize_keep(int nc)
01231 {
01232 Tracer tr("RowVector::resize_keep");
01233 if (nc < ncols_val)
01234 {
01235 REPORT
01236 RowVector X = columns(1,nc);
01237 swap(X);
01238 }
01239 else if (nc > ncols_val)
01240 {
01241 REPORT
01242 RowVector X(nc); X = 0;
01243 X.columns(1,ncols_val) = *this;
01244 swap(X);
01245 }
01246 }
01247
01248 void RowVector::resize_keep(int nr, int nc)
01249 {
01250 Tracer tr("RowVector::resize_keep 2");
01251 REPORT
01252 if (nr != 1) Throw(VectorException(*this));
01253 resize_keep(nc);
01254 }
01255
01256 void ColumnVector::resize_keep(int nr)
01257 {
01258 Tracer tr("ColumnVector::resize_keep");
01259 if (nr < nrows_val)
01260 {
01261 REPORT
01262 ColumnVector X = rows(1,nr);
01263 swap(X);
01264 }
01265 else if (nr > nrows_val)
01266 {
01267 REPORT
01268 ColumnVector X(nr); X = 0;
01269 X.rows(1,nrows_val) = *this;
01270 swap(X);
01271 }
01272 }
01273
01274 void ColumnVector::resize_keep(int nr, int nc)
01275 {
01276 Tracer tr("ColumnVector::resize_keep 2");
01277 REPORT
01278 if (nc != 1) Throw(VectorException(*this));
01279 resize_keep(nr);
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 int GeneralMatrix::search(const BaseMatrix* s) const
01306 { REPORT return (s==this) ? 1 : 0; }
01307
01308 int GenericMatrix::search(const BaseMatrix* s) const
01309 { REPORT return gm->search(s); }
01310
01311 int MultipliedMatrix::search(const BaseMatrix* s) const
01312 { REPORT return bm1->search(s) + bm2->search(s); }
01313
01314 int ShiftedMatrix::search(const BaseMatrix* s) const
01315 { REPORT return bm->search(s); }
01316
01317 int NegatedMatrix::search(const BaseMatrix* s) const
01318 { REPORT return bm->search(s); }
01319
01320 int ReturnMatrix::search(const BaseMatrix* s) const
01321 { REPORT return (s==gm) ? 1 : 0; }
01322
01323 MatrixType Matrix::type() const { return MatrixType::Rt; }
01324 MatrixType SquareMatrix::type() const { return MatrixType::Sq; }
01325 MatrixType SymmetricMatrix::type() const { return MatrixType::Sm; }
01326 MatrixType UpperTriangularMatrix::type() const { return MatrixType::UT; }
01327 MatrixType LowerTriangularMatrix::type() const { return MatrixType::LT; }
01328 MatrixType DiagonalMatrix::type() const { return MatrixType::Dg; }
01329 MatrixType RowVector::type() const { return MatrixType::RV; }
01330 MatrixType ColumnVector::type() const { return MatrixType::CV; }
01331 MatrixType CroutMatrix::type() const { return MatrixType::Ct; }
01332 MatrixType BandMatrix::type() const { return MatrixType::BM; }
01333 MatrixType UpperBandMatrix::type() const { return MatrixType::UB; }
01334 MatrixType LowerBandMatrix::type() const { return MatrixType::LB; }
01335 MatrixType SymmetricBandMatrix::type() const { return MatrixType::SB; }
01336
01337 MatrixType IdentityMatrix::type() const { return MatrixType::Id; }
01338
01339
01340
01341 MatrixBandWidth BaseMatrix::bandwidth() const { REPORT return -1; }
01342 MatrixBandWidth DiagonalMatrix::bandwidth() const { REPORT return 0; }
01343 MatrixBandWidth IdentityMatrix::bandwidth() const { REPORT return 0; }
01344
01345 MatrixBandWidth UpperTriangularMatrix::bandwidth() const
01346 { REPORT return MatrixBandWidth(0,-1); }
01347
01348 MatrixBandWidth LowerTriangularMatrix::bandwidth() const
01349 { REPORT return MatrixBandWidth(-1,0); }
01350
01351 MatrixBandWidth BandMatrix::bandwidth() const
01352 { REPORT return MatrixBandWidth(lower_val,upper_val); }
01353
01354 MatrixBandWidth BandLUMatrix::bandwidth() const
01355 { REPORT return MatrixBandWidth(m1,m2); }
01356
01357 MatrixBandWidth GenericMatrix::bandwidth()const
01358 { REPORT return gm->bandwidth(); }
01359
01360 MatrixBandWidth AddedMatrix::bandwidth() const
01361 { REPORT return gm1->bandwidth() + gm2->bandwidth(); }
01362
01363 MatrixBandWidth SPMatrix::bandwidth() const
01364 { REPORT return gm1->bandwidth().minimum(gm2->bandwidth()); }
01365
01366 MatrixBandWidth KPMatrix::bandwidth() const
01367 {
01368 int lower, upper;
01369 MatrixBandWidth bw1 = gm1->bandwidth(), bw2 = gm2->bandwidth();
01370 if (bw1.Lower() < 0)
01371 {
01372 if (bw2.Lower() < 0) { REPORT lower = -1; }
01373 else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); }
01374 }
01375 else
01376 {
01377 if (bw2.Lower() < 0)
01378 { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; }
01379 else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); }
01380 }
01381 if (bw1.Upper() < 0)
01382 {
01383 if (bw2.Upper() < 0) { REPORT upper = -1; }
01384 else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); }
01385 }
01386 else
01387 {
01388 if (bw2.Upper() < 0)
01389 { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; }
01390 else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); }
01391 }
01392 return MatrixBandWidth(lower, upper);
01393 }
01394
01395 MatrixBandWidth MultipliedMatrix::bandwidth() const
01396 { REPORT return gm1->bandwidth() * gm2->bandwidth(); }
01397
01398 MatrixBandWidth ConcatenatedMatrix::bandwidth() const { REPORT return -1; }
01399
01400 MatrixBandWidth SolvedMatrix::bandwidth() const
01401 {
01402 if (+gm1->type() & MatrixType::Diagonal)
01403 { REPORT return gm2->bandwidth(); }
01404 else { REPORT return -1; }
01405 }
01406
01407 MatrixBandWidth ScaledMatrix::bandwidth() const
01408 { REPORT return gm->bandwidth(); }
01409
01410 MatrixBandWidth NegatedMatrix::bandwidth() const
01411 { REPORT return gm->bandwidth(); }
01412
01413 MatrixBandWidth TransposedMatrix::bandwidth() const
01414 { REPORT return gm->bandwidth().t(); }
01415
01416 MatrixBandWidth InvertedMatrix::bandwidth() const
01417 {
01418 if (+gm->type() & MatrixType::Diagonal)
01419 { REPORT return MatrixBandWidth(0,0); }
01420 else { REPORT return -1; }
01421 }
01422
01423 MatrixBandWidth RowedMatrix::bandwidth() const { REPORT return -1; }
01424 MatrixBandWidth ColedMatrix::bandwidth() const { REPORT return -1; }
01425 MatrixBandWidth DiagedMatrix::bandwidth() const { REPORT return 0; }
01426 MatrixBandWidth MatedMatrix::bandwidth() const { REPORT return -1; }
01427 MatrixBandWidth ReturnMatrix::bandwidth() const
01428 { REPORT return gm->bandwidth(); }
01429
01430 MatrixBandWidth GetSubMatrix::bandwidth() const
01431 {
01432
01433 if (row_skip==col_skip && row_number==col_number)
01434 { REPORT return gm->bandwidth(); }
01435 else { REPORT return MatrixBandWidth(-1); }
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 void GeneralMatrix::tDelete()
01457 {
01458 if (tag_val<0)
01459 {
01460 if (tag_val<-1) { REPORT store = 0; delete this; return; }
01461 else { REPORT return; }
01462 }
01463 if (tag_val==1)
01464 {
01465 if (store)
01466 {
01467 REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store)
01468 delete [] store;
01469 }
01470 MiniCleanUp(); return;
01471 }
01472 if (tag_val==0) { REPORT delete this; return; }
01473
01474 REPORT tag_val--; return;
01475 }
01476
01477 void newmat_block_copy(int n, Real* from, Real* to)
01478 {
01479 REPORT
01480 int i = (n >> 3);
01481 while (i--)
01482 {
01483 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
01484 *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
01485 }
01486 i = n & 7; while (i--) *to++ = *from++;
01487 }
01488
01489 bool GeneralMatrix::reuse()
01490 {
01491 if (tag_val < -1)
01492 {
01493 if (storage)
01494 {
01495 REPORT
01496 Real* s = new Real [storage]; MatrixErrorNoSpace(s);
01497 MONITOR_REAL_NEW("Make (reuse)",storage,s)
01498 newmat_block_copy(storage, store, s); store = s;
01499 }
01500 else { REPORT MiniCleanUp(); }
01501 tag_val = 0; return true;
01502 }
01503 if (tag_val < 0 ) { REPORT return false; }
01504 if (tag_val <= 1 ) { REPORT return true; }
01505 REPORT tag_val--; return false;
01506 }
01507
01508 Real* GeneralMatrix::GetStore()
01509 {
01510 if (tag_val<0 || tag_val>1)
01511 {
01512 Real* s;
01513 if (storage)
01514 {
01515 s = new Real [storage]; MatrixErrorNoSpace(s);
01516 MONITOR_REAL_NEW("Make (GetStore)",storage,s)
01517 newmat_block_copy(storage, store, s);
01518 }
01519 else s = 0;
01520 if (tag_val > 1) { REPORT tag_val--; }
01521 else if (tag_val < -1) { REPORT store = 0; delete this; }
01522 else { REPORT }
01523 return s;
01524 }
01525 Real* s = store;
01526 if (tag_val==0) { REPORT store = 0; delete this; }
01527 else { REPORT MiniCleanUp(); }
01528 return s;
01529 }
01530
01531 void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx)
01532 {
01533 REPORT tag_val=-1; nrows_val=gmx->Nrows(); ncols_val=gmx->Ncols();
01534 storage=gmx->storage; SetParameters(gmx);
01535 store=((GeneralMatrix*)gmx)->GetStore();
01536 }
01537
01538 GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt)
01539
01540
01541 {
01542 if (!mt)
01543 {
01544 if (tag_val == -1) { REPORT gmx->tag_val = -2; gmx->store = store; }
01545 else { REPORT gmx->tag_val = 0; gmx->store = GetStore(); }
01546 }
01547 else if (Compare(gmx->type(),mt))
01548 { REPORT gmx->tag_val = 0; gmx->store = GetStore(); }
01549 else
01550 {
01551 REPORT gmx->tag_val = -2; gmx->store = store;
01552 gmx = gmx->Evaluate(mt); gmx->tag_val = 0; tDelete();
01553 }
01554
01555 return gmx;
01556 }
01557
01558 void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt)
01559
01560
01561
01562
01563 {
01564 #ifdef DO_SEARCH
01565 int counter=X.search(this);
01566 if (counter==0)
01567 {
01568 REPORT
01569 if (store)
01570 {
01571 MONITOR_REAL_DELETE("Free (operator=)",storage,store)
01572 REPORT delete [] store; storage = 0; store = 0;
01573 }
01574 }
01575 else { REPORT Release(counter); }
01576 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
01577 if (gmx!=this) { REPORT GetMatrix(gmx); }
01578 else { REPORT }
01579 Protect();
01580 #else
01581 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
01582 if (gmx!=this)
01583 {
01584 REPORT
01585 if (store)
01586 {
01587 MONITOR_REAL_DELETE("Free (operator=)",storage,store)
01588 REPORT delete [] store; storage = 0; store = 0;
01589 }
01590 GetMatrix(gmx);
01591 }
01592 else { REPORT }
01593 Protect();
01594 #endif
01595 }
01596
01597
01598 void GeneralMatrix::Eq(const GeneralMatrix& X)
01599 {
01600 GeneralMatrix* gmx = (GeneralMatrix*)&X;
01601 if (gmx!=this)
01602 {
01603 REPORT
01604 if (store)
01605 {
01606 MONITOR_REAL_DELETE("Free (operator=)",storage,store)
01607 REPORT delete [] store; storage = 0; store = 0;
01608 }
01609 GetMatrix(gmx);
01610 }
01611 else { REPORT }
01612 Protect();
01613 }
01614
01615
01616 void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok)
01617 {
01618 REPORT
01619 if (ldok) mt.SetDataLossOK();
01620 Eq(X, mt);
01621 }
01622
01623 void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt)
01624
01625
01626
01627
01628 {
01629 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
01630 if (gmx!=this) { REPORT GetMatrix(gmx); }
01631 else { REPORT }
01632 Protect();
01633 }
01634
01635 void GeneralMatrix::inject(const GeneralMatrix& X)
01636
01637 {
01638 REPORT
01639 Tracer tr("inject");
01640 if (nrows_val != X.nrows_val || ncols_val != X.ncols_val)
01641 Throw(IncompatibleDimensionsException());
01642 MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
01643 MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart);
01644 int i=nrows_val;
01645 while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); }
01646 }
01647
01648
01649
01650 bool Compare(const MatrixType& source, MatrixType& destination)
01651 {
01652 if (!destination) { destination=source; return true; }
01653 if (destination==source) return true;
01654 if (!destination.DataLossOK && !(destination>=source))
01655 Throw(ProgramException("Illegal Conversion", source, destination));
01656 return false;
01657 }
01658
01659
01660
01661 GeneralMatrix* Matrix::Image() const
01662 {
01663 REPORT
01664 GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm);
01665 return gm;
01666 }
01667
01668 GeneralMatrix* SquareMatrix::Image() const
01669 {
01670 REPORT
01671 GeneralMatrix* gm = new SquareMatrix(*this); MatrixErrorNoSpace(gm);
01672 return gm;
01673 }
01674
01675 GeneralMatrix* SymmetricMatrix::Image() const
01676 {
01677 REPORT
01678 GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm);
01679 return gm;
01680 }
01681
01682 GeneralMatrix* UpperTriangularMatrix::Image() const
01683 {
01684 REPORT
01685 GeneralMatrix* gm = new UpperTriangularMatrix(*this);
01686 MatrixErrorNoSpace(gm); return gm;
01687 }
01688
01689 GeneralMatrix* LowerTriangularMatrix::Image() const
01690 {
01691 REPORT
01692 GeneralMatrix* gm = new LowerTriangularMatrix(*this);
01693 MatrixErrorNoSpace(gm); return gm;
01694 }
01695
01696 GeneralMatrix* DiagonalMatrix::Image() const
01697 {
01698 REPORT
01699 GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm);
01700 return gm;
01701 }
01702
01703 GeneralMatrix* RowVector::Image() const
01704 {
01705 REPORT
01706 GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm);
01707 return gm;
01708 }
01709
01710 GeneralMatrix* ColumnVector::Image() const
01711 {
01712 REPORT
01713 GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm);
01714 return gm;
01715 }
01716
01717 GeneralMatrix* nricMatrix::Image() const
01718 {
01719 REPORT
01720 GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm);
01721 return gm;
01722 }
01723
01724 GeneralMatrix* IdentityMatrix::Image() const
01725 {
01726 REPORT
01727 GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm);
01728 return gm;
01729 }
01730
01731 GeneralMatrix* CroutMatrix::Image() const
01732 {
01733 REPORT
01734 GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm);
01735 return gm;
01736 }
01737
01738 GeneralMatrix* GeneralMatrix::Image() const
01739 {
01740 bool dummy = true;
01741 if (dummy)
01742 Throw(InternalException("Cannot apply Image to this matrix type"));
01743 return 0;
01744 }
01745
01746
01747
01748
01749 void nricMatrix::MakeRowPointer()
01750 {
01751 REPORT
01752 if (nrows_val > 0)
01753 {
01754 row_pointer = new Real* [nrows_val]; MatrixErrorNoSpace(row_pointer);
01755 Real* s = Store() - 1; int i = nrows_val; Real** rp = row_pointer;
01756 if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols_val; }
01757 }
01758 else row_pointer = 0;
01759 }
01760
01761 void nricMatrix::DeleteRowPointer()
01762 { REPORT if (nrows_val) delete [] row_pointer; }
01763
01764 void GeneralMatrix::CheckStore() const
01765 {
01766 REPORT
01767 if (!store)
01768 Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
01769 }
01770
01771
01772
01773
01774 void GeneralMatrix::cleanup()
01775 {
01776
01777 REPORT
01778 if (store && storage)
01779 {
01780 MONITOR_REAL_DELETE("Free (cleanup) ",storage,store)
01781 REPORT delete [] store;
01782 }
01783 store=0; storage=0; nrows_val=0; ncols_val=0; tag_val = -1;
01784 }
01785
01786 void nricMatrix::cleanup()
01787 { REPORT DeleteRowPointer(); GeneralMatrix::cleanup(); }
01788
01789 void nricMatrix::MiniCleanUp()
01790 { REPORT DeleteRowPointer(); GeneralMatrix::MiniCleanUp(); }
01791
01792 void RowVector::cleanup()
01793 { REPORT GeneralMatrix::cleanup(); nrows_val=1; }
01794
01795 void ColumnVector::cleanup()
01796 { REPORT GeneralMatrix::cleanup(); ncols_val=1; }
01797
01798 void CroutMatrix::cleanup()
01799 {
01800 REPORT
01801 if (nrows_val) delete [] indx;
01802 GeneralMatrix::cleanup();
01803 }
01804
01805 void CroutMatrix::MiniCleanUp()
01806 {
01807 REPORT
01808 if (nrows_val) delete [] indx;
01809 GeneralMatrix::MiniCleanUp();
01810 }
01811
01812 void BandLUMatrix::cleanup()
01813 {
01814 REPORT
01815 if (nrows_val) delete [] indx;
01816 if (storage2) delete [] store2;
01817 GeneralMatrix::cleanup();
01818 }
01819
01820 void BandLUMatrix::MiniCleanUp()
01821 {
01822 REPORT
01823 if (nrows_val) delete [] indx;
01824 if (storage2) delete [] store2;
01825 GeneralMatrix::MiniCleanUp();
01826 }
01827
01828
01829
01830
01831
01832
01833 SimpleIntArray::SimpleIntArray(int xn) : n(xn)
01834 {
01835 if (n < 0) Throw(Logic_error("invalid array length"));
01836 else if (n == 0) { REPORT a = 0; }
01837 else { REPORT a = new int [n]; if (!a) Throw(Bad_alloc()); }
01838 }
01839
01840
01841
01842 SimpleIntArray::~SimpleIntArray() { REPORT if (a) delete [] a; }
01843
01844
01845
01846
01847
01848
01849 int& SimpleIntArray::operator[](int i)
01850 {
01851 REPORT
01852 if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
01853 return a[i];
01854 }
01855
01856
01857
01858
01859 int SimpleIntArray::operator[](int i) const
01860 {
01861 REPORT
01862 if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
01863 return a[i];
01864 }
01865
01866
01867
01868 void SimpleIntArray::operator=(int ai)
01869 { REPORT for (int i = 0; i < n; i++) a[i] = ai; }
01870
01871
01872
01873
01874 void SimpleIntArray::operator=(const SimpleIntArray& b)
01875 {
01876 REPORT
01877 if (b.n != n) resize(b.n);
01878 for (int i = 0; i < n; i++) a[i] = b.a[i];
01879 }
01880
01881
01882
01883
01884 SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : Janitor(), n(b.n)
01885 {
01886 if (n == 0) { REPORT a = 0; }
01887 else
01888 {
01889 REPORT
01890 a = new int [n]; if (!a) Throw(Bad_alloc());
01891 for (int i = 0; i < n; i++) a[i] = b.a[i];
01892 }
01893 }
01894
01895
01896
01897
01898 void SimpleIntArray::resize(int n1, bool keep)
01899 {
01900 if (n1 == n) { REPORT return; }
01901 else if (n1 == 0) { REPORT n = 0; delete [] a; a = 0; }
01902 else if (n == 0)
01903 {
01904 REPORT
01905 a = new int [n1]; if (!a) Throw(Bad_alloc());
01906 n = n1;
01907 if (keep) operator=(0);
01908 }
01909 else
01910 {
01911 int* a1 = a;
01912 if (keep)
01913 {
01914 REPORT
01915 int i;
01916 a = new int [n1]; if (!a) Throw(Bad_alloc());
01917 if (n > n1) n = n1;
01918 else for (i = n; i < n1; i++) a[i] = 0;
01919 for (i = 0; i < n; i++) a[i] = a1[i];
01920 n = n1; delete [] a1;
01921 }
01922 else
01923 {
01924 REPORT n = n1; delete [] a1;
01925 a = new int [n]; if (!a) Throw(Bad_alloc());
01926 }
01927 }
01928 }
01929
01930
01931
01932
01933
01934 void GeneralMatrix::swap(GeneralMatrix& gm)
01935 {
01936 REPORT
01937 int t;
01938 t = tag_val; tag_val = gm.tag_val; gm.tag_val = t;
01939 t = nrows_val; nrows_val = gm.nrows_val; gm.nrows_val = t;
01940 t = ncols_val; ncols_val = gm.ncols_val; gm.ncols_val = t;
01941 t = storage; storage = gm.storage; gm.storage = t;
01942 Real* s = store; store = gm.store; gm.store = s;
01943 }
01944
01945 void nricMatrix::swap(nricMatrix& gm)
01946 {
01947 REPORT
01948 GeneralMatrix::swap((GeneralMatrix&)gm);
01949 Real** rp = row_pointer; row_pointer = gm.row_pointer; gm.row_pointer = rp;
01950 }
01951
01952 void CroutMatrix::swap(CroutMatrix& gm)
01953 {
01954 REPORT
01955 GeneralMatrix::swap((GeneralMatrix&)gm);
01956 int* i = indx; indx = gm.indx; gm.indx = i;
01957 bool b;
01958 b = d; d = gm.d; gm.d = b;
01959 b = sing; sing = gm.sing; gm.sing = b;
01960 }
01961
01962 void BandMatrix::swap(BandMatrix& gm)
01963 {
01964 REPORT
01965 GeneralMatrix::swap((GeneralMatrix&)gm);
01966 int i;
01967 i = lower_val; lower_val = gm.lower_val; gm.lower_val = i;
01968 i = upper_val; upper_val = gm.upper_val; gm.upper_val = i;
01969 }
01970
01971 void SymmetricBandMatrix::swap(SymmetricBandMatrix& gm)
01972 {
01973 REPORT
01974 GeneralMatrix::swap((GeneralMatrix&)gm);
01975 int i;
01976 i = lower_val; lower_val = gm.lower_val; gm.lower_val = i;
01977 }
01978
01979 void BandLUMatrix::swap(BandLUMatrix& gm)
01980 {
01981 REPORT
01982 GeneralMatrix::swap((GeneralMatrix&)gm);
01983 int* i = indx; indx = gm.indx; gm.indx = i;
01984 bool b;
01985 b = d; d = gm.d; gm.d = b;
01986 b = sing; sing = gm.sing; gm.sing = b;
01987 int m;
01988 m = storage2; storage2 = gm.storage2; gm.storage2 = m;
01989 m = m1; m1 = gm.m1; gm.m1 = m;
01990 m = m2; m2 = gm.m2; gm.m2 = m;
01991 Real* s = store2; store2 = gm.store2; gm.store2 = s;
01992 }
01993
01994 void GenericMatrix::swap(GenericMatrix& x)
01995 {
01996 REPORT
01997 GeneralMatrix* tgm = gm; gm = x.gm; x.gm = tgm;
01998 }
01999
02000
02001
02002 RealStarStar::RealStarStar(Matrix& A)
02003 {
02004 REPORT
02005 Tracer tr("RealStarStar");
02006 int n = A.ncols();
02007 int m = A.nrows();
02008 a = new Real*[m];
02009 MatrixErrorNoSpace(a);
02010 Real* d = A.data();
02011 for (int i = 0; i < m; ++i) a[i] = d + i * n;
02012 }
02013
02014 ConstRealStarStar::ConstRealStarStar(const Matrix& A)
02015 {
02016 REPORT
02017 Tracer tr("ConstRealStarStar");
02018 int n = A.ncols();
02019 int m = A.nrows();
02020 a = new const Real*[m];
02021 MatrixErrorNoSpace(a);
02022 const Real* d = A.data();
02023 for (int i = 0; i < m; ++i) a[i] = d + i * n;
02024 }
02025
02026
02027
02028 #ifdef use_namespace
02029 }
02030 #endif
02031
02032
02050
02051
02052
02053
02054
02055
02056
02060
02063
02064
02065
02066
02067
02068 #ifdef use_namespace
02069 namespace NEWMAT {
02070 #endif
02071
02072
02073 #ifdef DO_REPORT
02074 #define REPORT { static ExeCounter ExeCount(__LINE__,5); ++ExeCount; }
02075 #else
02076 #define REPORT {}
02077 #endif
02078
02079
02080
02081
02082
02083 GeneralMatrix* GeneralMatrix::Transpose(TransposedMatrix* tm, MatrixType mt)
02084 {
02085 GeneralMatrix* gm1;
02086
02087 if (Compare(Type().t(),mt))
02088 {
02089 REPORT
02090 gm1 = mt.New(ncols_val,nrows_val,tm);
02091 for (int i=0; i<ncols_val; i++)
02092 {
02093 MatrixRow mr(gm1, StoreOnExit+DirectPart, i);
02094 MatrixCol mc(this, mr.Data(), LoadOnEntry, i);
02095 }
02096 }
02097 else
02098 {
02099 REPORT
02100 gm1 = mt.New(ncols_val,nrows_val,tm);
02101 MatrixRow mr(this, LoadOnEntry);
02102 MatrixCol mc(gm1, StoreOnExit+DirectPart);
02103 int i = nrows_val;
02104 while (i--) { mc.Copy(mr); mr.Next(); mc.Next(); }
02105 }
02106 tDelete(); gm1->ReleaseAndDelete(); return gm1;
02107 }
02108
02109 GeneralMatrix* SymmetricMatrix::Transpose(TransposedMatrix*, MatrixType mt)
02110 { REPORT return Evaluate(mt); }
02111
02112
02113 GeneralMatrix* DiagonalMatrix::Transpose(TransposedMatrix*, MatrixType mt)
02114 { REPORT return Evaluate(mt); }
02115
02116 GeneralMatrix* ColumnVector::Transpose(TransposedMatrix*, MatrixType mt)
02117 {
02118 REPORT
02119 GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
02120 gmx->nrows_val = 1; gmx->ncols_val = gmx->storage = storage;
02121 return BorrowStore(gmx,mt);
02122 }
02123
02124 GeneralMatrix* RowVector::Transpose(TransposedMatrix*, MatrixType mt)
02125 {
02126 REPORT
02127 GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
02128 gmx->ncols_val = 1; gmx->nrows_val = gmx->storage = storage;
02129 return BorrowStore(gmx,mt);
02130 }
02131
02132 GeneralMatrix* IdentityMatrix::Transpose(TransposedMatrix*, MatrixType mt)
02133 { REPORT return Evaluate(mt); }
02134
02135 GeneralMatrix* GeneralMatrix::Evaluate(MatrixType mt)
02136 {
02137 if (Compare(this->Type(),mt)) { REPORT return this; }
02138 REPORT
02139 GeneralMatrix* gmx = mt.New(nrows_val,ncols_val,this);
02140 MatrixRow mr(this, LoadOnEntry);
02141 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02142 int i=nrows_val;
02143 while (i--) { mrx.Copy(mr); mrx.Next(); mr.Next(); }
02144 tDelete(); gmx->ReleaseAndDelete(); return gmx;
02145 }
02146
02147 GeneralMatrix* CroutMatrix::Evaluate(MatrixType mt)
02148 {
02149 if (Compare(this->Type(),mt)) { REPORT return this; }
02150 REPORT
02151 Tracer et("CroutMatrix::Evaluate");
02152 bool dummy = true;
02153 if (dummy) Throw(ProgramException("Illegal use of CroutMatrix", *this));
02154 return this;
02155 }
02156
02157 GeneralMatrix* GenericMatrix::Evaluate(MatrixType mt)
02158 { REPORT return gm->Evaluate(mt); }
02159
02160 GeneralMatrix* ShiftedMatrix::Evaluate(MatrixType mt)
02161 {
02162 gm=((BaseMatrix*&)bm)->Evaluate();
02163 int nr=gm->Nrows(); int nc=gm->Ncols();
02164 Compare(gm->Type().AddEqualEl(),mt);
02165 if (!(mt==gm->Type()))
02166 {
02167 REPORT
02168 GeneralMatrix* gmx = mt.New(nr,nc,this);
02169 MatrixRow mr(gm, LoadOnEntry);
02170 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02171 while (nr--) { mrx.Add(mr,f); mrx.Next(); mr.Next(); }
02172 gmx->ReleaseAndDelete(); gm->tDelete();
02173 return gmx;
02174 }
02175 else if (gm->reuse())
02176 {
02177 REPORT gm->Add(f);
02178 return gm;
02179 }
02180 else
02181 {
02182 REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
02183 gmy->ReleaseAndDelete(); gmy->Add(gm,f);
02184 return gmy;
02185 }
02186 }
02187
02188 GeneralMatrix* NegShiftedMatrix::Evaluate(MatrixType mt)
02189 {
02190 gm=((BaseMatrix*&)bm)->Evaluate();
02191 int nr=gm->Nrows(); int nc=gm->Ncols();
02192 Compare(gm->Type().AddEqualEl(),mt);
02193 if (!(mt==gm->Type()))
02194 {
02195 REPORT
02196 GeneralMatrix* gmx = mt.New(nr,nc,this);
02197 MatrixRow mr(gm, LoadOnEntry);
02198 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02199 while (nr--) { mrx.NegAdd(mr,f); mrx.Next(); mr.Next(); }
02200 gmx->ReleaseAndDelete(); gm->tDelete();
02201 return gmx;
02202 }
02203 else if (gm->reuse())
02204 {
02205 REPORT gm->NegAdd(f);
02206 return gm;
02207 }
02208 else
02209 {
02210 REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
02211 gmy->ReleaseAndDelete(); gmy->NegAdd(gm,f);
02212 return gmy;
02213 }
02214 }
02215
02216 GeneralMatrix* ScaledMatrix::Evaluate(MatrixType mt)
02217 {
02218 gm=((BaseMatrix*&)bm)->Evaluate();
02219 int nr=gm->Nrows(); int nc=gm->Ncols();
02220 if (Compare(gm->Type(),mt))
02221 {
02222 if (gm->reuse())
02223 {
02224 REPORT gm->Multiply(f);
02225 return gm;
02226 }
02227 else
02228 {
02229 REPORT GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
02230 gmx->ReleaseAndDelete(); gmx->Multiply(gm,f);
02231 return gmx;
02232 }
02233 }
02234 else
02235 {
02236 REPORT
02237 GeneralMatrix* gmx = mt.New(nr,nc,this);
02238 MatrixRow mr(gm, LoadOnEntry);
02239 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02240 while (nr--) { mrx.Multiply(mr,f); mrx.Next(); mr.Next(); }
02241 gmx->ReleaseAndDelete(); gm->tDelete();
02242 return gmx;
02243 }
02244 }
02245
02246 GeneralMatrix* NegatedMatrix::Evaluate(MatrixType mt)
02247 {
02248 gm=((BaseMatrix*&)bm)->Evaluate();
02249 int nr=gm->Nrows(); int nc=gm->Ncols();
02250 if (Compare(gm->Type(),mt))
02251 {
02252 if (gm->reuse())
02253 {
02254 REPORT gm->Negate();
02255 return gm;
02256 }
02257 else
02258 {
02259 REPORT
02260 GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
02261 gmx->ReleaseAndDelete(); gmx->Negate(gm);
02262 return gmx;
02263 }
02264 }
02265 else
02266 {
02267 REPORT
02268 GeneralMatrix* gmx = mt.New(nr,nc,this);
02269 MatrixRow mr(gm, LoadOnEntry);
02270 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02271 while (nr--) { mrx.Negate(mr); mrx.Next(); mr.Next(); }
02272 gmx->ReleaseAndDelete(); gm->tDelete();
02273 return gmx;
02274 }
02275 }
02276
02277 GeneralMatrix* ReversedMatrix::Evaluate(MatrixType mt)
02278 {
02279 gm=((BaseMatrix*&)bm)->Evaluate(); GeneralMatrix* gmx;
02280
02281 if ((gm->Type()).is_band() && ! (gm->Type()).is_diagonal())
02282 {
02283 gm->tDelete();
02284 Throw(NotDefinedException("Reverse", "band matrices"));
02285 }
02286
02287 if (gm->reuse()) { REPORT gm->ReverseElements(); gmx = gm; }
02288 else
02289 {
02290 REPORT
02291 gmx = gm->Type().New(gm->Nrows(), gm->Ncols(), this);
02292 gmx->ReverseElements(gm); gmx->ReleaseAndDelete();
02293 }
02294 return gmx->Evaluate(mt);
02295
02296 }
02297
02298 GeneralMatrix* TransposedMatrix::Evaluate(MatrixType mt)
02299 {
02300 REPORT
02301 gm=((BaseMatrix*&)bm)->Evaluate();
02302 Compare(gm->Type().t(),mt);
02303 GeneralMatrix* gmx=gm->Transpose(this, mt);
02304 return gmx;
02305 }
02306
02307 GeneralMatrix* RowedMatrix::Evaluate(MatrixType mt)
02308 {
02309 gm = ((BaseMatrix*&)bm)->Evaluate();
02310 GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
02311 gmx->nrows_val = 1; gmx->ncols_val = gmx->storage = gm->storage;
02312 return gm->BorrowStore(gmx,mt);
02313 }
02314
02315 GeneralMatrix* ColedMatrix::Evaluate(MatrixType mt)
02316 {
02317 gm = ((BaseMatrix*&)bm)->Evaluate();
02318 GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
02319 gmx->ncols_val = 1; gmx->nrows_val = gmx->storage = gm->storage;
02320 return gm->BorrowStore(gmx,mt);
02321 }
02322
02323 GeneralMatrix* DiagedMatrix::Evaluate(MatrixType mt)
02324 {
02325 gm = ((BaseMatrix*&)bm)->Evaluate();
02326 GeneralMatrix* gmx = new DiagonalMatrix; MatrixErrorNoSpace(gmx);
02327 gmx->nrows_val = gmx->ncols_val = gmx->storage = gm->storage;
02328 return gm->BorrowStore(gmx,mt);
02329 }
02330
02331 GeneralMatrix* MatedMatrix::Evaluate(MatrixType mt)
02332 {
02333 Tracer tr("MatedMatrix::Evaluate");
02334 gm = ((BaseMatrix*&)bm)->Evaluate();
02335 GeneralMatrix* gmx = new Matrix; MatrixErrorNoSpace(gmx);
02336 gmx->nrows_val = nr; gmx->ncols_val = nc; gmx->storage = gm->storage;
02337 if (nr*nc != gmx->storage)
02338 Throw(IncompatibleDimensionsException());
02339 return gm->BorrowStore(gmx,mt);
02340 }
02341
02342 GeneralMatrix* GetSubMatrix::Evaluate(MatrixType mt)
02343 {
02344 REPORT
02345 Tracer tr("SubMatrix(evaluate)");
02346 gm = ((BaseMatrix*&)bm)->Evaluate();
02347 if (row_number < 0) row_number = gm->Nrows();
02348 if (col_number < 0) col_number = gm->Ncols();
02349 if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
02350 {
02351 gm->tDelete();
02352 Throw(SubMatrixDimensionException());
02353 }
02354 if (IsSym) Compare(gm->Type().ssub(), mt);
02355 else Compare(gm->Type().sub(), mt);
02356 GeneralMatrix* gmx = mt.New(row_number, col_number, this);
02357 int i = row_number;
02358 MatrixRow mr(gm, LoadOnEntry, row_skip);
02359 MatrixRow mrx(gmx, StoreOnExit+DirectPart);
02360 MatrixRowCol sub;
02361 while (i--)
02362 {
02363 mr.SubRowCol(sub, col_skip, col_number);
02364 mrx.Copy(sub); mrx.Next(); mr.Next();
02365 }
02366 gmx->ReleaseAndDelete(); gm->tDelete();
02367 return gmx;
02368 }
02369
02370
02371 GeneralMatrix* ReturnMatrix::Evaluate(MatrixType mt)
02372 {
02373 return gm->Evaluate(mt);
02374 }
02375
02376
02377 void GeneralMatrix::Add(GeneralMatrix* gm1, Real f)
02378 {
02379 REPORT
02380 Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
02381 while (i--)
02382 { *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; }
02383 i = storage & 3; while (i--) *s++ = *s1++ + f;
02384 }
02385
02386 void GeneralMatrix::Add(Real f)
02387 {
02388 REPORT
02389 Real* s=store; int i=(storage >> 2);
02390 while (i--) { *s++ += f; *s++ += f; *s++ += f; *s++ += f; }
02391 i = storage & 3; while (i--) *s++ += f;
02392 }
02393
02394 void GeneralMatrix::NegAdd(GeneralMatrix* gm1, Real f)
02395 {
02396 REPORT
02397 Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
02398 while (i--)
02399 { *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; }
02400 i = storage & 3; while (i--) *s++ = f - *s1++;
02401 }
02402
02403 void GeneralMatrix::NegAdd(Real f)
02404 {
02405 REPORT
02406 Real* s=store; int i=(storage >> 2);
02407 while (i--)
02408 {
02409 *s = f - *s; s++; *s = f - *s; s++;
02410 *s = f - *s; s++; *s = f - *s; s++;
02411 }
02412 i = storage & 3; while (i--) { *s = f - *s; s++; }
02413 }
02414
02415 void GeneralMatrix::Negate(GeneralMatrix* gm1)
02416 {
02417
02418 REPORT
02419 Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
02420 while (i--)
02421 { *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); }
02422 i = storage & 3; while(i--) *s++ = -(*s1++);
02423 }
02424
02425 void GeneralMatrix::Negate()
02426 {
02427 REPORT
02428 Real* s=store; int i=(storage >> 2);
02429 while (i--)
02430 { *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; }
02431 i = storage & 3; while(i--) { *s = -(*s); s++; }
02432 }
02433
02434 void GeneralMatrix::Multiply(GeneralMatrix* gm1, Real f)
02435 {
02436 REPORT
02437 Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
02438 while (i--)
02439 { *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; }
02440 i = storage & 3; while (i--) *s++ = *s1++ * f;
02441 }
02442
02443 void GeneralMatrix::Multiply(Real f)
02444 {
02445 REPORT
02446 Real* s=store; int i=(storage >> 2);
02447 while (i--) { *s++ *= f; *s++ *= f; *s++ *= f; *s++ *= f; }
02448 i = storage & 3; while (i--) *s++ *= f;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457 MatrixInput MatrixInput::operator<<(double f)
02458 {
02459 REPORT
02460 Tracer et("MatrixInput");
02461 if (n<=0) Throw(ProgramException("List of values too long"));
02462 *r = (Real)f; int n1 = n-1; n=0;
02463 return MatrixInput(n1, r+1);
02464 }
02465
02466
02467 MatrixInput GeneralMatrix::operator<<(double f)
02468 {
02469 REPORT
02470 Tracer et("MatrixInput");
02471 int n = Storage();
02472 if (n<=0) Throw(ProgramException("Loading data to zero length matrix"));
02473 Real* r; r = Store(); *r = (Real)f; n--;
02474 return MatrixInput(n, r+1);
02475 }
02476
02477 MatrixInput GetSubMatrix::operator<<(double f)
02478 {
02479 REPORT
02480 Tracer et("MatrixInput (GetSubMatrix)");
02481 SetUpLHS();
02482 if (row_number != 1 || col_skip != 0 || col_number != gm->Ncols())
02483 {
02484 Throw(ProgramException("MatrixInput requires complete rows"));
02485 }
02486 MatrixRow mr(gm, DirectPart, row_skip);
02487 int n = mr.Storage();
02488 if (n<=0)
02489 {
02490 Throw(ProgramException("Loading data to zero length row"));
02491 }
02492 Real* r; r = mr.Data(); *r = (Real)f; n--;
02493 if (+(mr.cw*HaveStore))
02494 {
02495 Throw(ProgramException("Fails with this matrix type"));
02496 }
02497 return MatrixInput(n, r+1);
02498 }
02499
02500 MatrixInput MatrixInput::operator<<(float f)
02501 {
02502 REPORT
02503 Tracer et("MatrixInput");
02504 if (n<=0) Throw(ProgramException("List of values too long"));
02505 *r = (Real)f; int n1 = n-1; n=0;
02506 return MatrixInput(n1, r+1);
02507 }
02508
02509
02510 MatrixInput GeneralMatrix::operator<<(float f)
02511 {
02512 REPORT
02513 Tracer et("MatrixInput");
02514 int n = Storage();
02515 if (n<=0) Throw(ProgramException("Loading data to zero length matrix"));
02516 Real* r; r = Store(); *r = (Real)f; n--;
02517 return MatrixInput(n, r+1);
02518 }
02519
02520 MatrixInput GetSubMatrix::operator<<(float f)
02521 {
02522 REPORT
02523 Tracer et("MatrixInput (GetSubMatrix)");
02524 SetUpLHS();
02525 if (row_number != 1 || col_skip != 0 || col_number != gm->Ncols())
02526 {
02527 Throw(ProgramException("MatrixInput requires complete rows"));
02528 }
02529 MatrixRow mr(gm, DirectPart, row_skip);
02530 int n = mr.Storage();
02531 if (n<=0)
02532 {
02533 Throw(ProgramException("Loading data to zero length row"));
02534 }
02535 Real* r; r = mr.Data(); *r = (Real)f; n--;
02536 if (+(mr.cw*HaveStore))
02537 {
02538 Throw(ProgramException("Fails with this matrix type"));
02539 }
02540 return MatrixInput(n, r+1);
02541 }
02542 MatrixInput::~MatrixInput()
02543 {
02544 REPORT
02545 Tracer et("MatrixInput");
02546 if (n!=0) Throw(ProgramException("A list of values was too short"));
02547 }
02548
02549 MatrixInput BandMatrix::operator<<(double)
02550 {
02551 Tracer et("MatrixInput");
02552 bool dummy = true;
02553 if (dummy)
02554 Throw(ProgramException("Cannot use list read with a BandMatrix"));
02555 return MatrixInput(0, 0);
02556 }
02557
02558 MatrixInput BandMatrix::operator<<(float)
02559 {
02560 Tracer et("MatrixInput");
02561 bool dummy = true;
02562 if (dummy)
02563 Throw(ProgramException("Cannot use list read with a BandMatrix"));
02564 return MatrixInput(0, 0);
02565 }
02566
02567 void BandMatrix::operator<<(const double*)
02568 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02569
02570 void BandMatrix::operator<<(const float*)
02571 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02572
02573 void BandMatrix::operator<<(const int*)
02574 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02575
02576 void SymmetricBandMatrix::operator<<(const double*)
02577 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02578
02579 void SymmetricBandMatrix::operator<<(const float*)
02580 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02581
02582 void SymmetricBandMatrix::operator<<(const int*)
02583 { Throw(ProgramException("Cannot use array read with a BandMatrix")); }
02584
02585
02586
02587 void GeneralMatrix::ReverseElements(GeneralMatrix* gm)
02588 {
02589
02590 REPORT
02591 int n = Storage(); Real* rx = Store() + n; Real* x = gm->Store();
02592 while (n--) *(--rx) = *(x++);
02593 }
02594
02595 void GeneralMatrix::ReverseElements()
02596 {
02597
02598 REPORT
02599 int n = Storage(); Real* x = Store(); Real* rx = x + n;
02600 n /= 2;
02601 while (n--) { Real t = *(--rx); *rx = *x; *(x++) = t; }
02602 }
02603
02604
02605 #ifdef use_namespace
02606 }
02607 #endif
02608
02612
02615
02616
02617
02618 #ifdef use_namespace
02619 namespace NEWMAT {
02620 #endif
02621
02622
02623
02624 #ifdef DO_REPORT
02625 #define REPORT { static ExeCounter ExeCount(__LINE__,6); ++ExeCount; }
02626 #else
02627 #define REPORT {}
02628 #endif
02629
02630
02631
02632
02633
02634 Real& Matrix::operator()(int m, int n)
02635 {
02636 REPORT
02637 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val)
02638 Throw(IndexException(m,n,*this));
02639 return store[(m-1)*ncols_val+n-1];
02640 }
02641
02642 Real& SymmetricMatrix::operator()(int m, int n)
02643 {
02644 REPORT
02645 if (m<=0 || n<=0 || m>nrows_val || n>ncols_val)
02646 Throw(IndexException(m,n,*this));
02647 if (m>=n) return store[tristore(m-1)+n-1];
02648 else return store[tristore(n-1)+m-1];
02649 }
02650
02651 Real& UpperTriangularMatrix::operator()(int m, int n)
02652 {
02653 REPORT
02654 if (m<=0 || n<m || n>ncols_val)
02655 Throw(IndexException(m,n,*this));
02656 return store[(m-1)*ncols_val+n-1-tristore(m-1)];
02657 }
02658
02659 Real& LowerTriangularMatrix::operator()(int m, int n)
02660 {
02661 REPORT
02662 if (n<=0 || m<n || m>nrows_val)
02663 Throw(IndexException(m,n,*this));
02664 return store[tristore(m-1)+n-1];
02665 }
02666
02667 Real& DiagonalMatrix::operator()(int m, int n)
02668 {
02669 REPORT
02670 if (n<=0 || m!=n || m>nrows_val || n>ncols_val)
02671 Throw(IndexException(m,n,*this));
02672 return store[n-1];
02673 }
02674
02675 Real& DiagonalMatrix::operator()(int m)
02676 {
02677 REPORT
02678 if (m<=0 || m>nrows_val) Throw(IndexException(m,*this));
02679 return store[m-1];
02680 }
02681
02682 Real& ColumnVector::operator()(int m)
02683 {
02684 REPORT
02685 if (m<=0 || m> nrows_val) Throw(IndexException(m,*this));
02686 return store[m-1];
02687 }
02688
02689 Real& RowVector::operator()(int n)
02690 {
02691 REPORT
02692 if (n<=0 || n> ncols_val) Throw(IndexException(n,*this));
02693 return store[n-1];
02694 }
02695
02696 Real& BandMatrix::operator()(int m, int n)
02697 {
02698 REPORT
02699 int w = upper_val+lower_val+1; int i = lower_val+n-m;
02700 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02701 Throw(IndexException(m,n,*this));
02702 return store[w*(m-1)+i];
02703 }
02704
02705 Real& UpperBandMatrix::operator()(int m, int n)
02706 {
02707 REPORT
02708 int w = upper_val+1; int i = n-m;
02709 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02710 Throw(IndexException(m,n,*this));
02711 return store[w*(m-1)+i];
02712 }
02713
02714 Real& LowerBandMatrix::operator()(int m, int n)
02715 {
02716 REPORT
02717 int w = lower_val+1; int i = lower_val+n-m;
02718 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02719 Throw(IndexException(m,n,*this));
02720 return store[w*(m-1)+i];
02721 }
02722
02723 Real& SymmetricBandMatrix::operator()(int m, int n)
02724 {
02725 REPORT
02726 int w = lower_val+1;
02727 if (m>=n)
02728 {
02729 REPORT
02730 int i = lower_val+n-m;
02731 if ( m>nrows_val || n<=0 || i<0 )
02732 Throw(IndexException(m,n,*this));
02733 return store[w*(m-1)+i];
02734 }
02735 else
02736 {
02737 REPORT
02738 int i = lower_val+m-n;
02739 if ( n>nrows_val || m<=0 || i<0 )
02740 Throw(IndexException(m,n,*this));
02741 return store[w*(n-1)+i];
02742 }
02743 }
02744
02745
02746 Real Matrix::operator()(int m, int n) const
02747 {
02748 REPORT
02749 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val)
02750 Throw(IndexException(m,n,*this));
02751 return store[(m-1)*ncols_val+n-1];
02752 }
02753
02754 Real SymmetricMatrix::operator()(int m, int n) const
02755 {
02756 REPORT
02757 if (m<=0 || n<=0 || m>nrows_val || n>ncols_val)
02758 Throw(IndexException(m,n,*this));
02759 if (m>=n) return store[tristore(m-1)+n-1];
02760 else return store[tristore(n-1)+m-1];
02761 }
02762
02763 Real UpperTriangularMatrix::operator()(int m, int n) const
02764 {
02765 REPORT
02766 if (m<=0 || n<m || n>ncols_val)
02767 Throw(IndexException(m,n,*this));
02768 return store[(m-1)*ncols_val+n-1-tristore(m-1)];
02769 }
02770
02771 Real LowerTriangularMatrix::operator()(int m, int n) const
02772 {
02773 REPORT
02774 if (n<=0 || m<n || m>nrows_val)
02775 Throw(IndexException(m,n,*this));
02776 return store[tristore(m-1)+n-1];
02777 }
02778
02779 Real DiagonalMatrix::operator()(int m, int n) const
02780 {
02781 REPORT
02782 if (n<=0 || m!=n || m>nrows_val || n>ncols_val)
02783 Throw(IndexException(m,n,*this));
02784 return store[n-1];
02785 }
02786
02787 Real DiagonalMatrix::operator()(int m) const
02788 {
02789 REPORT
02790 if (m<=0 || m>nrows_val) Throw(IndexException(m,*this));
02791 return store[m-1];
02792 }
02793
02794 Real ColumnVector::operator()(int m) const
02795 {
02796 REPORT
02797 if (m<=0 || m> nrows_val) Throw(IndexException(m,*this));
02798 return store[m-1];
02799 }
02800
02801 Real RowVector::operator()(int n) const
02802 {
02803 REPORT
02804 if (n<=0 || n> ncols_val) Throw(IndexException(n,*this));
02805 return store[n-1];
02806 }
02807
02808 Real BandMatrix::operator()(int m, int n) const
02809 {
02810 REPORT
02811 int w = upper_val+lower_val+1; int i = lower_val+n-m;
02812 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02813 Throw(IndexException(m,n,*this));
02814 return store[w*(m-1)+i];
02815 }
02816
02817 Real UpperBandMatrix::operator()(int m, int n) const
02818 {
02819 REPORT
02820 int w = upper_val+1; int i = n-m;
02821 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02822 Throw(IndexException(m,n,*this));
02823 return store[w*(m-1)+i];
02824 }
02825
02826 Real LowerBandMatrix::operator()(int m, int n) const
02827 {
02828 REPORT
02829 int w = lower_val+1; int i = lower_val+n-m;
02830 if (m<=0 || m>nrows_val || n<=0 || n>ncols_val || i<0 || i>=w)
02831 Throw(IndexException(m,n,*this));
02832 return store[w*(m-1)+i];
02833 }
02834
02835 Real SymmetricBandMatrix::operator()(int m, int n) const
02836 {
02837 REPORT
02838 int w = lower_val+1;
02839 if (m>=n)
02840 {
02841 REPORT
02842 int i = lower_val+n-m;
02843 if ( m>nrows_val || n<=0 || i<0 )
02844 Throw(IndexException(m,n,*this));
02845 return store[w*(m-1)+i];
02846 }
02847 else
02848 {
02849 REPORT
02850 int i = lower_val+m-n;
02851 if ( n>nrows_val || m<=0 || i<0 )
02852 Throw(IndexException(m,n,*this));
02853 return store[w*(n-1)+i];
02854 }
02855 }
02856
02857
02858 Real BaseMatrix::as_scalar() const
02859 {
02860 REPORT
02861 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
02862
02863 if (gm->nrows_val!=1 || gm->ncols_val!=1)
02864 {
02865 Tracer tr("as_scalar");
02866 Try
02867 { Throw(ProgramException("Cannot convert to scalar", *gm)); }
02868 CatchAll { gm->tDelete(); ReThrow; }
02869 }
02870
02871 Real x = *(gm->store); gm->tDelete(); return x;
02872 }
02873
02874
02875 AddedMatrix BaseMatrix::operator+(const BaseMatrix& bm) const
02876 { REPORT return AddedMatrix(this, &bm); }
02877
02878 SPMatrix SP(const BaseMatrix& bm1,const BaseMatrix& bm2)
02879 { REPORT return SPMatrix(&bm1, &bm2); }
02880
02881 KPMatrix KP(const BaseMatrix& bm1,const BaseMatrix& bm2)
02882 { REPORT return KPMatrix(&bm1, &bm2); }
02883
02884 MultipliedMatrix BaseMatrix::operator*(const BaseMatrix& bm) const
02885 { REPORT return MultipliedMatrix(this, &bm); }
02886
02887 ConcatenatedMatrix BaseMatrix::operator|(const BaseMatrix& bm) const
02888 { REPORT return ConcatenatedMatrix(this, &bm); }
02889
02890 StackedMatrix BaseMatrix::operator&(const BaseMatrix& bm) const
02891 { REPORT return StackedMatrix(this, &bm); }
02892
02893 SolvedMatrix InvertedMatrix::operator*(const BaseMatrix& bmx) const
02894 { REPORT return SolvedMatrix(bm, &bmx); }
02895
02896 SubtractedMatrix BaseMatrix::operator-(const BaseMatrix& bm) const
02897 { REPORT return SubtractedMatrix(this, &bm); }
02898
02899 ShiftedMatrix BaseMatrix::operator+(Real f) const
02900 { REPORT return ShiftedMatrix(this, f); }
02901
02902 ShiftedMatrix operator+(Real f, const BaseMatrix& BM)
02903 { REPORT return ShiftedMatrix(&BM, f); }
02904
02905 NegShiftedMatrix operator-(Real f, const BaseMatrix& bm)
02906 { REPORT return NegShiftedMatrix(f, &bm); }
02907
02908 ScaledMatrix BaseMatrix::operator*(Real f) const
02909 { REPORT return ScaledMatrix(this, f); }
02910
02911 ScaledMatrix BaseMatrix::operator/(Real f) const
02912 { REPORT return ScaledMatrix(this, 1.0/f); }
02913
02914 ScaledMatrix operator*(Real f, const BaseMatrix& BM)
02915 { REPORT return ScaledMatrix(&BM, f); }
02916
02917 ShiftedMatrix BaseMatrix::operator-(Real f) const
02918 { REPORT return ShiftedMatrix(this, -f); }
02919
02920 TransposedMatrix BaseMatrix::t() const
02921 { REPORT return TransposedMatrix(this); }
02922
02923 NegatedMatrix BaseMatrix::operator-() const
02924 { REPORT return NegatedMatrix(this); }
02925
02926 ReversedMatrix BaseMatrix::reverse() const
02927 { REPORT return ReversedMatrix(this); }
02928
02929 InvertedMatrix BaseMatrix::i() const
02930 { REPORT return InvertedMatrix(this); }
02931
02932
02933 RowedMatrix BaseMatrix::as_row() const
02934 { REPORT return RowedMatrix(this); }
02935
02936 ColedMatrix BaseMatrix::as_column() const
02937 { REPORT return ColedMatrix(this); }
02938
02939 DiagedMatrix BaseMatrix::as_diagonal() const
02940 { REPORT return DiagedMatrix(this); }
02941
02942 MatedMatrix BaseMatrix::as_matrix(int nrx, int ncx) const
02943 { REPORT return MatedMatrix(this,nrx,ncx); }
02944
02945
02946 void GeneralMatrix::operator=(Real f)
02947 { REPORT int i=storage; Real* s=store; while (i--) { *s++ = f; } }
02948
02949 void Matrix::operator=(const BaseMatrix& X)
02950 {
02951 REPORT
02952
02953 Eq(X,MatrixType::Rt);
02954 }
02955
02956 void SquareMatrix::operator=(const BaseMatrix& X)
02957 {
02958 REPORT
02959
02960 Eq(X,MatrixType::Rt);
02961 if (nrows_val != ncols_val)
02962 { Tracer tr("SquareMatrix(=)"); Throw(NotSquareException(*this)); }
02963 }
02964
02965 void SquareMatrix::operator=(const Matrix& m)
02966 {
02967 REPORT
02968 if (m.nrows_val != m.ncols_val)
02969 { Tracer tr("SquareMatrix(=Matrix)"); Throw(NotSquareException(*this)); }
02970 Eq(m);
02971 }
02972
02973 void RowVector::operator=(const BaseMatrix& X)
02974 {
02975 REPORT
02976
02977 Eq(X,MatrixType::RV);
02978 if (nrows_val!=1)
02979 { Tracer tr("RowVector(=)"); Throw(VectorException(*this)); }
02980 }
02981
02982 void ColumnVector::operator=(const BaseMatrix& X)
02983 {
02984 REPORT
02985
02986 Eq(X,MatrixType::CV);
02987 if (ncols_val!=1)
02988 { Tracer tr("ColumnVector(=)"); Throw(VectorException(*this)); }
02989 }
02990
02991 void SymmetricMatrix::operator=(const BaseMatrix& X)
02992 {
02993 REPORT
02994
02995 Eq(X,MatrixType::Sm);
02996 }
02997
02998 void UpperTriangularMatrix::operator=(const BaseMatrix& X)
02999 {
03000 REPORT
03001
03002 Eq(X,MatrixType::UT);
03003 }
03004
03005 void LowerTriangularMatrix::operator=(const BaseMatrix& X)
03006 {
03007 REPORT
03008
03009 Eq(X,MatrixType::LT);
03010 }
03011
03012 void DiagonalMatrix::operator=(const BaseMatrix& X)
03013 {
03014 REPORT
03015
03016 Eq(X,MatrixType::Dg);
03017 }
03018
03019 void IdentityMatrix::operator=(const BaseMatrix& X)
03020 {
03021 REPORT
03022
03023 Eq(X,MatrixType::Id);
03024 }
03025
03026
03027 void CroutMatrix::operator=(const CroutMatrix& gm)
03028 {
03029 if (&gm == this) { REPORT tag_val = -1; return; }
03030 REPORT
03031 if (indx > 0) { delete [] indx; indx = 0; }
03032 ((CroutMatrix&)gm).get_aux(*this);
03033 Eq(gm);
03034 }
03035
03036
03037
03038
03039
03040 void GeneralMatrix::operator<<(const double* r)
03041 {
03042 REPORT
03043 int i = storage; Real* s=store;
03044 while(i--) *s++ = (Real)*r++;
03045 }
03046
03047
03048 void GeneralMatrix::operator<<(const float* r)
03049 {
03050 REPORT
03051 int i = storage; Real* s=store;
03052 while(i--) *s++ = (Real)*r++;
03053 }
03054
03055
03056 void GeneralMatrix::operator<<(const int* r)
03057 {
03058 REPORT
03059 int i = storage; Real* s=store;
03060 while(i--) *s++ = (Real)*r++;
03061 }
03062
03063
03064 void GenericMatrix::operator=(const GenericMatrix& bmx)
03065 {
03066 if (&bmx != this) { REPORT if (gm) delete gm; gm = bmx.gm->Image();}
03067 else { REPORT }
03068 gm->Protect();
03069 }
03070
03071 void GenericMatrix::operator=(const BaseMatrix& bmx)
03072 {
03073 if (gm)
03074 {
03075 int counter=bmx.search(gm);
03076 if (counter==0) { REPORT delete gm; gm=0; }
03077 else { REPORT gm->Release(counter); }
03078 }
03079 else { REPORT }
03080 GeneralMatrix* gmx = ((BaseMatrix&)bmx).Evaluate();
03081 if (gmx != gm) { REPORT if (gm) delete gm; gm = gmx->Image(); }
03082 else { REPORT }
03083 gm->Protect();
03084 }
03085
03086
03087
03088
03089
03090
03091
03092 void GeneralMatrix::operator+=(const BaseMatrix& X)
03093 {
03094 REPORT
03095 Tracer tr("GeneralMatrix::operator+=");
03096
03097 Protect();
03098
03099 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
03100 AddedMatrix am(this,gm);
03101 if (gm==this) Release(2); else Release();
03102 Eq2(am,type());
03103 }
03104
03105 void GeneralMatrix::operator-=(const BaseMatrix& X)
03106 {
03107 REPORT
03108 Tracer tr("GeneralMatrix::operator-=");
03109
03110 Protect();
03111
03112 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
03113 SubtractedMatrix am(this,gm);
03114 if (gm==this) Release(2); else Release();
03115 Eq2(am,type());
03116 }
03117
03118 void GeneralMatrix::operator*=(const BaseMatrix& X)
03119 {
03120 REPORT
03121 Tracer tr("GeneralMatrix::operator*=");
03122
03123 Protect();
03124
03125 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
03126 MultipliedMatrix am(this,gm);
03127 if (gm==this) Release(2); else Release();
03128 Eq2(am,type());
03129 }
03130
03131 void GeneralMatrix::operator|=(const BaseMatrix& X)
03132 {
03133 REPORT
03134 Tracer tr("GeneralMatrix::operator|=");
03135
03136 Protect();
03137
03138 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
03139 ConcatenatedMatrix am(this,gm);
03140 if (gm==this) Release(2); else Release();
03141 Eq2(am,type());
03142 }
03143
03144 void GeneralMatrix::operator&=(const BaseMatrix& X)
03145 {
03146 REPORT
03147 Tracer tr("GeneralMatrix::operator&=");
03148
03149 Protect();
03150
03151 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
03152 StackedMatrix am(this,gm);
03153 if (gm==this) Release(2); else Release();
03154 Eq2(am,type());
03155 }
03156
03157 void GeneralMatrix::operator+=(Real r)
03158 {
03159 REPORT
03160 Tracer tr("GeneralMatrix::operator+=(Real)");
03161
03162 ShiftedMatrix am(this,r);
03163 Release(); Eq2(am,type());
03164 }
03165
03166 void GeneralMatrix::operator*=(Real r)
03167 {
03168 REPORT
03169 Tracer tr("GeneralMatrix::operator*=(Real)");
03170
03171 ScaledMatrix am(this,r);
03172 Release(); Eq2(am,type());
03173 }
03174
03175
03176
03177
03178 void GenericMatrix::operator+=(const BaseMatrix& X)
03179 {
03180 REPORT
03181 Tracer tr("GenericMatrix::operator+=");
03182 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03183 gm->Protect();
03184 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
03185 AddedMatrix am(gm,gmx);
03186 if (gmx==gm) gm->Release(2); else gm->Release();
03187 GeneralMatrix* gmy = am.Evaluate();
03188 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03189 else { REPORT }
03190 gm->Protect();
03191 }
03192
03193 void GenericMatrix::operator-=(const BaseMatrix& X)
03194 {
03195 REPORT
03196 Tracer tr("GenericMatrix::operator-=");
03197 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03198 gm->Protect();
03199 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
03200 SubtractedMatrix am(gm,gmx);
03201 if (gmx==gm) gm->Release(2); else gm->Release();
03202 GeneralMatrix* gmy = am.Evaluate();
03203 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03204 else { REPORT }
03205 gm->Protect();
03206 }
03207
03208 void GenericMatrix::operator*=(const BaseMatrix& X)
03209 {
03210 REPORT
03211 Tracer tr("GenericMatrix::operator*=");
03212 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03213 gm->Protect();
03214 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
03215 MultipliedMatrix am(gm,gmx);
03216 if (gmx==gm) gm->Release(2); else gm->Release();
03217 GeneralMatrix* gmy = am.Evaluate();
03218 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03219 else { REPORT }
03220 gm->Protect();
03221 }
03222
03223 void GenericMatrix::operator|=(const BaseMatrix& X)
03224 {
03225 REPORT
03226 Tracer tr("GenericMatrix::operator|=");
03227 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03228 gm->Protect();
03229 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
03230 ConcatenatedMatrix am(gm,gmx);
03231 if (gmx==gm) gm->Release(2); else gm->Release();
03232 GeneralMatrix* gmy = am.Evaluate();
03233 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03234 else { REPORT }
03235 gm->Protect();
03236 }
03237
03238 void GenericMatrix::operator&=(const BaseMatrix& X)
03239 {
03240 REPORT
03241 Tracer tr("GenericMatrix::operator&=");
03242 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03243 gm->Protect();
03244 GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
03245 StackedMatrix am(gm,gmx);
03246 if (gmx==gm) gm->Release(2); else gm->Release();
03247 GeneralMatrix* gmy = am.Evaluate();
03248 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03249 else { REPORT }
03250 gm->Protect();
03251 }
03252
03253 void GenericMatrix::operator+=(Real r)
03254 {
03255 REPORT
03256 Tracer tr("GenericMatrix::operator+= (Real)");
03257 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03258 ShiftedMatrix am(gm,r);
03259 gm->Release();
03260 GeneralMatrix* gmy = am.Evaluate();
03261 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03262 else { REPORT }
03263 gm->Protect();
03264 }
03265
03266 void GenericMatrix::operator*=(Real r)
03267 {
03268 REPORT
03269 Tracer tr("GenericMatrix::operator*= (Real)");
03270 if (!gm) Throw(ProgramException("GenericMatrix is null"));
03271 ScaledMatrix am(gm,r);
03272 gm->Release();
03273 GeneralMatrix* gmy = am.Evaluate();
03274 if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
03275 else { REPORT }
03276 gm->Protect();
03277 }
03278
03279
03280
03281
03282 Real& Matrix::element(int m, int n)
03283 {
03284 REPORT
03285 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val)
03286 Throw(IndexException(m,n,*this,true));
03287 return store[m*ncols_val+n];
03288 }
03289
03290 Real Matrix::element(int m, int n) const
03291 {
03292 REPORT
03293 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val)
03294 Throw(IndexException(m,n,*this,true));
03295 return store[m*ncols_val+n];
03296 }
03297
03298 Real& SymmetricMatrix::element(int m, int n)
03299 {
03300 REPORT
03301 if (m<0 || n<0 || m >= nrows_val || n>=ncols_val)
03302 Throw(IndexException(m,n,*this,true));
03303 if (m>=n) return store[tristore(m)+n];
03304 else return store[tristore(n)+m];
03305 }
03306
03307 Real SymmetricMatrix::element(int m, int n) const
03308 {
03309 REPORT
03310 if (m<0 || n<0 || m >= nrows_val || n>=ncols_val)
03311 Throw(IndexException(m,n,*this,true));
03312 if (m>=n) return store[tristore(m)+n];
03313 else return store[tristore(n)+m];
03314 }
03315
03316 Real& UpperTriangularMatrix::element(int m, int n)
03317 {
03318 REPORT
03319 if (m<0 || n<m || n>=ncols_val)
03320 Throw(IndexException(m,n,*this,true));
03321 return store[m*ncols_val+n-tristore(m)];
03322 }
03323
03324 Real UpperTriangularMatrix::element(int m, int n) const
03325 {
03326 REPORT
03327 if (m<0 || n<m || n>=ncols_val)
03328 Throw(IndexException(m,n,*this,true));
03329 return store[m*ncols_val+n-tristore(m)];
03330 }
03331
03332 Real& LowerTriangularMatrix::element(int m, int n)
03333 {
03334 REPORT
03335 if (n<0 || m<n || m>=nrows_val)
03336 Throw(IndexException(m,n,*this,true));
03337 return store[tristore(m)+n];
03338 }
03339
03340 Real LowerTriangularMatrix::element(int m, int n) const
03341 {
03342 REPORT
03343 if (n<0 || m<n || m>=nrows_val)
03344 Throw(IndexException(m,n,*this,true));
03345 return store[tristore(m)+n];
03346 }
03347
03348 Real& DiagonalMatrix::element(int m, int n)
03349 {
03350 REPORT
03351 if (n<0 || m!=n || m>=nrows_val || n>=ncols_val)
03352 Throw(IndexException(m,n,*this,true));
03353 return store[n];
03354 }
03355
03356 Real DiagonalMatrix::element(int m, int n) const
03357 {
03358 REPORT
03359 if (n<0 || m!=n || m>=nrows_val || n>=ncols_val)
03360 Throw(IndexException(m,n,*this,true));
03361 return store[n];
03362 }
03363
03364 Real& DiagonalMatrix::element(int m)
03365 {
03366 REPORT
03367 if (m<0 || m>=nrows_val) Throw(IndexException(m,*this,true));
03368 return store[m];
03369 }
03370
03371 Real DiagonalMatrix::element(int m) const
03372 {
03373 REPORT
03374 if (m<0 || m>=nrows_val) Throw(IndexException(m,*this,true));
03375 return store[m];
03376 }
03377
03378 Real& ColumnVector::element(int m)
03379 {
03380 REPORT
03381 if (m<0 || m>= nrows_val) Throw(IndexException(m,*this,true));
03382 return store[m];
03383 }
03384
03385 Real ColumnVector::element(int m) const
03386 {
03387 REPORT
03388 if (m<0 || m>= nrows_val) Throw(IndexException(m,*this,true));
03389 return store[m];
03390 }
03391
03392 Real& RowVector::element(int n)
03393 {
03394 REPORT
03395 if (n<0 || n>= ncols_val) Throw(IndexException(n,*this,true));
03396 return store[n];
03397 }
03398
03399 Real RowVector::element(int n) const
03400 {
03401 REPORT
03402 if (n<0 || n>= ncols_val) Throw(IndexException(n,*this,true));
03403 return store[n];
03404 }
03405
03406 Real& BandMatrix::element(int m, int n)
03407 {
03408 REPORT
03409 int w = upper_val+lower_val+1; int i = lower_val+n-m;
03410 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03411 Throw(IndexException(m,n,*this,true));
03412 return store[w*m+i];
03413 }
03414
03415 Real BandMatrix::element(int m, int n) const
03416 {
03417 REPORT
03418 int w = upper_val+lower_val+1; int i = lower_val+n-m;
03419 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03420 Throw(IndexException(m,n,*this,true));
03421 return store[w*m+i];
03422 }
03423
03424 Real& UpperBandMatrix::element(int m, int n)
03425 {
03426 REPORT
03427 int w = upper_val+1; int i = n-m;
03428 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03429 Throw(IndexException(m,n,*this,true));
03430 return store[w*m+i];
03431 }
03432
03433 Real UpperBandMatrix::element(int m, int n) const
03434 {
03435 REPORT
03436 int w = upper_val+1; int i = n-m;
03437 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03438 Throw(IndexException(m,n,*this,true));
03439 return store[w*m+i];
03440 }
03441
03442 Real& LowerBandMatrix::element(int m, int n)
03443 {
03444 REPORT
03445 int w = lower_val+1; int i = lower_val+n-m;
03446 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03447 Throw(IndexException(m,n,*this,true));
03448 return store[w*m+i];
03449 }
03450
03451 Real LowerBandMatrix::element(int m, int n) const
03452 {
03453 REPORT
03454 int w = lower_val+1; int i = lower_val+n-m;
03455 if (m<0 || m>= nrows_val || n<0 || n>= ncols_val || i<0 || i>=w)
03456 Throw(IndexException(m,n,*this,true));
03457 return store[w*m+i];
03458 }
03459
03460 Real& SymmetricBandMatrix::element(int m, int n)
03461 {
03462 REPORT
03463 int w = lower_val+1;
03464 if (m>=n)
03465 {
03466 REPORT
03467 int i = lower_val+n-m;
03468 if ( m>=nrows_val || n<0 || i<0 )
03469 Throw(IndexException(m,n,*this,true));
03470 return store[w*m+i];
03471 }
03472 else
03473 {
03474 REPORT
03475 int i = lower_val+m-n;
03476 if ( n>=nrows_val || m<0 || i<0 )
03477 Throw(IndexException(m,n,*this,true));
03478 return store[w*n+i];
03479 }
03480 }
03481
03482 Real SymmetricBandMatrix::element(int m, int n) const
03483 {
03484 REPORT
03485 int w = lower_val+1;
03486 if (m>=n)
03487 {
03488 REPORT
03489 int i = lower_val+n-m;
03490 if ( m>=nrows_val || n<0 || i<0 )
03491 Throw(IndexException(m,n,*this,true));
03492 return store[w*m+i];
03493 }
03494 else
03495 {
03496 REPORT
03497 int i = lower_val+m-n;
03498 if ( n>=nrows_val || m<0 || i<0 )
03499 Throw(IndexException(m,n,*this,true));
03500 return store[w*n+i];
03501 }
03502 }
03503
03504 #ifdef use_namespace
03505 }
03506 #endif
03507
03508
03512
03515
03516
03517
03518 #define WANT_MATH
03519
03522
03525
03526 #ifndef PRECISION_LIB
03527 #define PRECISION_LIB 0
03528
03529 #define WANT_MATH
03530
03531 #ifdef _STANDARD_ // standard library available
03532 #include <limits>
03533 #endif
03534
03535 #ifdef use_namespace
03536 namespace NEWMAT {
03537 #endif
03538
03539 #ifdef _STANDARD_ // standard library available
03540
03541 #ifdef OPT_COMPATIBLE
03542 #include <cfloat>
03543 #endif
03544
03545 using namespace std;
03546
03548 class FloatingPointPrecision
03549 {
03550 public:
03551 static int Dig()
03552 { return numeric_limits<Real>::digits10 ; }
03553
03554 static Real Epsilon()
03555 { return numeric_limits<Real>::epsilon(); }
03556
03557 static int Mantissa()
03558 { return numeric_limits<Real>::digits; }
03559
03560 static Real Maximum()
03561 { return numeric_limits<Real>::max(); }
03562
03563 static int MaximumDecimalExponent()
03564 { return numeric_limits<Real>::max_exponent10; }
03565
03566 static int MaximumExponent()
03567 { return numeric_limits<Real>::max_exponent; }
03568
03569 static Real LnMaximum()
03570 { return (Real)log(Maximum()); }
03571
03572 static Real Minimum()
03573 { return numeric_limits<Real>::min(); }
03574
03575 static int MinimumDecimalExponent()
03576 { return numeric_limits<Real>::min_exponent10; }
03577
03578 static int MinimumExponent()
03579 { return numeric_limits<Real>::min_exponent; }
03580
03581 static Real LnMinimum()
03582 { return (Real)log(Minimum()); }
03583
03584 static int Radix()
03585 { return numeric_limits<Real>::radix; }
03586
03587 static int Rounds()
03588 {
03589 return numeric_limits<Real>::round_style ==
03590 round_to_nearest ? 1 : 0;
03591 }
03592
03593 };
03594
03595
03596 #else // _STANDARD_ not defined
03597
03598 #ifndef SystemV // if there is float.h
03599
03600 #ifdef USING_FLOAT
03601
03603 class FloatingPointPrecision
03604 {
03605 public:
03606 static int Dig()
03607 { return FLT_DIG; }
03608
03609 static Real Epsilon()
03610 { return FLT_EPSILON; }
03611
03612 static int Mantissa()
03613 { return FLT_MANT_DIG; }
03614
03615 static Real Maximum()
03616 { return FLT_MAX; }
03617
03618 static int MaximumDecimalExponent()
03619 { return FLT_MAX_10_EXP; }
03620
03621 static int MaximumExponent()
03622 { return FLT_MAX_EXP; }
03623
03624 static Real LnMaximum()
03625 { return (Real)log(Maximum()); }
03626
03627 static Real Minimum()
03628 { return FLT_MIN; }
03629
03630 static int MinimumDecimalExponent()
03631 { return FLT_MIN_10_EXP; }
03632
03633 static int MinimumExponent()
03634 { return FLT_MIN_EXP; }
03635
03636 static Real LnMinimum()
03637 { return (Real)log(Minimum()); }
03638
03639 static int Radix()
03640 { return FLT_RADIX; }
03641
03642 static int Rounds()
03643 { return FLT_ROUNDS; }
03644
03645 };
03646
03647 #endif // USING_FLOAT
03648
03649
03650 #ifdef USING_DOUBLE
03651
03653 class FloatingPointPrecision
03654 {
03655 public:
03656
03657 static int Dig()
03658 { return DBL_DIG; }
03659
03660 static Real Epsilon()
03661 { return DBL_EPSILON; }
03662
03663 static int Mantissa()
03664 { return DBL_MANT_DIG; }
03665
03666 static Real Maximum()
03667 { return DBL_MAX; }
03668
03669 static int MaximumDecimalExponent()
03670 { return DBL_MAX_10_EXP; }
03671
03672 static int MaximumExponent()
03673 { return DBL_MAX_EXP; }
03674
03675 static Real LnMaximum()
03676 { return (Real)log(Maximum()); }
03677
03678 static Real Minimum()
03679 {
03680
03681
03682
03683 return DBL_MIN;
03684
03685 }
03686
03687 static int MinimumDecimalExponent()
03688 { return DBL_MIN_10_EXP; }
03689
03690 static int MinimumExponent()
03691 { return DBL_MIN_EXP; }
03692
03693 static Real LnMinimum()
03694 { return (Real)log(Minimum()); }
03695
03696
03697 static int Radix()
03698 { return FLT_RADIX; }
03699
03700 static int Rounds()
03701 { return FLT_ROUNDS; }
03702
03703 };
03704
03705 #endif // USING_DOUBLE
03706
03707 #else // if there is no float.h
03708
03709 #ifdef OPT_COMPATIBLE
03710 #define FLT_MAX MAXFLOAT
03711 #endif
03712
03713
03714 #ifdef USING_FLOAT
03715
03717 class FloatingPointPrecision
03718 {
03719 public:
03720
03721 static Real Epsilon()
03722 { return pow(2.0,(int)(1-FSIGNIF)); }
03723
03724
03725 static Real Maximum()
03726 { return MAXFLOAT; }
03727
03728 static Real LnMaximum()
03729 { return (Real)log(Maximum()); }
03730
03731 static Real Minimum()
03732 { return MINFLOAT; }
03733
03734 static Real LnMinimum()
03735 { return (Real)log(Minimum()); }
03736
03737 };
03738
03739 #endif // USING_FLOAT
03740
03741
03742 #ifdef USING_DOUBLE
03743
03745 class FloatingPointPrecision
03746 {
03747 public:
03748
03749 static Real Epsilon()
03750 { return pow(2.0,(int)(1-DSIGNIF)); }
03751
03752
03753 static Real Maximum()
03754 { return MAXDOUBLE; }
03755
03756 static Real LnMaximum()
03757 { return LN_MAXDOUBLE; }
03758
03759 static Real Minimum()
03760 { return MINDOUBLE; }
03761
03762 static Real LnMinimum()
03763 { return LN_MINDOUBLE; }
03764 };
03765
03766 #endif // USING_DOUBLE
03767
03768 #endif // SystemV
03769
03770 #endif // _STANDARD_
03771
03772
03773
03774
03775 #ifdef use_namespace
03776 }
03777 #endif // use_namespace
03778
03779
03780
03781 #endif // PRECISION_LIB
03782
03783
03785
03786 #ifdef use_namespace
03787 namespace NEWMAT {
03788 #endif
03789
03790
03791 #ifdef DO_REPORT
03792 #define REPORT { static ExeCounter ExeCount(__LINE__,8); ++ExeCount; }
03793 #else
03794 #define REPORT {}
03795 #endif
03796
03797
03798
03799
03800 void CroutMatrix::ludcmp()
03801
03802
03803
03804
03805
03806 {
03807 REPORT
03808 Tracer tr( "Crout(ludcmp)" ); sing = false;
03809 Real* akk = store;
03810
03811 Real big = fabs(*akk); int mu = 0; Real* ai = akk; int k;
03812
03813 for (k = 1; k < nrows_val; k++)
03814 {
03815 ai += nrows_val; const Real trybig = fabs(*ai);
03816 if (big < trybig) { big = trybig; mu = k; }
03817 }
03818
03819
03820 if (nrows_val) for (k = 0;;)
03821 {
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836 indx[k] = mu;
03837
03838 if (mu != k)
03839 {
03840 Real* a1 = store + nrows_val * k;
03841 Real* a2 = store + nrows_val * mu; d = !d;
03842 int j = nrows_val;
03843 while (j--) { const Real temp = *a1; *a1++ = *a2; *a2++ = temp; }
03844 }
03845
03846 Real diag = *akk; big = 0; mu = k + 1;
03847 if (diag != 0)
03848 {
03849 ai = akk; int i = nrows_val - k - 1;
03850 while (i--)
03851 {
03852 ai += nrows_val; Real* al = ai;
03853 Real mult = *al / diag; *al = mult;
03854 int l = nrows_val - k - 1; Real* aj = akk;
03855
03856
03857 if (l-- != 0)
03858 {
03859 *(++al) -= (mult * *(++aj));
03860 const Real trybig = fabs(*al);
03861 if (big < trybig) { big = trybig; mu = nrows_val - i - 1; }
03862 while (l--) *(++al) -= (mult * *(++aj));
03863 }
03864 }
03865 }
03866 else sing = true;
03867 if (++k == nrows_val) break;
03868 akk += nrows_val + 1;
03869 }
03870 }
03871
03872 void CroutMatrix::lubksb(Real* B, int mini)
03873 {
03874 REPORT
03875
03876
03877
03878
03879
03880
03881 Tracer tr("Crout(lubksb)");
03882 if (sing) Throw(SingularException(*this));
03883 int i, j, ii = nrows_val;
03884
03885
03886
03887 for (i = 0; i < nrows_val; i++)
03888 {
03889 int ip = indx[i]; Real temp = B[ip]; B[ip] = B[i]; B[i] = temp;
03890 if (temp != 0.0) { ii = i; break; }
03891 }
03892
03893 Real* bi; Real* ai;
03894 i = ii + 1;
03895
03896 if (i < nrows_val)
03897 {
03898 bi = B + ii; ai = store + ii + i * nrows_val;
03899 for (;;)
03900 {
03901 int ip = indx[i]; Real sum = B[ip]; B[ip] = B[i];
03902 Real* aij = ai; Real* bj = bi; j = i - ii;
03903 while (j--) sum -= *aij++ * *bj++;
03904 B[i] = sum;
03905 if (++i == nrows_val) break;
03906 ai += nrows_val;
03907 }
03908 }
03909
03910 ai = store + nrows_val * nrows_val;
03911
03912 for (i = nrows_val - 1; i >= mini; i--)
03913 {
03914 Real* bj = B+i; ai -= nrows_val; Real* ajx = ai+i;
03915 Real sum = *bj; Real diag = *ajx;
03916 j = nrows_val - i; while(--j) sum -= *(++ajx) * *(++bj);
03917 B[i] = sum / diag;
03918 }
03919 }
03920
03921
03922
03923
03924 Real GeneralMatrix::sum_square() const
03925 {
03926 REPORT
03927 Real sum = 0.0; int i = storage; Real* s = store;
03928 while (i--) sum += square(*s++);
03929 ((GeneralMatrix&)*this).tDelete(); return sum;
03930 }
03931
03932 Real GeneralMatrix::sum_absolute_value() const
03933 {
03934 REPORT
03935 Real sum = 0.0; int i = storage; Real* s = store;
03936 while (i--) sum += fabs(*s++);
03937 ((GeneralMatrix&)*this).tDelete(); return sum;
03938 }
03939
03940 Real GeneralMatrix::sum() const
03941 {
03942 REPORT
03943 Real sm = 0.0; int i = storage; Real* s = store;
03944 while (i--) sm += *s++;
03945 ((GeneralMatrix&)*this).tDelete(); return sm;
03946 }
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980 static void NullMatrixError(const GeneralMatrix* gm)
03981 {
03982 ((GeneralMatrix&)*gm).tDelete();
03983 Throw(ProgramException("Maximum or minimum of null matrix"));
03984 }
03985
03986 Real GeneralMatrix::maximum_absolute_value() const
03987 {
03988 REPORT
03989 if (storage == 0) NullMatrixError(this);
03990 Real maxval = 0.0; int l = storage; Real* s = store;
03991 while (l--) { Real a = fabs(*s++); if (maxval < a) maxval = a; }
03992 ((GeneralMatrix&)*this).tDelete(); return maxval;
03993 }
03994
03995 Real GeneralMatrix::maximum_absolute_value1(int& i) const
03996 {
03997 REPORT
03998 if (storage == 0) NullMatrixError(this);
03999 Real maxval = 0.0; int l = storage; Real* s = store; int li = storage;
04000 while (l--)
04001 { Real a = fabs(*s++); if (maxval <= a) { maxval = a; li = l; } }
04002 i = storage - li;
04003 ((GeneralMatrix&)*this).tDelete(); return maxval;
04004 }
04005
04006 Real GeneralMatrix::minimum_absolute_value() const
04007 {
04008 REPORT
04009 if (storage == 0) NullMatrixError(this);
04010 int l = storage - 1; Real* s = store; Real minval = fabs(*s++);
04011 while (l--) { Real a = fabs(*s++); if (minval > a) minval = a; }
04012 ((GeneralMatrix&)*this).tDelete(); return minval;
04013 }
04014
04015 Real GeneralMatrix::minimum_absolute_value1(int& i) const
04016 {
04017 REPORT
04018 if (storage == 0) NullMatrixError(this);
04019 int l = storage - 1; Real* s = store; Real minval = fabs(*s++); int li = l;
04020 while (l--)
04021 { Real a = fabs(*s++); if (minval >= a) { minval = a; li = l; } }
04022 i = storage - li;
04023 ((GeneralMatrix&)*this).tDelete(); return minval;
04024 }
04025
04026 Real GeneralMatrix::maximum() const
04027 {
04028 REPORT
04029 if (storage == 0) NullMatrixError(this);
04030 int l = storage - 1; Real* s = store; Real maxval = *s++;
04031 while (l--) { Real a = *s++; if (maxval < a) maxval = a; }
04032 ((GeneralMatrix&)*this).tDelete(); return maxval;
04033 }
04034
04035 Real GeneralMatrix::maximum1(int& i) const
04036 {
04037 REPORT
04038 if (storage == 0) NullMatrixError(this);
04039 int l = storage - 1; Real* s = store; Real maxval = *s++; int li = l;
04040 while (l--) { Real a = *s++; if (maxval <= a) { maxval = a; li = l; } }
04041 i = storage - li;
04042 ((GeneralMatrix&)*this).tDelete(); return maxval;
04043 }
04044
04045 Real GeneralMatrix::minimum() const
04046 {
04047 REPORT
04048 if (storage == 0) NullMatrixError(this);
04049 int l = storage - 1; Real* s = store; Real minval = *s++;
04050 while (l--) { Real a = *s++; if (minval > a) minval = a; }
04051 ((GeneralMatrix&)*this).tDelete(); return minval;
04052 }
04053
04054 Real GeneralMatrix::minimum1(int& i) const
04055 {
04056 REPORT
04057 if (storage == 0) NullMatrixError(this);
04058 int l = storage - 1; Real* s = store; Real minval = *s++; int li = l;
04059 while (l--) { Real a = *s++; if (minval >= a) { minval = a; li = l; } }
04060 i = storage - li;
04061 ((GeneralMatrix&)*this).tDelete(); return minval;
04062 }
04063
04064 Real GeneralMatrix::maximum_absolute_value2(int& i, int& j) const
04065 {
04066 REPORT
04067 if (storage == 0) NullMatrixError(this);
04068 Real maxval = 0.0; int nr = Nrows();
04069 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
04070 for (int r = 1; r <= nr; r++)
04071 {
04072 int c; maxval = mr.MaximumAbsoluteValue1(maxval, c);
04073 if (c > 0) { i = r; j = c; }
04074 mr.Next();
04075 }
04076 ((GeneralMatrix&)*this).tDelete(); return maxval;
04077 }
04078
04079 Real GeneralMatrix::minimum_absolute_value2(int& i, int& j) const
04080 {
04081 REPORT
04082 if (storage == 0) NullMatrixError(this);
04083 Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
04084 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
04085 for (int r = 1; r <= nr; r++)
04086 {
04087 int c; minval = mr.MinimumAbsoluteValue1(minval, c);
04088 if (c > 0) { i = r; j = c; }
04089 mr.Next();
04090 }
04091 ((GeneralMatrix&)*this).tDelete(); return minval;
04092 }
04093
04094 Real GeneralMatrix::maximum2(int& i, int& j) const
04095 {
04096 REPORT
04097 if (storage == 0) NullMatrixError(this);
04098 Real maxval = -FloatingPointPrecision::Maximum(); int nr = Nrows();
04099 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
04100 for (int r = 1; r <= nr; r++)
04101 {
04102 int c; maxval = mr.Maximum1(maxval, c);
04103 if (c > 0) { i = r; j = c; }
04104 mr.Next();
04105 }
04106 ((GeneralMatrix&)*this).tDelete(); return maxval;
04107 }
04108
04109 Real GeneralMatrix::minimum2(int& i, int& j) const
04110 {
04111 REPORT
04112 if (storage == 0) NullMatrixError(this);
04113 Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
04114 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
04115 for (int r = 1; r <= nr; r++)
04116 {
04117 int c; minval = mr.Minimum1(minval, c);
04118 if (c > 0) { i = r; j = c; }
04119 mr.Next();
04120 }
04121 ((GeneralMatrix&)*this).tDelete(); return minval;
04122 }
04123
04124 Real Matrix::maximum_absolute_value2(int& i, int& j) const
04125 {
04126 REPORT
04127 int k; Real m = GeneralMatrix::maximum_absolute_value1(k); k--;
04128 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
04129 return m;
04130 }
04131
04132 Real Matrix::minimum_absolute_value2(int& i, int& j) const
04133 {
04134 REPORT
04135 int k; Real m = GeneralMatrix::minimum_absolute_value1(k); k--;
04136 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
04137 return m;
04138 }
04139
04140 Real Matrix::maximum2(int& i, int& j) const
04141 {
04142 REPORT
04143 int k; Real m = GeneralMatrix::maximum1(k); k--;
04144 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
04145 return m;
04146 }
04147
04148 Real Matrix::minimum2(int& i, int& j) const
04149 {
04150 REPORT
04151 int k; Real m = GeneralMatrix::minimum1(k); k--;
04152 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
04153 return m;
04154 }
04155
04156 Real SymmetricMatrix::sum_square() const
04157 {
04158 REPORT
04159 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_val;
04160 for (int i = 0; i<nr; i++)
04161 {
04162 int j = i;
04163 while (j--) sum2 += square(*s++);
04164 sum1 += square(*s++);
04165 }
04166 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
04167 }
04168
04169 Real SymmetricMatrix::sum_absolute_value() const
04170 {
04171 REPORT
04172 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_val;
04173 for (int i = 0; i<nr; i++)
04174 {
04175 int j = i;
04176 while (j--) sum2 += fabs(*s++);
04177 sum1 += fabs(*s++);
04178 }
04179 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
04180 }
04181
04182 Real IdentityMatrix::sum_absolute_value() const
04183 { REPORT return fabs(trace()); }
04184
04185 Real SymmetricMatrix::sum() const
04186 {
04187 REPORT
04188 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_val;
04189 for (int i = 0; i<nr; i++)
04190 {
04191 int j = i;
04192 while (j--) sum2 += *s++;
04193 sum1 += *s++;
04194 }
04195 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
04196 }
04197
04198 Real IdentityMatrix::sum_square() const
04199 {
04200 Real sum = *store * *store * nrows_val;
04201 ((GeneralMatrix&)*this).tDelete(); return sum;
04202 }
04203
04204
04205 Real BaseMatrix::sum_square() const
04206 {
04207 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04208 Real s = gm->sum_square(); return s;
04209 }
04210
04211 Real BaseMatrix::norm_Frobenius() const
04212 { REPORT return sqrt(sum_square()); }
04213
04214 Real BaseMatrix::sum_absolute_value() const
04215 {
04216 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04217 Real s = gm->sum_absolute_value(); return s;
04218 }
04219
04220 Real BaseMatrix::sum() const
04221 {
04222 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04223 Real s = gm->sum(); return s;
04224 }
04225
04226 Real BaseMatrix::maximum_absolute_value() const
04227 {
04228 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04229 Real s = gm->maximum_absolute_value(); return s;
04230 }
04231
04232 Real BaseMatrix::maximum_absolute_value1(int& i) const
04233 {
04234 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04235 Real s = gm->maximum_absolute_value1(i); return s;
04236 }
04237
04238 Real BaseMatrix::maximum_absolute_value2(int& i, int& j) const
04239 {
04240 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04241 Real s = gm->maximum_absolute_value2(i, j); return s;
04242 }
04243
04244 Real BaseMatrix::minimum_absolute_value() const
04245 {
04246 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04247 Real s = gm->minimum_absolute_value(); return s;
04248 }
04249
04250 Real BaseMatrix::minimum_absolute_value1(int& i) const
04251 {
04252 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04253 Real s = gm->minimum_absolute_value1(i); return s;
04254 }
04255
04256 Real BaseMatrix::minimum_absolute_value2(int& i, int& j) const
04257 {
04258 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04259 Real s = gm->minimum_absolute_value2(i, j); return s;
04260 }
04261
04262 Real BaseMatrix::maximum() const
04263 {
04264 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04265 Real s = gm->maximum(); return s;
04266 }
04267
04268 Real BaseMatrix::maximum1(int& i) const
04269 {
04270 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04271 Real s = gm->maximum1(i); return s;
04272 }
04273
04274 Real BaseMatrix::maximum2(int& i, int& j) const
04275 {
04276 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04277 Real s = gm->maximum2(i, j); return s;
04278 }
04279
04280 Real BaseMatrix::minimum() const
04281 {
04282 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04283 Real s = gm->minimum(); return s;
04284 }
04285
04286 Real BaseMatrix::minimum1(int& i) const
04287 {
04288 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04289 Real s = gm->minimum1(i); return s;
04290 }
04291
04292 Real BaseMatrix::minimum2(int& i, int& j) const
04293 {
04294 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04295 Real s = gm->minimum2(i, j); return s;
04296 }
04297
04298 Real dotproduct(const Matrix& A, const Matrix& B)
04299 {
04300 REPORT
04301 int n = A.storage;
04302 if (n != B.storage)
04303 {
04304 Tracer tr("dotproduct");
04305 Throw(IncompatibleDimensionsException(A,B));
04306 }
04307 Real sum = 0.0; Real* a = A.store; Real* b = B.store;
04308 while (n--) sum += *a++ * *b++;
04309 return sum;
04310 }
04311
04312 Real Matrix::trace() const
04313 {
04314 REPORT
04315 Tracer tr("trace");
04316 int i = nrows_val; int d = i+1;
04317 if (i != ncols_val) Throw(NotSquareException(*this));
04318 Real sum = 0.0; Real* s = store;
04319
04320 if (i) for (;;) { sum += *s; if (!(--i)) break; s += d; }
04321 ((GeneralMatrix&)*this).tDelete(); return sum;
04322 }
04323
04324 Real DiagonalMatrix::trace() const
04325 {
04326 REPORT
04327 int i = nrows_val; Real sum = 0.0; Real* s = store;
04328 while (i--) sum += *s++;
04329 ((GeneralMatrix&)*this).tDelete(); return sum;
04330 }
04331
04332 Real SymmetricMatrix::trace() const
04333 {
04334 REPORT
04335 int i = nrows_val; Real sum = 0.0; Real* s = store; int j = 2;
04336
04337 if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
04338 ((GeneralMatrix&)*this).tDelete(); return sum;
04339 }
04340
04341 Real LowerTriangularMatrix::trace() const
04342 {
04343 REPORT
04344 int i = nrows_val; Real sum = 0.0; Real* s = store; int j = 2;
04345
04346 if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
04347 ((GeneralMatrix&)*this).tDelete(); return sum;
04348 }
04349
04350 Real UpperTriangularMatrix::trace() const
04351 {
04352 REPORT
04353 int i = nrows_val; Real sum = 0.0; Real* s = store;
04354 while (i) { sum += *s; s += i--; }
04355 ((GeneralMatrix&)*this).tDelete(); return sum;
04356 }
04357
04358 Real BandMatrix::trace() const
04359 {
04360 REPORT
04361 int i = nrows_val; int w = lower_val+upper_val+1;
04362 Real sum = 0.0; Real* s = store+lower_val;
04363
04364 if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
04365 ((GeneralMatrix&)*this).tDelete(); return sum;
04366 }
04367
04368 Real SymmetricBandMatrix::trace() const
04369 {
04370 REPORT
04371 int i = nrows_val; int w = lower_val+1;
04372 Real sum = 0.0; Real* s = store+lower_val;
04373
04374 if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
04375 ((GeneralMatrix&)*this).tDelete(); return sum;
04376 }
04377
04378 Real IdentityMatrix::trace() const
04379 {
04380 Real sum = *store * nrows_val;
04381 ((GeneralMatrix&)*this).tDelete(); return sum;
04382 }
04383
04384
04385 Real BaseMatrix::trace() const
04386 {
04387 REPORT
04388 MatrixType Diag = MatrixType::Dg; Diag.SetDataLossOK();
04389 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(Diag);
04390 Real sum = gm->trace(); return sum;
04391 }
04392
04393 void LogAndSign::operator*=(Real x)
04394 {
04395 if (x > 0.0) { log_val += log(x); }
04396 else if (x < 0.0) { log_val += log(-x); sign_val = -sign_val; }
04397 else sign_val = 0;
04398 }
04399
04400 void LogAndSign::pow_eq(int k)
04401 {
04402 if (sign_val)
04403 {
04404 log_val *= k;
04405 if ( (k & 1) == 0 ) sign_val = 1;
04406 }
04407 }
04408
04409 Real LogAndSign::value() const
04410 {
04411 Tracer et("LogAndSign::value");
04412 if (log_val >= FloatingPointPrecision::LnMaximum())
04413 Throw(OverflowException("Overflow in exponential"));
04414 return sign_val * exp(log_val);
04415 }
04416
04417 LogAndSign::LogAndSign(Real f)
04418 {
04419 if (f == 0.0) { log_val = 0.0; sign_val = 0; return; }
04420 else if (f < 0.0) { sign_val = -1; f = -f; }
04421 else sign_val = 1;
04422 log_val = log(f);
04423 }
04424
04425 LogAndSign DiagonalMatrix::log_determinant() const
04426 {
04427 REPORT
04428 int i = nrows_val; LogAndSign sum; Real* s = store;
04429 while (i--) sum *= *s++;
04430 ((GeneralMatrix&)*this).tDelete(); return sum;
04431 }
04432
04433 LogAndSign LowerTriangularMatrix::log_determinant() const
04434 {
04435 REPORT
04436 int i = nrows_val; LogAndSign sum; Real* s = store; int j = 2;
04437
04438 if (i) for(;;) { sum *= *s; if (!(--i)) break; s += j++; }
04439 ((GeneralMatrix&)*this).tDelete(); return sum;
04440 }
04441
04442 LogAndSign UpperTriangularMatrix::log_determinant() const
04443 {
04444 REPORT
04445 int i = nrows_val; LogAndSign sum; Real* s = store;
04446 while (i) { sum *= *s; s += i--; }
04447 ((GeneralMatrix&)*this).tDelete(); return sum;
04448 }
04449
04450 LogAndSign IdentityMatrix::log_determinant() const
04451 {
04452 REPORT
04453 int i = nrows_val; LogAndSign sum;
04454 if (i > 0) { sum = *store; sum.PowEq(i); }
04455 ((GeneralMatrix&)*this).tDelete(); return sum;
04456 }
04457
04458 LogAndSign BaseMatrix::log_determinant() const
04459 {
04460 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04461 LogAndSign sum = gm->log_determinant(); return sum;
04462 }
04463
04464 LogAndSign GeneralMatrix::log_determinant() const
04465 {
04466 REPORT
04467 Tracer tr("log_determinant");
04468 if (nrows_val != ncols_val) Throw(NotSquareException(*this));
04469 CroutMatrix C(*this); return C.log_determinant();
04470 }
04471
04472 LogAndSign CroutMatrix::log_determinant() const
04473 {
04474 REPORT
04475 if (sing) return 0.0;
04476 int i = nrows_val; int dd = i+1; LogAndSign sum; Real* s = store;
04477 if (i) for(;;)
04478 {
04479 sum *= *s;
04480 if (!(--i)) break;
04481 s += dd;
04482 }
04483 if (!d) sum.ChangeSign(); return sum;
04484
04485 }
04486
04487 Real BaseMatrix::determinant() const
04488 {
04489 REPORT
04490 Tracer tr("determinant");
04491 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04492 LogAndSign ld = gm->log_determinant();
04493 return ld.Value();
04494 }
04495
04496 LinearEquationSolver::LinearEquationSolver(const BaseMatrix& bm)
04497 {
04498 gm = ( ((BaseMatrix&)bm).Evaluate() )->MakeSolver();
04499 if (gm==&bm) { REPORT gm = gm->Image(); }
04500
04501 else { REPORT gm->Protect(); }
04502 }
04503
04504 ReturnMatrix BaseMatrix::sum_square_rows() const
04505 {
04506 REPORT
04507 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04508 int nr = gm->nrows();
04509 ColumnVector ssq(nr);
04510 if (gm->size() == 0) { REPORT ssq = 0.0; }
04511 else
04512 {
04513 MatrixRow mr(gm, LoadOnEntry);
04514 for (int i = 1; i <= nr; ++i)
04515 {
04516 Real sum = 0.0;
04517 int s = mr.Storage();
04518 Real* in = mr.Data();
04519 while (s--) sum += square(*in++);
04520 ssq(i) = sum;
04521 mr.Next();
04522 }
04523 }
04524 gm->tDelete();
04525 ssq.release(); return ssq.for_return();
04526 }
04527
04528 ReturnMatrix BaseMatrix::sum_square_columns() const
04529 {
04530 REPORT
04531 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04532 int nr = gm->nrows(); int nc = gm->ncols();
04533 RowVector ssq(nc); ssq = 0.0;
04534 if (gm->size() != 0)
04535 {
04536 MatrixRow mr(gm, LoadOnEntry);
04537 for (int i = 1; i <= nr; ++i)
04538 {
04539 int s = mr.Storage();
04540 Real* in = mr.Data(); Real* out = ssq.data() + mr.Skip();
04541 while (s--) *out++ += square(*in++);
04542 mr.Next();
04543 }
04544 }
04545 gm->tDelete();
04546 ssq.release(); return ssq.for_return();
04547 }
04548
04549 ReturnMatrix BaseMatrix::sum_rows() const
04550 {
04551 REPORT
04552 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04553 int nr = gm->nrows();
04554 ColumnVector sum_vec(nr);
04555 if (gm->size() == 0) { REPORT sum_vec = 0.0; }
04556 else
04557 {
04558 MatrixRow mr(gm, LoadOnEntry);
04559 for (int i = 1; i <= nr; ++i)
04560 {
04561 Real sum = 0.0;
04562 int s = mr.Storage();
04563 Real* in = mr.Data();
04564 while (s--) sum += *in++;
04565 sum_vec(i) = sum;
04566 mr.Next();
04567 }
04568 }
04569 gm->tDelete();
04570 sum_vec.release(); return sum_vec.for_return();
04571 }
04572
04573 ReturnMatrix BaseMatrix::sum_columns() const
04574 {
04575 REPORT
04576 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
04577 int nr = gm->nrows(); int nc = gm->ncols();
04578 RowVector sum_vec(nc); sum_vec = 0.0;
04579 if (gm->size() != 0)
04580 {
04581 MatrixRow mr(gm, LoadOnEntry);
04582 for (int i = 1; i <= nr; ++i)
04583 {
04584 int s = mr.Storage();
04585 Real* in = mr.Data(); Real* out = sum_vec.data() + mr.Skip();
04586 while (s--) *out++ += *in++;
04587 mr.Next();
04588 }
04589 }
04590 gm->tDelete();
04591 sum_vec.release(); return sum_vec.for_return();
04592 }
04593
04594
04595 #ifdef use_namespace
04596 }
04597 #endif
04598
04599
04603
04606
04607
04608
04609
04610 #ifdef use_namespace
04611 namespace NEWMAT {
04612 #endif
04613
04614
04615 #ifdef DO_REPORT
04616 #define REPORT { static ExeCounter ExeCount(__LINE__,7); ++ExeCount; }
04617 #else
04618 #define REPORT {}
04619 #endif
04620
04621
04622
04623
04624 GeneralMatrix* GeneralMatrix::MakeSolver()
04625 {
04626 REPORT
04627 GeneralMatrix* gm = new CroutMatrix(*this);
04628 MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
04629 }
04630
04631 GeneralMatrix* Matrix::MakeSolver()
04632 {
04633 REPORT
04634 GeneralMatrix* gm = new CroutMatrix(*this);
04635 MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
04636 }
04637
04638 void CroutMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin)
04639 {
04640 REPORT
04641 int i = mcin.skip; Real* el = mcin.data-i; Real* el1 = el;
04642 while (i--) *el++ = 0.0;
04643 el += mcin.storage; i = nrows_val - mcin.skip - mcin.storage;
04644 while (i--) *el++ = 0.0;
04645 lubksb(el1, mcout.skip);
04646 }
04647
04648
04649
04650
04651 void UpperTriangularMatrix::Solver(MatrixColX& mcout,
04652 const MatrixColX& mcin)
04653 {
04654 REPORT
04655 int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
04656 while (i-- > 0) *elx++ = 0.0;
04657 int nr = mcin.skip+mcin.storage;
04658 elx = mcin.data+mcin.storage; Real* el = elx;
04659 int j = mcout.skip+mcout.storage-nr;
04660 int nc = ncols_val-nr; i = nr-mcout.skip;
04661 while (j-- > 0) *elx++ = 0.0;
04662 Real* Ael = store + (nr*(2*ncols_val-nr+1))/2; j = 0;
04663 while (i-- > 0)
04664 {
04665 elx = el; Real sum = 0.0; int jx = j++; Ael -= nc;
04666 while (jx--) sum += *(--Ael) * *(--elx);
04667 elx--; *elx = (*elx - sum) / *(--Ael);
04668 }
04669 }
04670
04671 void LowerTriangularMatrix::Solver(MatrixColX& mcout,
04672 const MatrixColX& mcin)
04673 {
04674 REPORT
04675 int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
04676 while (i-- > 0) *elx++ = 0.0;
04677 int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage;
04678 int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
04679 while (j-- > 0) *elx++ = 0.0;
04680 Real* el = mcin.data; Real* Ael = store + (nc*(nc+1))/2; j = 0;
04681 while (i-- > 0)
04682 {
04683 elx = el; Real sum = 0.0; int jx = j++; Ael += nc;
04684 while (jx--) sum += *Ael++ * *elx++;
04685 *elx = (*elx - sum) / *Ael++;
04686 }
04687 }
04688
04689
04690
04691 static GeneralMatrix*
04692 GeneralMult(GeneralMatrix*,GeneralMatrix*,MultipliedMatrix*,MatrixType);
04693 static GeneralMatrix*
04694 GeneralSolv(GeneralMatrix*,GeneralMatrix*,BaseMatrix*,MatrixType);
04695 static GeneralMatrix*
04696 GeneralSolvI(GeneralMatrix*,BaseMatrix*,MatrixType);
04697 static GeneralMatrix*
04698 GeneralKP(GeneralMatrix*,GeneralMatrix*,KPMatrix*,MatrixType);
04699
04700 GeneralMatrix* MultipliedMatrix::Evaluate(MatrixType mt)
04701 {
04702 REPORT
04703 gm2 = ((BaseMatrix*&)bm2)->Evaluate();
04704 gm2 = gm2->Evaluate(gm2->type().MultRHS());
04705 gm1 = ((BaseMatrix*&)bm1)->Evaluate();
04706 return GeneralMult(gm1, gm2, this, mt);
04707 }
04708
04709 GeneralMatrix* SolvedMatrix::Evaluate(MatrixType mt)
04710 {
04711 REPORT
04712 gm1 = ((BaseMatrix*&)bm1)->Evaluate();
04713 gm2 = ((BaseMatrix*&)bm2)->Evaluate();
04714 return GeneralSolv(gm1,gm2,this,mt);
04715 }
04716
04717 GeneralMatrix* KPMatrix::Evaluate(MatrixType mt)
04718 {
04719 REPORT
04720 gm1 = ((BaseMatrix*&)bm1)->Evaluate();
04721 gm2 = ((BaseMatrix*&)bm2)->Evaluate();
04722 return GeneralKP(gm1,gm2,this,mt);
04723 }
04724
04725
04726
04727 static void Add(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04728 {
04729 REPORT
04730 Real* s1=gm1->Store(); Real* s2=gm2->Store();
04731 Real* s=gm->Store(); int i=gm->Storage() >> 2;
04732 while (i--)
04733 {
04734 *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++;
04735 *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++;
04736 }
04737 i=gm->Storage() & 3; while (i--) *s++ = *s1++ + *s2++;
04738 }
04739
04740 static void AddTo(GeneralMatrix* gm, const GeneralMatrix* gm2)
04741 {
04742 REPORT
04743 const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
04744 while (i--)
04745 { *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; }
04746 i=gm->Storage() & 3; while (i--) *s++ += *s2++;
04747 }
04748
04749 void GeneralMatrix::PlusEqual(const GeneralMatrix& gm)
04750 {
04751 REPORT
04752 if (nrows_val != gm.nrows_val || ncols_val != gm.ncols_val)
04753 Throw(IncompatibleDimensionsException(*this, gm));
04754 AddTo(this, &gm);
04755 }
04756
04757 static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04758 {
04759 REPORT
04760 Real* s1=gm1->Store(); Real* s2=gm2->Store();
04761 Real* s=gm->Store(); int i=gm->Storage() >> 2;
04762 while (i--)
04763 {
04764 *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++;
04765 *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++;
04766 }
04767 i=gm->Storage() & 3; while (i--) *s++ = *s1++ - *s2++;
04768 }
04769
04770 static void SubtractFrom(GeneralMatrix* gm, const GeneralMatrix* gm2)
04771 {
04772 REPORT
04773 const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
04774 while (i--)
04775 { *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; }
04776 i=gm->Storage() & 3; while (i--) *s++ -= *s2++;
04777 }
04778
04779 void GeneralMatrix::MinusEqual(const GeneralMatrix& gm)
04780 {
04781 REPORT
04782 if (nrows_val != gm.nrows_val || ncols_val != gm.ncols_val)
04783 Throw(IncompatibleDimensionsException(*this, gm));
04784 SubtractFrom(this, &gm);
04785 }
04786
04787 static void ReverseSubtract(GeneralMatrix* gm, const GeneralMatrix* gm2)
04788 {
04789 REPORT
04790 const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
04791 while (i--)
04792 {
04793 *s = *s2++ - *s; s++; *s = *s2++ - *s; s++;
04794 *s = *s2++ - *s; s++; *s = *s2++ - *s; s++;
04795 }
04796 i=gm->Storage() & 3; while (i--) { *s = *s2++ - *s; s++; }
04797 }
04798
04799 static void SP(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04800 {
04801 REPORT
04802 Real* s1=gm1->Store(); Real* s2=gm2->Store();
04803 Real* s=gm->Store(); int i=gm->Storage() >> 2;
04804 while (i--)
04805 {
04806 *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++;
04807 *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++;
04808 }
04809 i=gm->Storage() & 3; while (i--) *s++ = *s1++ * *s2++;
04810 }
04811
04812 static void SP(GeneralMatrix* gm, GeneralMatrix* gm2)
04813 {
04814 REPORT
04815 Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
04816 while (i--)
04817 { *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; }
04818 i=gm->Storage() & 3; while (i--) *s++ *= *s2++;
04819 }
04820
04821
04822
04823 static void AddDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04824 {
04825 REPORT
04826 int nr = gm->Nrows();
04827 MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
04828 MatrixRow mr(gm, StoreOnExit+DirectPart);
04829 while (nr--) { mr.Add(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
04830 }
04831
04832 static void AddDS(GeneralMatrix* gm, GeneralMatrix* gm2)
04833
04834 {
04835 REPORT
04836 int nr = gm->Nrows();
04837 MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart);
04838 MatrixRow mr2(gm2, LoadOnEntry);
04839 while (nr--) { mr.Add(mr2); mr.Next(); mr2.Next(); }
04840 }
04841
04842 static void SubtractDS
04843 (GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04844 {
04845 REPORT
04846 int nr = gm->Nrows();
04847 MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
04848 MatrixRow mr(gm, StoreOnExit+DirectPart);
04849 while (nr--) { mr.Sub(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
04850 }
04851
04852 static void SubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2)
04853 {
04854 REPORT
04855 int nr = gm->Nrows();
04856 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart);
04857 MatrixRow mr2(gm2, LoadOnEntry);
04858 while (nr--) { mr.Sub(mr2); mr.Next(); mr2.Next(); }
04859 }
04860
04861 static void ReverseSubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2)
04862 {
04863 REPORT
04864 int nr = gm->Nrows();
04865 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart);
04866 MatrixRow mr2(gm2, LoadOnEntry);
04867 while (nr--) { mr.RevSub(mr2); mr2.Next(); mr.Next(); }
04868 }
04869
04870 static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
04871 {
04872 REPORT
04873 int nr = gm->Nrows();
04874 MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
04875 MatrixRow mr(gm, StoreOnExit+DirectPart);
04876 while (nr--) { mr.Multiply(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
04877 }
04878
04879 static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm2)
04880
04881 {
04882 REPORT
04883 int nr = gm->Nrows();
04884 MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart);
04885 MatrixRow mr2(gm2, LoadOnEntry);
04886 while (nr--) { mr.Multiply(mr2); mr.Next(); mr2.Next(); }
04887 }
04888
04889 static GeneralMatrix* GeneralMult1(GeneralMatrix* gm1, GeneralMatrix* gm2,
04890 MultipliedMatrix* mm, MatrixType mtx)
04891 {
04892 REPORT
04893 Tracer tr("GeneralMult1");
04894 int nr=gm1->Nrows(); int nc=gm2->Ncols();
04895 if (gm1->Ncols() !=gm2->Nrows())
04896 Throw(IncompatibleDimensionsException(*gm1, *gm2));
04897 GeneralMatrix* gmx = mtx.New(nr,nc,mm);
04898
04899 MatrixCol mcx(gmx, StoreOnExit+DirectPart);
04900 MatrixCol mc2(gm2, LoadOnEntry);
04901 while (nc--)
04902 {
04903 MatrixRow mr1(gm1, LoadOnEntry, mcx.Skip());
04904 Real* el = mcx.Data();
04905 int n = mcx.Storage();
04906 while (n--) { *(el++) = DotProd(mr1,mc2); mr1.Next(); }
04907 mc2.Next(); mcx.Next();
04908 }
04909 gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
04910 }
04911
04912 static GeneralMatrix* GeneralMult2(GeneralMatrix* gm1, GeneralMatrix* gm2,
04913 MultipliedMatrix* mm, MatrixType mtx)
04914 {
04915
04916
04917 REPORT
04918 Tracer tr("GeneralMult2");
04919 int nr=gm1->Nrows(); int nc=gm2->Ncols();
04920 if (gm1->Ncols() !=gm2->Nrows())
04921 Throw(IncompatibleDimensionsException(*gm1, *gm2));
04922 GeneralMatrix* gmx = mtx.New(nr,nc,mm);
04923
04924 MatrixRow mrx(gmx, LoadOnEntry+StoreOnExit+DirectPart);
04925 MatrixRow mr1(gm1, LoadOnEntry);
04926 while (nr--)
04927 {
04928 MatrixRow mr2(gm2, LoadOnEntry, mr1.Skip());
04929 Real* el = mr1.Data();
04930 int n = mr1.Storage();
04931 mrx.Zero();
04932 while (n--) { mrx.AddScaled(mr2, *el++); mr2.Next(); }
04933 mr1.Next(); mrx.Next();
04934 }
04935 gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
04936 }
04937
04938 static GeneralMatrix* mmMult(GeneralMatrix* gm1, GeneralMatrix* gm2)
04939 {
04940
04941 REPORT
04942 Tracer tr("MatrixMult");
04943
04944 int nr=gm1->Nrows(); int ncr=gm1->Ncols(); int nc=gm2->Ncols();
04945 if (ncr != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1,*gm2));
04946
04947 Matrix* gm = new Matrix(nr,nc); MatrixErrorNoSpace(gm);
04948
04949 Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store();
04950
04951 if (ncr)
04952 {
04953 while (nr--)
04954 {
04955 Real* s2x = s2; int j = ncr;
04956 Real* sx = s; Real f = *s1++; int k = nc;
04957 while (k--) *sx++ = f * *s2x++;
04958 while (--j)
04959 { sx = s; f = *s1++; k = nc; while (k--) *sx++ += f * *s2x++; }
04960 s = sx;
04961 }
04962 }
04963 else *gm = 0.0;
04964
04965 gm->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gm;
04966 }
04967
04968 static GeneralMatrix* GeneralMult(GeneralMatrix* gm1, GeneralMatrix* gm2,
04969 MultipliedMatrix* mm, MatrixType mtx)
04970 {
04971 if ( Rectangular(gm1->type(), gm2->type(), mtx))
04972 { REPORT return mmMult(gm1, gm2); }
04973 Compare(gm1->type() * gm2->type(),mtx);
04974 int nr = gm2->Nrows(); int nc = gm2->Ncols();
04975 if (nc <= 5 && nr > nc) { REPORT return GeneralMult1(gm1, gm2, mm, mtx); }
04976 REPORT return GeneralMult2(gm1, gm2, mm, mtx);
04977 }
04978
04979 static GeneralMatrix* GeneralKP(GeneralMatrix* gm1, GeneralMatrix* gm2,
04980 KPMatrix* kp, MatrixType mtx)
04981 {
04982 REPORT
04983 Tracer tr("GeneralKP");
04984 int nr1 = gm1->Nrows(); int nc1 = gm1->Ncols();
04985 int nr2 = gm2->Nrows(); int nc2 = gm2->Ncols();
04986 Compare((gm1->type()).KP(gm2->type()),mtx);
04987 GeneralMatrix* gmx = mtx.New(nr1*nr2, nc1*nc2, kp);
04988 MatrixRow mrx(gmx, LoadOnEntry+StoreOnExit+DirectPart);
04989 MatrixRow mr1(gm1, LoadOnEntry);
04990 for (int i = 1; i <= nr1; ++i)
04991 {
04992 MatrixRow mr2(gm2, LoadOnEntry);
04993 for (int j = 1; j <= nr2; ++j)
04994 { mrx.KP(mr1,mr2); mr2.Next(); mrx.Next(); }
04995 mr1.Next();
04996 }
04997 gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
04998 }
04999
05000 static GeneralMatrix* GeneralSolv(GeneralMatrix* gm1, GeneralMatrix* gm2,
05001 BaseMatrix* sm, MatrixType mtx)
05002 {
05003 REPORT
05004 Tracer tr("GeneralSolv");
05005 Compare(gm1->type().i() * gm2->type(),mtx);
05006 int nr = gm1->Nrows();
05007 if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1));
05008 int nc = gm2->Ncols();
05009 if (gm1->Ncols() != gm2->Nrows())
05010 Throw(IncompatibleDimensionsException(*gm1, *gm2));
05011 GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx);
05012 Real* r = new Real [nr]; MatrixErrorNoSpace(r);
05013 MONITOR_REAL_NEW("Make (GenSolv)",nr,r)
05014 GeneralMatrix* gms = gm1->MakeSolver();
05015 Try
05016 {
05017
05018 MatrixColX mcx(gmx, r, StoreOnExit+DirectPart);
05019
05020 MatrixColX mc2(gm2, r, LoadOnEntry);
05021 while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); }
05022 }
05023 CatchAll
05024 {
05025 if (gms) gms->tDelete();
05026 delete gmx;
05027 gm2->tDelete();
05028 MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r)
05029
05030 delete [] r;
05031 ReThrow;
05032 }
05033 gms->tDelete(); gmx->ReleaseAndDelete(); gm2->tDelete();
05034 MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r)
05035
05036 delete [] r;
05037 return gmx;
05038 }
05039
05040
05041 static GeneralMatrix* GeneralSolvI(GeneralMatrix* gm1, BaseMatrix* sm,
05042 MatrixType mtx)
05043 {
05044 REPORT
05045 Tracer tr("GeneralSolvI");
05046 Compare(gm1->type().i(),mtx);
05047 int nr = gm1->Nrows();
05048 if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1));
05049 int nc = nr;
05050
05051 IdentityMatrix I(nr);
05052 GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx);
05053 Real* r = new Real [nr]; MatrixErrorNoSpace(r);
05054 MONITOR_REAL_NEW("Make (GenSolvI)",nr,r)
05055 GeneralMatrix* gms = gm1->MakeSolver();
05056 Try
05057 {
05058
05059 MatrixColX mcx(gmx, r, StoreOnExit+DirectPart);
05060
05061 MatrixColX mc2(&I, r, LoadOnEntry);
05062 while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); }
05063 }
05064 CatchAll
05065 {
05066 if (gms) gms->tDelete();
05067 delete gmx;
05068 MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r)
05069
05070 delete [] r;
05071 ReThrow;
05072 }
05073 gms->tDelete(); gmx->ReleaseAndDelete();
05074 MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r)
05075
05076 delete [] r;
05077 return gmx;
05078 }
05079
05080 GeneralMatrix* InvertedMatrix::Evaluate(MatrixType mtx)
05081 {
05082
05083 Tracer tr("InvertedMatrix::Evaluate");
05084 REPORT
05085 gm=((BaseMatrix*&)bm)->Evaluate();
05086 return GeneralSolvI(gm,this,mtx);
05087 }
05088
05089
05090
05091 GeneralMatrix* AddedMatrix::Evaluate(MatrixType mtd)
05092 {
05093 REPORT
05094 Tracer tr("AddedMatrix::Evaluate");
05095 gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
05096 int nr=gm1->Nrows(); int nc=gm1->Ncols();
05097 if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
05098 {
05099 Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
05100 CatchAll
05101 {
05102 gm1->tDelete(); gm2->tDelete();
05103 ReThrow;
05104 }
05105 }
05106 MatrixType mt1 = gm1->type(), mt2 = gm2->type(); MatrixType mts = mt1 + mt2;
05107 if (!mtd) { REPORT mtd = mts; }
05108 else if (!(mtd.DataLossOK || mtd >= mts))
05109 {
05110 REPORT
05111 gm1->tDelete(); gm2->tDelete();
05112 Throw(ProgramException("Illegal Conversion", mts, mtd));
05113 }
05114 GeneralMatrix* gmx;
05115 bool c1 = (mtd == mt1), c2 = (mtd == mt2);
05116 if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
05117 {
05118 if (gm1->reuse()) { REPORT AddTo(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05119 else if (gm2->reuse()) { REPORT AddTo(gm2,gm1); gmx = gm2; }
05120 else
05121 {
05122 REPORT
05123
05124 Try { gmx = mt1.New(nr,nc,this); }
05125 CatchAll
05126 {
05127 ReThrow;
05128 }
05129 gmx->ReleaseAndDelete(); Add(gmx,gm1,gm2);
05130 }
05131 }
05132 else
05133 {
05134 if (c1 && c2)
05135 {
05136 short SAO = gm1->SimpleAddOK(gm2);
05137 if (SAO & 1) { REPORT c1 = false; }
05138 if (SAO & 2) { REPORT c2 = false; }
05139 }
05140 if (c1 && gm1->reuse() )
05141 { REPORT AddDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05142 else if (c2 && gm2->reuse() )
05143 { REPORT AddDS(gm2,gm1); if (!c1) gm1->tDelete(); gmx = gm2; }
05144 else
05145 {
05146 REPORT
05147 Try { gmx = mtd.New(nr,nc,this); }
05148 CatchAll
05149 {
05150 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05151 ReThrow;
05152 }
05153 AddDS(gmx,gm1,gm2);
05154 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05155 gmx->ReleaseAndDelete();
05156 }
05157 }
05158 return gmx;
05159 }
05160
05161 GeneralMatrix* SubtractedMatrix::Evaluate(MatrixType mtd)
05162 {
05163 REPORT
05164 Tracer tr("SubtractedMatrix::Evaluate");
05165 gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
05166 int nr=gm1->Nrows(); int nc=gm1->Ncols();
05167 if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
05168 {
05169 Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
05170 CatchAll
05171 {
05172 gm1->tDelete(); gm2->tDelete();
05173 ReThrow;
05174 }
05175 }
05176 MatrixType mt1 = gm1->type(), mt2 = gm2->type(); MatrixType mts = mt1 + mt2;
05177 if (!mtd) { REPORT mtd = mts; }
05178 else if (!(mtd.DataLossOK || mtd >= mts))
05179 {
05180 gm1->tDelete(); gm2->tDelete();
05181 Throw(ProgramException("Illegal Conversion", mts, mtd));
05182 }
05183 GeneralMatrix* gmx;
05184 bool c1 = (mtd == mt1), c2 = (mtd == mt2);
05185 if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
05186 {
05187 if (gm1->reuse())
05188 { REPORT SubtractFrom(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05189 else if (gm2->reuse()) { REPORT ReverseSubtract(gm2,gm1); gmx = gm2; }
05190 else
05191 {
05192 REPORT
05193 Try { gmx = mt1.New(nr,nc,this); }
05194 CatchAll
05195 {
05196 ReThrow;
05197 }
05198 gmx->ReleaseAndDelete(); Subtract(gmx,gm1,gm2);
05199 }
05200 }
05201 else
05202 {
05203 if (c1 && c2)
05204 {
05205 short SAO = gm1->SimpleAddOK(gm2);
05206 if (SAO & 1) { REPORT c1 = false; }
05207 if (SAO & 2) { REPORT c2 = false; }
05208 }
05209 if (c1 && gm1->reuse() )
05210 { REPORT SubtractDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05211 else if (c2 && gm2->reuse() )
05212 {
05213 REPORT ReverseSubtractDS(gm2,gm1);
05214 if (!c1) gm1->tDelete(); gmx = gm2;
05215 }
05216 else
05217 {
05218 REPORT
05219
05220 Try { gmx = mtd.New(nr,nc,this); }
05221 CatchAll
05222 {
05223 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05224 ReThrow;
05225 }
05226 SubtractDS(gmx,gm1,gm2);
05227 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05228 gmx->ReleaseAndDelete();
05229 }
05230 }
05231 return gmx;
05232 }
05233
05234 GeneralMatrix* SPMatrix::Evaluate(MatrixType mtd)
05235 {
05236 REPORT
05237 Tracer tr("SPMatrix::Evaluate");
05238 gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
05239 int nr=gm1->Nrows(); int nc=gm1->Ncols();
05240 if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
05241 {
05242 Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
05243 CatchAll
05244 {
05245 gm1->tDelete(); gm2->tDelete();
05246 ReThrow;
05247 }
05248 }
05249 MatrixType mt1 = gm1->type(), mt2 = gm2->type();
05250 MatrixType mts = mt1.SP(mt2);
05251 if (!mtd) { REPORT mtd = mts; }
05252 else if (!(mtd.DataLossOK || mtd >= mts))
05253 {
05254 gm1->tDelete(); gm2->tDelete();
05255 Throw(ProgramException("Illegal Conversion", mts, mtd));
05256 }
05257 GeneralMatrix* gmx;
05258 bool c1 = (mtd == mt1), c2 = (mtd == mt2);
05259 if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
05260 {
05261 if (gm1->reuse()) { REPORT SP(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05262 else if (gm2->reuse()) { REPORT SP(gm2,gm1); gmx = gm2; }
05263 else
05264 {
05265 REPORT
05266 Try { gmx = mt1.New(nr,nc,this); }
05267 CatchAll
05268 {
05269 ReThrow;
05270 }
05271 gmx->ReleaseAndDelete(); SP(gmx,gm1,gm2);
05272 }
05273 }
05274 else
05275 {
05276 if (c1 && c2)
05277 {
05278 short SAO = gm1->SimpleAddOK(gm2);
05279 if (SAO & 1) { REPORT c2 = false; }
05280 if (SAO & 2) { REPORT c1 = false; }
05281 }
05282 if (c1 && gm1->reuse() )
05283 { REPORT SPDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
05284 else if (c2 && gm2->reuse() )
05285 { REPORT SPDS(gm2,gm1); if (!c1) gm1->tDelete(); gmx = gm2; }
05286 else
05287 {
05288 REPORT
05289
05290 Try { gmx = mtd.New(nr,nc,this); }
05291 CatchAll
05292 {
05293 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05294 ReThrow;
05295 }
05296 SPDS(gmx,gm1,gm2);
05297 if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
05298 gmx->ReleaseAndDelete();
05299 }
05300 }
05301 return gmx;
05302 }
05303
05304
05305
05306
05307
05308 Real BaseMatrix::norm1() const
05309 {
05310
05311 REPORT
05312 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
05313 int nc = gm->Ncols(); Real value = 0.0;
05314 MatrixCol mc(gm, LoadOnEntry);
05315 while (nc--)
05316 { Real v = mc.SumAbsoluteValue(); if (value < v) value = v; mc.Next(); }
05317 gm->tDelete(); return value;
05318 }
05319
05320 Real BaseMatrix::norm_infinity() const
05321 {
05322
05323 REPORT
05324 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
05325 int nr = gm->Nrows(); Real value = 0.0;
05326 MatrixRow mr(gm, LoadOnEntry);
05327 while (nr--)
05328 { Real v = mr.SumAbsoluteValue(); if (value < v) value = v; mr.Next(); }
05329 gm->tDelete(); return value;
05330 }
05331
05332
05333
05334 GeneralMatrix* ConcatenatedMatrix::Evaluate(MatrixType mtx)
05335 {
05336 REPORT
05337 Tracer tr("Concatenate");
05338 gm2 = ((BaseMatrix*&)bm2)->Evaluate();
05339 gm1 = ((BaseMatrix*&)bm1)->Evaluate();
05340 Compare(gm1->type() | gm2->type(),mtx);
05341 int nr=gm1->Nrows(); int nc = gm1->Ncols() + gm2->Ncols();
05342 if (nr != gm2->Nrows())
05343 Throw(IncompatibleDimensionsException(*gm1, *gm2));
05344 GeneralMatrix* gmx = mtx.New(nr,nc,this);
05345 MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
05346 MatrixRow mr(gmx, StoreOnExit+DirectPart);
05347 while (nr--) { mr.ConCat(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
05348 gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
05349 }
05350
05351 GeneralMatrix* StackedMatrix::Evaluate(MatrixType mtx)
05352 {
05353 REPORT
05354 Tracer tr("Stack");
05355 gm2 = ((BaseMatrix*&)bm2)->Evaluate();
05356 gm1 = ((BaseMatrix*&)bm1)->Evaluate();
05357 Compare(gm1->type() & gm2->type(),mtx);
05358 int nc=gm1->Ncols();
05359 int nr1 = gm1->Nrows(); int nr2 = gm2->Nrows();
05360 if (nc != gm2->Ncols())
05361 Throw(IncompatibleDimensionsException(*gm1, *gm2));
05362 GeneralMatrix* gmx = mtx.New(nr1+nr2,nc,this);
05363 MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
05364 MatrixRow mr(gmx, StoreOnExit+DirectPart);
05365 while (nr1--) { mr.Copy(mr1); mr1.Next(); mr.Next(); }
05366 while (nr2--) { mr.Copy(mr2); mr2.Next(); mr.Next(); }
05367 gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
05368 }
05369
05370
05371
05372 static bool RealEqual(Real* s1, Real* s2, int n)
05373 {
05374 int i = n >> 2;
05375 while (i--)
05376 {
05377 if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
05378 if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
05379 }
05380 i = n & 3; while (i--) if (*s1++ != *s2++) return false;
05381 return true;
05382 }
05383
05384 static bool intEqual(int* s1, int* s2, int n)
05385 {
05386 int i = n >> 2;
05387 while (i--)
05388 {
05389 if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
05390 if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
05391 }
05392 i = n & 3; while (i--) if (*s1++ != *s2++) return false;
05393 return true;
05394 }
05395
05396
05397 bool operator==(const BaseMatrix& A, const BaseMatrix& B)
05398 {
05399 Tracer tr("BaseMatrix ==");
05400 REPORT
05401 GeneralMatrix* gmA = ((BaseMatrix&)A).Evaluate();
05402 GeneralMatrix* gmB = ((BaseMatrix&)B).Evaluate();
05403
05404 if (gmA == gmB)
05405 { REPORT gmA->tDelete(); return true; }
05406
05407 if ( gmA->Nrows() != gmB->Nrows() || gmA->Ncols() != gmB->Ncols() )
05408
05409 { REPORT gmA->tDelete(); gmB->tDelete(); return false; }
05410
05411
05412 MatrixType AType = gmA->type(); MatrixType BType = gmB->type();
05413 if (AType.CannotConvert() || BType.CannotConvert() )
05414 {
05415 REPORT
05416 bool bx = gmA->IsEqual(*gmB);
05417 gmA->tDelete(); gmB->tDelete();
05418 return bx;
05419 }
05420
05421
05422
05423 if (AType == BType && gmA->bandwidth() == gmB->bandwidth())
05424 {
05425 REPORT
05426 bool bx = RealEqual(gmA->Store(),gmB->Store(),gmA->Storage());
05427 gmA->tDelete(); gmB->tDelete();
05428 return bx;
05429 }
05430
05431
05432 REPORT return is_zero(*gmA-*gmB);
05433 }
05434
05435 bool operator==(const GeneralMatrix& A, const GeneralMatrix& B)
05436 {
05437 Tracer tr("GeneralMatrix ==");
05438
05439 REPORT
05440
05441 if (&A == &B)
05442 { REPORT return true; }
05443
05444 if ( A.Nrows() != B.Nrows() || A.Ncols() != B.Ncols() )
05445 { REPORT return false; }
05446
05447
05448 MatrixType AType = A.Type(); MatrixType BType = B.Type();
05449 if (AType.CannotConvert() || BType.CannotConvert() )
05450 { REPORT return A.IsEqual(B); }
05451
05452
05453
05454 if (AType == BType && A.bandwidth() == B.bandwidth())
05455 { REPORT return RealEqual(A.Store(),B.Store(),A.Storage()); }
05456
05457
05458 REPORT return is_zero(A-B);
05459 }
05460
05461 bool GeneralMatrix::is_zero() const
05462 {
05463 REPORT
05464 Real* s=store; int i = storage >> 2;
05465 while (i--)
05466 {
05467 if (*s++) return false; if (*s++) return false;
05468 if (*s++) return false; if (*s++) return false;
05469 }
05470 i = storage & 3; while (i--) if (*s++) return false;
05471 return true;
05472 }
05473
05474 bool is_zero(const BaseMatrix& A)
05475 {
05476 Tracer tr("BaseMatrix::is_zero");
05477 REPORT
05478 GeneralMatrix* gm1 = 0; bool bx;
05479 Try { gm1=((BaseMatrix&)A).Evaluate(); bx = gm1->is_zero(); }
05480 CatchAll { if (gm1) gm1->tDelete(); ReThrow; }
05481 gm1->tDelete();
05482 return bx;
05483 }
05484
05485
05486
05487
05488 bool GeneralMatrix::IsEqual(const GeneralMatrix& A) const
05489 {
05490 Tracer tr("GeneralMatrix IsEqual");
05491 if (A.type() != type())
05492 { REPORT return false; }
05493 if (&A == this)
05494 { REPORT return true; }
05495 if (A.nrows_val != nrows_val || A.ncols_val != ncols_val)
05496
05497 { REPORT return false; }
05498
05499 REPORT
05500 return RealEqual(A.store,store,storage);
05501 }
05502
05503 bool CroutMatrix::IsEqual(const GeneralMatrix& A) const
05504 {
05505 Tracer tr("CroutMatrix IsEqual");
05506 if (A.type() != type())
05507 { REPORT return false; }
05508 if (&A == this)
05509 { REPORT return true; }
05510 if (A.nrows_val != nrows_val || A.ncols_val != ncols_val)
05511
05512 { REPORT return false; }
05513
05514 REPORT
05515 return RealEqual(A.store,store,storage)
05516 && intEqual(((CroutMatrix&)A).indx, indx, nrows_val);
05517 }
05518
05519
05520 bool BandLUMatrix::IsEqual(const GeneralMatrix& A) const
05521 {
05522 Tracer tr("BandLUMatrix IsEqual");
05523 if (A.type() != type())
05524 { REPORT return false; }
05525 if (&A == this)
05526 { REPORT return true; }
05527 if ( A.Nrows() != nrows_val || A.Ncols() != ncols_val
05528 || ((BandLUMatrix&)A).m1 != m1 || ((BandLUMatrix&)A).m2 != m2 )
05529
05530 { REPORT return false; }
05531
05532
05533 REPORT
05534 return RealEqual(A.Store(),store,storage)
05535 && RealEqual(((BandLUMatrix&)A).store2,store2,storage2)
05536 && intEqual(((BandLUMatrix&)A).indx, indx, nrows_val);
05537 }
05538
05539
05540
05541
05542 inline void crossproduct_body(Real* a, Real* b, Real* c)
05543 {
05544 c[0] = a[1] * b[2] - a[2] * b[1];
05545 c[1] = a[2] * b[0] - a[0] * b[2];
05546 c[2] = a[0] * b[1] - a[1] * b[0];
05547 }
05548
05549 Matrix crossproduct(const Matrix& A, const Matrix& B)
05550 {
05551 REPORT
05552 int ac = A.Ncols(); int ar = A.Nrows();
05553 int bc = B.Ncols(); int br = B.Nrows();
05554 Real* a = A.Store(); Real* b = B.Store();
05555 if (ac == 3)
05556 {
05557 if (bc != 3 || ar != 1 || br != 1)
05558 { Tracer et("crossproduct"); IncompatibleDimensionsException(A, B); }
05559 REPORT
05560 RowVector C(3); Real* c = C.Store(); crossproduct_body(a, b, c);
05561 return (Matrix&)C;
05562 }
05563 else
05564 {
05565 if (ac != 1 || bc != 1 || ar != 3 || br != 3)
05566 { Tracer et("crossproduct"); IncompatibleDimensionsException(A, B); }
05567 REPORT
05568 ColumnVector C(3); Real* c = C.Store(); crossproduct_body(a, b, c);
05569 return (Matrix&)C;
05570 }
05571 }
05572
05573 ReturnMatrix crossproduct_rows(const Matrix& A, const Matrix& B)
05574 {
05575 REPORT
05576 int n = A.Nrows();
05577 if (A.Ncols() != 3 || B.Ncols() != 3 || n != B.Nrows())
05578 {
05579 Tracer et("crossproduct_rows"); IncompatibleDimensionsException(A, B);
05580 }
05581 Matrix C(n, 3);
05582 Real* a = A.Store(); Real* b = B.Store(); Real* c = C.Store();
05583 if (n--)
05584 {
05585 for (;;)
05586 {
05587 crossproduct_body(a, b, c);
05588 if (!(n--)) break;
05589 a += 3; b += 3; c += 3;
05590 }
05591 }
05592
05593 return C.ForReturn();
05594 }
05595
05596 ReturnMatrix crossproduct_columns(const Matrix& A, const Matrix& B)
05597 {
05598 REPORT
05599 int n = A.Ncols();
05600 if (A.Nrows() != 3 || B.Nrows() != 3 || n != B.Ncols())
05601 {
05602 Tracer et("crossproduct_columns");
05603 IncompatibleDimensionsException(A, B);
05604 }
05605 Matrix C(3, n);
05606 Real* a = A.Store(); Real* b = B.Store(); Real* c = C.Store();
05607 Real* an = a+n; Real* an2 = an+n;
05608 Real* bn = b+n; Real* bn2 = bn+n;
05609 Real* cn = c+n; Real* cn2 = cn+n;
05610
05611 int i = n;
05612 while (i--)
05613 {
05614 *c++ = *an * *bn2 - *an2 * *bn;
05615 *cn++ = *an2++ * *b - *a * *bn2++;
05616 *cn2++ = *a++ * *bn++ - *an++ * *b++;
05617 }
05618
05619 return C.ForReturn();
05620 }
05621
05622
05623 #ifdef use_namespace
05624 }
05625 #endif
05626
05628
05631
05634
05635
05636
05637
05638
05639 #ifdef use_namespace
05640 namespace NEWMAT {
05641 #endif
05642
05643
05644 #ifdef DO_REPORT
05645 #define REPORT { static ExeCounter ExeCount(__LINE__,3); ++ExeCount; }
05646 #else
05647 #define REPORT {}
05648 #endif
05649
05650
05651
05652
05653 #define MONITOR(what,store,storage) {}
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708 void GeneralMatrix::NextRow(MatrixRowCol& mrc)
05709 {
05710 REPORT
05711 if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreRow(mrc); }
05712 mrc.rowcol++;
05713 if (mrc.rowcol<nrows_val) { REPORT this->GetRow(mrc); }
05714 else { REPORT mrc.cw -= StoreOnExit; }
05715 }
05716
05717 void GeneralMatrix::NextCol(MatrixRowCol& mrc)
05718 {
05719 REPORT
05720 if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
05721 mrc.rowcol++;
05722 if (mrc.rowcol<ncols_val) { REPORT this->GetCol(mrc); }
05723 else { REPORT mrc.cw -= StoreOnExit; }
05724 }
05725
05726 void GeneralMatrix::NextCol(MatrixColX& mrc)
05727 {
05728 REPORT
05729 if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
05730 mrc.rowcol++;
05731 if (mrc.rowcol<ncols_val) { REPORT this->GetCol(mrc); }
05732 else { REPORT mrc.cw -= StoreOnExit; }
05733 }
05734
05735
05736
05737
05738 void Matrix::GetRow(MatrixRowCol& mrc)
05739 {
05740 REPORT
05741 mrc.skip=0; mrc.storage=mrc.length=ncols_val;
05742 mrc.data=store+mrc.rowcol*ncols_val;
05743 }
05744
05745
05746 void Matrix::GetCol(MatrixRowCol& mrc)
05747 {
05748 REPORT
05749 mrc.skip=0; mrc.storage=mrc.length=nrows_val;
05750 if ( ncols_val==1 && !(mrc.cw*StoreHere) )
05751 { REPORT mrc.data=store; }
05752 else
05753 {
05754 Real* ColCopy;
05755 if ( !(mrc.cw*(HaveStore+StoreHere)) )
05756 {
05757 REPORT
05758 ColCopy = new Real [nrows_val]; MatrixErrorNoSpace(ColCopy);
05759 MONITOR_REAL_NEW("Make (MatGetCol)",nrows_val,ColCopy)
05760 mrc.data = ColCopy; mrc.cw += HaveStore;
05761 }
05762 else { REPORT ColCopy = mrc.data; }
05763 if (+(mrc.cw*LoadOnEntry))
05764 {
05765 REPORT
05766 Real* Mstore = store+mrc.rowcol; int i=nrows_val;
05767
05768 if (i) for (;;)
05769 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols_val; }
05770 }
05771 }
05772 }
05773
05774 void Matrix::GetCol(MatrixColX& mrc)
05775 {
05776 REPORT
05777 mrc.skip=0; mrc.storage=nrows_val; mrc.length=nrows_val;
05778 if (+(mrc.cw*LoadOnEntry))
05779 {
05780 REPORT Real* ColCopy = mrc.data;
05781 Real* Mstore = store+mrc.rowcol; int i=nrows_val;
05782
05783 if (i) for (;;)
05784 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols_val; }
05785 }
05786 }
05787
05788 void Matrix::RestoreCol(MatrixRowCol& mrc)
05789 {
05790
05791 REPORT
05792 if (+(mrc.cw*HaveStore))
05793 {
05794 REPORT
05795 Real* Mstore = store+mrc.rowcol; int i=nrows_val;
05796 Real* Cstore = mrc.data;
05797
05798 if (i) for (;;)
05799 { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols_val; }
05800 }
05801 }
05802
05803 void Matrix::RestoreCol(MatrixColX& mrc)
05804 {
05805 REPORT
05806 Real* Mstore = store+mrc.rowcol; int i=nrows_val; Real* Cstore = mrc.data;
05807
05808 if (i) for (;;)
05809 { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols_val; }
05810 }
05811
05812 void Matrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrMat(); }
05813
05814 void Matrix::NextCol(MatrixRowCol& mrc)
05815 {
05816 REPORT
05817 if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
05818 mrc.rowcol++;
05819 if (mrc.rowcol<ncols_val)
05820 {
05821 if (+(mrc.cw*LoadOnEntry))
05822 {
05823 REPORT
05824 Real* ColCopy = mrc.data;
05825 Real* Mstore = store+mrc.rowcol; int i=nrows_val;
05826
05827 if (i) for (;;)
05828 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols_val; }
05829 }
05830 }
05831 else { REPORT mrc.cw -= StoreOnExit; }
05832 }
05833
05834 void Matrix::NextCol(MatrixColX& mrc)
05835 {
05836 REPORT
05837 if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
05838 mrc.rowcol++;
05839 if (mrc.rowcol<ncols_val)
05840 {
05841 if (+(mrc.cw*LoadOnEntry))
05842 {
05843 REPORT
05844 Real* ColCopy = mrc.data;
05845 Real* Mstore = store+mrc.rowcol; int i=nrows_val;
05846
05847 if (i) for (;;)
05848 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols_val; }
05849 }
05850 }
05851 else { REPORT mrc.cw -= StoreOnExit; }
05852 }
05853
05854
05855
05856 void DiagonalMatrix::GetRow(MatrixRowCol& mrc)
05857 {
05858 REPORT
05859 mrc.skip=mrc.rowcol; mrc.storage=1;
05860 mrc.data=store+mrc.skip; mrc.length=ncols_val;
05861 }
05862
05863 void DiagonalMatrix::GetCol(MatrixRowCol& mrc)
05864 {
05865 REPORT
05866 mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows_val;
05867 if (+(mrc.cw*StoreHere))
05868 Throw(InternalException("DiagonalMatrix::GetCol(MatrixRowCol&)"));
05869 else { REPORT mrc.data=store+mrc.skip; }
05870
05871 }
05872
05873 void DiagonalMatrix::GetCol(MatrixColX& mrc)
05874 {
05875 REPORT
05876 mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows_val;
05877 mrc.data = mrc.store+mrc.skip;
05878 *(mrc.data)=*(store+mrc.skip);
05879 }
05880
05881 void DiagonalMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
05882
05883
05884 void DiagonalMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
05885
05886
05887 void DiagonalMatrix::NextCol(MatrixColX& mrc)
05888 {
05889 REPORT
05890 if (+(mrc.cw*StoreOnExit))
05891 { REPORT *(store+mrc.rowcol)=*(mrc.data); }
05892 mrc.IncrDiag();
05893 int t1 = +(mrc.cw*LoadOnEntry);
05894 if (t1 && mrc.rowcol < ncols_val)
05895 { REPORT *(mrc.data)=*(store+mrc.rowcol); }
05896 }
05897
05898
05899
05900 void UpperTriangularMatrix::GetRow(MatrixRowCol& mrc)
05901 {
05902 REPORT
05903 int row = mrc.rowcol; mrc.skip=row; mrc.length=ncols_val;
05904 mrc.storage=ncols_val-row; mrc.data=store+(row*(2*ncols_val-row+1))/2;
05905 }
05906
05907
05908 void UpperTriangularMatrix::GetCol(MatrixRowCol& mrc)
05909 {
05910 REPORT
05911 mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
05912 mrc.length=nrows_val; Real* ColCopy;
05913 if ( !(mrc.cw*(StoreHere+HaveStore)) )
05914 {
05915 REPORT
05916 ColCopy = new Real [nrows_val]; MatrixErrorNoSpace(ColCopy);
05917 MONITOR_REAL_NEW("Make (UT GetCol)",nrows_val,ColCopy)
05918 mrc.data = ColCopy; mrc.cw += HaveStore;
05919 }
05920 else { REPORT ColCopy = mrc.data; }
05921 if (+(mrc.cw*LoadOnEntry))
05922 {
05923 REPORT
05924 Real* Mstore = store+mrc.rowcol; int j = ncols_val;
05925
05926 if (i) for (;;)
05927 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
05928 }
05929 }
05930
05931 void UpperTriangularMatrix::GetCol(MatrixColX& mrc)
05932 {
05933 REPORT
05934 mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
05935 mrc.length=nrows_val;
05936 if (+(mrc.cw*LoadOnEntry))
05937 {
05938 REPORT
05939 Real* ColCopy = mrc.data;
05940 Real* Mstore = store+mrc.rowcol; int j = ncols_val;
05941
05942 if (i) for (;;)
05943 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
05944 }
05945 }
05946
05947 void UpperTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
05948 {
05949 REPORT
05950 Real* Mstore = store+mrc.rowcol; int i=mrc.rowcol+1; int j = ncols_val;
05951 Real* Cstore = mrc.data;
05952
05953 if (i) for (;;)
05954 { *Mstore = *Cstore++; if (!(--i)) break; Mstore += --j; }
05955 }
05956
05957 void UpperTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrUT(); }
05958
05959
05960
05961
05962 void LowerTriangularMatrix::GetRow(MatrixRowCol& mrc)
05963 {
05964 REPORT
05965 int row=mrc.rowcol; mrc.skip=0; mrc.storage=row+1; mrc.length=ncols_val;
05966 mrc.data=store+(row*(row+1))/2;
05967 }
05968
05969 void LowerTriangularMatrix::GetCol(MatrixRowCol& mrc)
05970 {
05971 REPORT
05972 int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows_val;
05973 int i=nrows_val-col; mrc.storage=i; Real* ColCopy;
05974 if ( +(mrc.cw*(StoreHere+HaveStore)) )
05975 { REPORT ColCopy = mrc.data; }
05976 else
05977 {
05978 REPORT
05979 ColCopy = new Real [nrows_val]; MatrixErrorNoSpace(ColCopy);
05980 MONITOR_REAL_NEW("Make (LT GetCol)",nrows_val,ColCopy)
05981 mrc.cw += HaveStore; mrc.data = ColCopy;
05982 }
05983
05984 if (+(mrc.cw*LoadOnEntry))
05985 {
05986 REPORT
05987 Real* Mstore = store+(col*(col+3))/2;
05988
05989 if (i) for (;;)
05990 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
05991 }
05992 }
05993
05994 void LowerTriangularMatrix::GetCol(MatrixColX& mrc)
05995 {
05996 REPORT
05997 int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows_val;
05998 int i=nrows_val-col; mrc.storage=i; mrc.data = mrc.store + col;
05999
06000 if (+(mrc.cw*LoadOnEntry))
06001 {
06002 REPORT Real* ColCopy = mrc.data;
06003 Real* Mstore = store+(col*(col+3))/2;
06004
06005 if (i) for (;;)
06006 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
06007 }
06008 }
06009
06010 void LowerTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
06011 {
06012 REPORT
06013 int col=mrc.rowcol; Real* Cstore = mrc.data;
06014 Real* Mstore = store+(col*(col+3))/2; int i=nrows_val-col;
06015
06016 if (i) for (;;)
06017 { *Mstore = *Cstore++; if (!(--i)) break; Mstore += ++col; }
06018 }
06019
06020 void LowerTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrLT(); }
06021
06022
06023
06024
06025 void SymmetricMatrix::GetRow(MatrixRowCol& mrc)
06026 {
06027 REPORT
06028 mrc.skip=0; int row=mrc.rowcol; mrc.length=ncols_val;
06029 if (+(mrc.cw*DirectPart))
06030 { REPORT mrc.storage=row+1; mrc.data=store+(row*(row+1))/2; }
06031 else
06032 {
06033
06034 if (+(mrc.cw*StoreOnExit))
06035 Throw(InternalException("SymmetricMatrix::GetRow(MatrixRowCol&)"));
06036 mrc.storage=ncols_val; Real* RowCopy;
06037 if (!(mrc.cw*HaveStore))
06038 {
06039 REPORT
06040 RowCopy = new Real [ncols_val]; MatrixErrorNoSpace(RowCopy);
06041 MONITOR_REAL_NEW("Make (SymGetRow)",ncols_val,RowCopy)
06042 mrc.cw += HaveStore; mrc.data = RowCopy;
06043 }
06044 else { REPORT RowCopy = mrc.data; }
06045 if (+(mrc.cw*LoadOnEntry))
06046 {
06047 REPORT
06048 Real* Mstore = store+(row*(row+1))/2; int i = row;
06049 while (i--) *RowCopy++ = *Mstore++;
06050 i = ncols_val-row;
06051
06052 if (i) for (;;)
06053 { *RowCopy++ = *Mstore; if (!(--i)) break; Mstore += ++row; }
06054 }
06055 }
06056 }
06057
06058 void SymmetricMatrix::GetCol(MatrixRowCol& mrc)
06059 {
06060
06061 if (+(mrc.cw*StoreHere))
06062 Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
06063
06064 int col=mrc.rowcol; mrc.length=nrows_val;
06065 REPORT
06066 mrc.skip=0;
06067 if (+(mrc.cw*DirectPart))
06068 { REPORT mrc.storage=col+1; mrc.data=store+(col*(col+1))/2; }
06069 else
06070 {
06071
06072 if (+(mrc.cw*StoreOnExit))
06073 Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
06074
06075 mrc.storage=ncols_val; Real* ColCopy;
06076 if ( +(mrc.cw*HaveStore)) { REPORT ColCopy = mrc.data; }
06077 else
06078 {
06079 REPORT
06080 ColCopy = new Real [ncols_val]; MatrixErrorNoSpace(ColCopy);
06081 MONITOR_REAL_NEW("Make (SymGetCol)",ncols_val,ColCopy)
06082 mrc.cw += HaveStore; mrc.data = ColCopy;
06083 }
06084 if (+(mrc.cw*LoadOnEntry))
06085 {
06086 REPORT
06087 Real* Mstore = store+(col*(col+1))/2; int i = col;
06088 while (i--) *ColCopy++ = *Mstore++;
06089 i = ncols_val-col;
06090
06091 if (i) for (;;)
06092 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
06093 }
06094 }
06095 }
06096
06097 void SymmetricMatrix::GetCol(MatrixColX& mrc)
06098 {
06099 int col=mrc.rowcol; mrc.length=nrows_val;
06100 if (+(mrc.cw*DirectPart))
06101 {
06102 REPORT
06103 mrc.skip=col; int i=nrows_val-col; mrc.storage=i;
06104 mrc.data = mrc.store+col;
06105 if (+(mrc.cw*LoadOnEntry))
06106 {
06107 REPORT
06108 Real* ColCopy = mrc.data;
06109 Real* Mstore = store+(col*(col+3))/2;
06110
06111 if (i) for (;;)
06112 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
06113 }
06114 }
06115 else
06116 {
06117 REPORT
06118
06119 if (+(mrc.cw*StoreOnExit))
06120 Throw(InternalException("SymmetricMatrix::GetCol(MatrixColX&)"));
06121
06122 mrc.skip=0; mrc.storage=ncols_val;
06123 if (+(mrc.cw*LoadOnEntry))
06124 {
06125 REPORT
06126 Real* ColCopy = mrc.data;
06127 Real* Mstore = store+(col*(col+1))/2; int i = col;
06128 while (i--) *ColCopy++ = *Mstore++;
06129 i = ncols_val-col;
06130
06131 if (i) for (;;)
06132 { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
06133 }
06134 }
06135 }
06136
06137
06138
06139 void SymmetricMatrix::RestoreCol(MatrixColX& mrc)
06140 {
06141 REPORT
06142
06143 int col=mrc.rowcol; Real* Cstore = mrc.data;
06144 Real* Mstore = store+(col*(col+3))/2; int i = nrows_val-col;
06145
06146 if (i) for (;;)
06147 { *Mstore = *Cstore++; if (!(--i)) break; Mstore+= ++col; }
06148
06149 }
06150
06151
06152
06153 void RowVector::GetCol(MatrixRowCol& mrc)
06154 {
06155 REPORT
06156
06157 if (+(mrc.cw*StoreHere))
06158 Throw(InternalException("RowVector::GetCol(MatrixRowCol&)"));
06159
06160 mrc.skip=0; mrc.storage=1; mrc.length=nrows_val;
06161 mrc.data = store+mrc.rowcol;
06162
06163 }
06164
06165 void RowVector::GetCol(MatrixColX& mrc)
06166 {
06167 REPORT
06168 mrc.skip=0; mrc.storage=1; mrc.length=nrows_val;
06169 if (mrc.cw >= LoadOnEntry)
06170 { REPORT *(mrc.data) = *(store+mrc.rowcol); }
06171
06172 }
06173
06174 void RowVector::NextCol(MatrixRowCol& mrc)
06175 { REPORT mrc.rowcol++; mrc.data++; }
06176
06177 void RowVector::NextCol(MatrixColX& mrc)
06178 {
06179 if (+(mrc.cw*StoreOnExit)) { REPORT *(store+mrc.rowcol)=*(mrc.data); }
06180
06181 mrc.rowcol++;
06182 if (mrc.rowcol < ncols_val)
06183 {
06184 if (+(mrc.cw*LoadOnEntry)) { REPORT *(mrc.data)=*(store+mrc.rowcol); }
06185 }
06186 else { REPORT mrc.cw -= StoreOnExit; }
06187 }
06188
06189 void RowVector::RestoreCol(MatrixColX& mrc)
06190 { REPORT *(store+mrc.rowcol)=*(mrc.data); }
06191
06192
06193
06194
06195 void BandMatrix::GetRow(MatrixRowCol& mrc)
06196 {
06197 REPORT
06198 int r = mrc.rowcol; int w = lower_val+1+upper_val; mrc.length=ncols_val;
06199 int s = r-lower_val;
06200 if (s<0) { mrc.data = store+(r*w-s); w += s; s = 0; }
06201 else mrc.data = store+r*w;
06202 mrc.skip = s; s += w-ncols_val; if (s>0) w -= s; mrc.storage = w;
06203 }
06204
06205
06206
06207 void BandMatrix::NextRow(MatrixRowCol& mrc)
06208 {
06209 REPORT
06210 int r = ++mrc.rowcol;
06211 if (r<=lower_val) { mrc.storage++; mrc.data += lower_val+upper_val; }
06212 else { mrc.skip++; mrc.data += lower_val+upper_val+1; }
06213 if (r>=ncols_val-upper_val) mrc.storage--;
06214 }
06215
06216 void BandMatrix::GetCol(MatrixRowCol& mrc)
06217 {
06218 REPORT
06219 int c = mrc.rowcol; int n = lower_val+upper_val; int w = n+1;
06220 mrc.length=nrows_val; Real* ColCopy;
06221 int b; int s = c-upper_val;
06222 if (s<=0) { w += s; s = 0; b = c+lower_val; } else b = s*w+n;
06223 mrc.skip = s; s += w-nrows_val; if (s>0) w -= s; mrc.storage = w;
06224 if ( +(mrc.cw*(StoreHere+HaveStore)) )
06225 { REPORT ColCopy = mrc.data; }
06226 else
06227 {
06228 REPORT
06229 ColCopy = new Real [n+1]; MatrixErrorNoSpace(ColCopy);
06230 MONITOR_REAL_NEW("Make (BMGetCol)",n+1,ColCopy)
06231 mrc.cw += HaveStore; mrc.data = ColCopy;
06232 }
06233
06234 if (+(mrc.cw*LoadOnEntry))
06235 {
06236 REPORT
06237 Real* Mstore = store+b;
06238
06239 if (w) for (;;)
06240 { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
06241 }
06242 }
06243
06244 void BandMatrix::GetCol(MatrixColX& mrc)
06245 {
06246 REPORT
06247 int c = mrc.rowcol; int n = lower_val+upper_val; int w = n+1;
06248 mrc.length=nrows_val; int b; int s = c-upper_val;
06249 if (s<=0) { w += s; s = 0; b = c+lower_val; } else b = s*w+n;
06250 mrc.skip = s; s += w-nrows_val; if (s>0) w -= s; mrc.storage = w;
06251 mrc.data = mrc.store+mrc.skip;
06252
06253 if (+(mrc.cw*LoadOnEntry))
06254 {
06255 REPORT
06256 Real* ColCopy = mrc.data; Real* Mstore = store+b;
06257
06258 if (w) for (;;)
06259 { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
06260 }
06261 }
06262
06263 void BandMatrix::RestoreCol(MatrixRowCol& mrc)
06264 {
06265 REPORT
06266 int c = mrc.rowcol; int n = lower_val+upper_val; int s = c-upper_val;
06267 Real* Mstore = store + ((s<=0) ? c+lower_val : s*n+s+n);
06268 Real* Cstore = mrc.data;
06269 int w = mrc.storage;
06270
06271 if (w) for (;;)
06272 { *Mstore = *Cstore++; if (!(--w)) break; Mstore += n; }
06273 }
06274
06275
06276
06277 void SymmetricBandMatrix::GetRow(MatrixRowCol& mrc)
06278 {
06279 REPORT
06280 int r=mrc.rowcol; int s = r-lower_val; int w1 = lower_val+1; int o = r*w1;
06281 mrc.length = ncols_val;
06282 if (s<0) { w1 += s; o -= s; s = 0; }
06283 mrc.skip = s;
06284
06285 if (+(mrc.cw*DirectPart))
06286 { REPORT mrc.data = store+o; mrc.storage = w1; }
06287 else
06288 {
06289
06290 if (+(mrc.cw*StoreOnExit))
06291 Throw(InternalException("SymmetricBandMatrix::GetRow(MatrixRowCol&)"));
06292 int w = w1+lower_val; s += w-ncols_val; Real* RowCopy;
06293 if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
06294 if (!(mrc.cw*HaveStore))
06295 {
06296 REPORT
06297 RowCopy = new Real [2*lower_val+1]; MatrixErrorNoSpace(RowCopy);
06298 MONITOR_REAL_NEW("Make (SmBGetRow)",2*lower_val+1,RowCopy)
06299 mrc.cw += HaveStore; mrc.data = RowCopy;
06300 }
06301 else { REPORT RowCopy = mrc.data; }
06302
06303 if (+(mrc.cw*LoadOnEntry) && ncols_val > 0)
06304 {
06305 REPORT
06306 Real* Mstore = store+o;
06307 while (w1--) *RowCopy++ = *Mstore++;
06308 Mstore--;
06309 while (w2--) { Mstore += lower_val; *RowCopy++ = *Mstore; }
06310 }
06311 }
06312 }
06313
06314 void SymmetricBandMatrix::GetCol(MatrixRowCol& mrc)
06315 {
06316
06317 if (+(mrc.cw*StoreHere))
06318 Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
06319
06320 int c=mrc.rowcol; int w1 = lower_val+1; mrc.length=nrows_val;
06321 REPORT
06322 int s = c-lower_val; int o = c*w1;
06323 if (s<0) { w1 += s; o -= s; s = 0; }
06324 mrc.skip = s;
06325
06326 if (+(mrc.cw*DirectPart))
06327 { REPORT mrc.data = store+o; mrc.storage = w1; }
06328 else
06329 {
06330
06331 if (+(mrc.cw*StoreOnExit))
06332 Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
06333 int w = w1+lower_val; s += w-ncols_val; Real* ColCopy;
06334 if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
06335
06336 if ( +(mrc.cw*HaveStore) ) { REPORT ColCopy = mrc.data; }
06337 else
06338 {
06339 REPORT ColCopy = new Real [2*lower_val+1]; MatrixErrorNoSpace(ColCopy);
06340 MONITOR_REAL_NEW("Make (SmBGetCol)",2*lower_val+1,ColCopy)
06341 mrc.cw += HaveStore; mrc.data = ColCopy;
06342 }
06343
06344 if (+(mrc.cw*LoadOnEntry))
06345 {
06346 REPORT
06347 Real* Mstore = store+o;
06348 while (w1--) *ColCopy++ = *Mstore++;
06349 Mstore--;
06350 while (w2--) { Mstore += lower_val; *ColCopy++ = *Mstore; }
06351 }
06352 }
06353 }
06354
06355 void SymmetricBandMatrix::GetCol(MatrixColX& mrc)
06356 {
06357 int c=mrc.rowcol; int w1 = lower_val+1; mrc.length=nrows_val;
06358 if (+(mrc.cw*DirectPart))
06359 {
06360 REPORT
06361 int b = c*w1+lower_val;
06362 mrc.skip = c; c += w1-nrows_val; w1 -= c; mrc.storage = w1;
06363 Real* ColCopy = mrc.data = mrc.store+mrc.skip;
06364 if (+(mrc.cw*LoadOnEntry))
06365 {
06366 REPORT
06367 Real* Mstore = store+b;
06368
06369 if (w1) for (;;)
06370 { *ColCopy++ = *Mstore; if (!(--w1)) break; Mstore += lower_val; }
06371 }
06372 }
06373 else
06374 {
06375 REPORT
06376
06377 if (+(mrc.cw*StoreOnExit))
06378 Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixColX&)"));
06379 int s = c-lower_val; int o = c*w1;
06380 if (s<0) { w1 += s; o -= s; s = 0; }
06381 mrc.skip = s;
06382
06383 int w = w1+lower_val; s += w-ncols_val;
06384 if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
06385
06386 Real* ColCopy = mrc.data = mrc.store+mrc.skip;
06387
06388 if (+(mrc.cw*LoadOnEntry))
06389 {
06390 REPORT
06391 Real* Mstore = store+o;
06392 while (w1--) *ColCopy++ = *Mstore++;
06393 Mstore--;
06394 while (w2--) { Mstore += lower_val; *ColCopy++ = *Mstore; }
06395 }
06396
06397 }
06398 }
06399
06400 void SymmetricBandMatrix::RestoreCol(MatrixColX& mrc)
06401 {
06402 REPORT
06403 int c = mrc.rowcol;
06404 Real* Mstore = store + c*lower_val+c+lower_val;
06405 Real* Cstore = mrc.data; int w = mrc.storage;
06406
06407 if (w) for (;;)
06408 { *Mstore = *Cstore++; if (!(--w)) break; Mstore += lower_val; }
06409 }
06410
06411
06412
06413 void IdentityMatrix::GetRow(MatrixRowCol& mrc)
06414 {
06415 REPORT
06416 mrc.skip=mrc.rowcol; mrc.storage=1; mrc.data=store; mrc.length=ncols_val;
06417 }
06418
06419 void IdentityMatrix::GetCol(MatrixRowCol& mrc)
06420 {
06421 REPORT
06422 mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows_val;
06423 if (+(mrc.cw*StoreHere))
06424 Throw(InternalException("IdentityMatrix::GetCol(MatrixRowCol&)"));
06425 else { REPORT mrc.data=store; }
06426 }
06427
06428 void IdentityMatrix::GetCol(MatrixColX& mrc)
06429 {
06430 REPORT
06431 mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows_val;
06432 mrc.data = mrc.store+mrc.skip; *(mrc.data)=*store;
06433 }
06434
06435 void IdentityMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
06436
06437 void IdentityMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
06438
06439 void IdentityMatrix::NextCol(MatrixColX& mrc)
06440 {
06441 REPORT
06442 if (+(mrc.cw*StoreOnExit)) { REPORT *store=*(mrc.data); }
06443 mrc.IncrDiag();
06444 int t1 = +(mrc.cw*LoadOnEntry);
06445 if (t1 && mrc.rowcol < ncols_val) { REPORT *(mrc.data)=*store; }
06446 }
06447
06448
06449
06450
06451
06452
06453 MatrixRowCol::~MatrixRowCol()
06454 {
06455 if (+(cw*HaveStore))
06456 {
06457 MONITOR_REAL_DELETE("Free (RowCol)",-1,data)
06458 delete [] data;
06459 }
06460 }
06461
06462 MatrixRow::~MatrixRow() { if (+(cw*StoreOnExit)) gm->RestoreRow(*this); }
06463
06464 MatrixCol::~MatrixCol() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
06465
06466 MatrixColX::~MatrixColX() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
06467
06468 #ifdef use_namespace
06469 }
06470 #endif
06471
06473
06474
06475
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513
06514
06515
06516
06517
06518
06519
06520
06521
06522
06523
06529
06530 static const char rcsid[] = "$Id: homogen.cpp,v 1.15 2006/11/15 18:35:17 gourdeau Exp $";
06531
06532
06533 #ifdef use_namespace
06534 namespace ROBOOP {
06535 using namespace NEWMAT;
06536 #endif
06537
06538
06539 ReturnMatrix trans(const ColumnVector & a)
06541 {
06542 Matrix translation(4,4);
06543
06544 translation << fourbyfourident;
06545
06546 if (a.Nrows() == 3)
06547 {
06548 translation(1,4) = a(1);
06549 translation(2,4) = a(2);
06550 translation(3,4) = a(3);
06551 }
06552 else
06553 cerr << "trans: wrong size in input vector." << endl;
06554
06555 translation.Release(); return translation;
06556 }
06557
06558 ReturnMatrix rotx(const Real alpha)
06560 {
06561 Matrix rot(4,4);
06562 Real c, s;
06563
06564 rot << fourbyfourident;
06565
06566 c = cos(alpha);
06567 s = sin(alpha);
06568
06569 rot(2,2) = c;
06570 rot(3,3) = c;
06571 rot(2,3) = -s;
06572 rot(3,2) = s;
06573
06574 rot.Release(); return rot;
06575 }
06576
06577
06578 ReturnMatrix roty(const Real beta)
06580 {
06581 Matrix rot(4,4);
06582 Real c, s;
06583
06584 rot << fourbyfourident;
06585
06586 c = cos(beta);
06587 s = sin(beta);
06588
06589 rot(1,1) = c;
06590 rot(3,3) = c;
06591 rot(1,3) = s;
06592 rot(3,1) = -s;
06593
06594 rot.Release(); return rot;
06595 }
06596
06597
06598 ReturnMatrix rotz(const Real gamma)
06600 {
06601 Matrix rot(4,4);
06602 Real c, s;
06603
06604 rot << fourbyfourident;
06605
06606 c = cos(gamma);
06607 s = sin(gamma);
06608
06609 rot(1,1) = c;
06610 rot(2,2) = c;
06611 rot(1,2) = -s;
06612 rot(2,1) = s;
06613
06614 rot.Release(); return rot;
06615 }
06616
06617
06618
06619
06620 ReturnMatrix rotk(const Real theta, const ColumnVector & k)
06622 {
06623 Matrix rot(4,4);
06624 Real c, s, vers, kx, ky, kz;
06625
06626 rot << fourbyfourident;
06627
06628 vers = SumSquare(k.SubMatrix(1,3,1,1));
06629 if (vers != 0.0) {
06630 vers = sqrt(1/vers);
06631 kx = k(1)*vers;
06632 ky = k(2)*vers;
06633 kz = k(3)*vers;
06634 s = sin(theta);
06635 c = cos(theta);
06636 vers = 1-c;
06637
06638 rot(1,1) = kx*kx*vers+c;
06639 rot(1,2) = kx*ky*vers-kz*s;
06640 rot(1,3) = kx*kz*vers+ky*s;
06641 rot(2,1) = kx*ky*vers+kz*s;
06642 rot(2,2) = ky*ky*vers+c;
06643 rot(2,3) = ky*kz*vers-kx*s;
06644 rot(3,1) = kx*kz*vers-ky*s;
06645 rot(3,2) = ky*kz*vers+kx*s;
06646 rot(3,3) = kz*kz*vers+c;
06647 }
06648
06649 rot.Release(); return rot;
06650 }
06651
06652
06653 ReturnMatrix rpy(const ColumnVector & a)
06655 {
06656 Matrix rot(4,4);
06657 Real ca, sa, cb, sb, cc, sc;
06658
06659 rot << fourbyfourident;
06660
06661 ca = cos(a(1));
06662 sa = sin(a(1));
06663 cb = cos(a(2));
06664 sb = sin(a(2));
06665 cc = cos(a(3));
06666 sc = sin(a(3));
06667
06668 rot(1,1) = cb*cc;
06669 rot(1,2) = sa*sb*cc-ca*sc;
06670 rot(1,3) = ca*sb*cc+sa*sc;
06671 rot(2,1) = cb*sc;
06672 rot(2,2) = sa*sb*sc+ca*cc;
06673 rot(2,3) = ca*sb*sc-sa*cc;
06674 rot(3,1) = -sb;
06675 rot(3,2) = sa*cb;
06676 rot(3,3) = ca*cb;
06677
06678 rot.Release(); return rot;
06679 }
06680
06681
06682 ReturnMatrix eulzxz(const ColumnVector & a)
06684 {
06685 Matrix rot(4,4);
06686 Real c1, s1, ca, sa, c2, s2;
06687
06688 rot << fourbyfourident;
06689
06690 c1 = cos(a(1));
06691 s1 = sin(a(1));
06692 ca = cos(a(2));
06693 sa = sin(a(2));
06694 c2 = cos(a(3));
06695 s2 = sin(a(3));
06696
06697 rot(1,1) = c1*c2-s1*ca*s2;
06698 rot(1,2) = -c1*s2-s1*ca*c2;
06699 rot(1,3) = sa*s1;
06700 rot(2,1) = s1*c2+c1*ca*s2;
06701 rot(2,2) = -s1*s2+c1*ca*c2;
06702 rot(2,3) = -sa*c1;
06703 rot(3,1) = sa*s2;
06704 rot(3,2) = sa*c2;
06705 rot(3,3) = ca;
06706
06707 rot.Release(); return rot;
06708 }
06709
06710
06711 ReturnMatrix rotd(const Real theta, const ColumnVector & k1,
06712 const ColumnVector & k2)
06714 {
06715 Matrix rot;
06716
06717 rot = trans(k1)*rotk(theta,k2-k1)*trans(-k1);
06718
06719 rot.Release(); return rot;
06720 }
06721
06722
06723
06724 ReturnMatrix irotk(const Matrix & R)
06726 {
06727 ColumnVector k(4);
06728 Real a, b, c;
06729
06730 a = (R(3,2)-R(2,3));
06731 b = (R(1,3)-R(3,1));
06732 c = (R(2,1)-R(1,2));
06733 k(4) = atan2(sqrt(a*a + b*b + c*c),(R(1,1) + R(2,2) + R(3,3)-1));
06734 k(1) = (R(3,2)-R(2,3))/(2*sin(k(4)));
06735 k(2) = (R(1,3)-R(3,1))/(2*sin(k(4)));
06736 k(3) = (R(2,1)-R(1,2))/(2*sin(k(4)));
06737
06738 k.Release(); return k;
06739 }
06740
06741
06742 ReturnMatrix irpy(const Matrix & R)
06744 {
06745 ColumnVector k(3);
06746
06747 if (R(3,1)==1) {
06748 k(1) = atan2(-R(1,2),-R(1,3));
06749 k(2) = -M_PI/2;
06750 k(3) = 0.0;
06751 } else if (R(3,1)==-1) {
06752 k(1) = atan2(R(1,2),R(1,3));
06753 k(2) = M_PI/2;
06754 k(3) = 0.0;
06755 } else {
06756 k(1) = atan2(R(3,2), R(3,3));
06757 k(2) = atan2(-R(3,1), sqrt(R(1,1)*R(1,1) + R(2,1)*R(2,1)));
06758 k(3) = atan2(R(2,1), R(1,1));
06759 }
06760
06761 k.Release(); return k;
06762 }
06763
06764
06765 ReturnMatrix ieulzxz(const Matrix & R)
06767 {
06768 ColumnVector a(3);
06769
06770 if ((R(3,3)==1) || (R(3,3)==-1)) {
06771 a(1) = 0.0;
06772 a(2) = ((R(3,3) == 1) ? 0.0 : M_PI);
06773 a(3) = atan2(R(2,1),R(1,1));
06774 } else {
06775 a(1) = atan2(R(1,3), -R(2,3));
06776 a(2) = atan2(sqrt(R(1,3)*R(1,3) + R(2,3)*R(2,3)), R(3,3));
06777 a(3) = atan2(R(3,1), R(3,2));
06778 }
06779
06780 a.Release(); return a;
06781 }
06782
06783 #ifdef use_namespace
06784 }
06785 #endif
06786
06787
06788
06793
06794
06795
06796
06797 #define WANT_MATH
06798
06799
06800 #ifdef use_namespace
06801 namespace NEWMAT {
06802 #endif
06803
06804
06805 #ifdef DO_REPORT
06806 #define REPORT { static ExeCounter ExeCount(__LINE__,2); ++ExeCount; }
06807 #else
06808 #define REPORT {}
06809 #endif
06810
06811
06812
06813 #define MONITOR(what,store,storage) {}
06814
06815
06816
06817 void MatrixRowCol::Add(const MatrixRowCol& mrc)
06818 {
06819
06820 REPORT
06821 int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
06822 if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
06823 if (l<=0) return;
06824 Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
06825 while (l--) *elx++ += *el++;
06826 }
06827
06828 void MatrixRowCol::AddScaled(const MatrixRowCol& mrc, Real x)
06829 {
06830 REPORT
06831
06832 int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
06833 if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
06834 if (l<=0) return;
06835 Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
06836 while (l--) *elx++ += *el++ * x;
06837 }
06838
06839 void MatrixRowCol::Sub(const MatrixRowCol& mrc)
06840 {
06841 REPORT
06842
06843 int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
06844 if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
06845 if (l<=0) return;
06846 Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
06847 while (l--) *elx++ -= *el++;
06848 }
06849
06850 void MatrixRowCol::Inject(const MatrixRowCol& mrc)
06851
06852 {
06853 REPORT
06854 int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
06855 if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
06856 if (l<=0) return;
06857 Real* elx=data+(f-skip); Real* ely=mrc.data+(f-mrc.skip);
06858 while (l--) *elx++ = *ely++;
06859 }
06860
06861 Real DotProd(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
06862 {
06863 REPORT
06864 int f = mrc1.skip; int f2 = mrc2.skip;
06865 int l = f + mrc1.storage; int l2 = f2 + mrc2.storage;
06866 if (f < f2) f = f2; if (l > l2) l = l2; l -= f;
06867 if (l<=0) return 0.0;
06868
06869 Real* el1=mrc1.data+(f-mrc1.skip); Real* el2=mrc2.data+(f-mrc2.skip);
06870 Real sum = 0.0;
06871 while (l--) sum += *el1++ * *el2++;
06872 return sum;
06873 }
06874
06875 void MatrixRowCol::Add(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
06876 {
06877
06878 int f = skip; int l = skip + storage;
06879 int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
06880 if (f1<f) f1=f; if (l1>l) l1=l;
06881 int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
06882 if (f2<f) f2=f; if (l2>l) l2=l;
06883 Real* el = data + (f-skip);
06884 Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
06885 if (f1<f2)
06886 {
06887 int i = f1-f; while (i--) *el++ = 0.0;
06888 if (l1<=f2)
06889 {
06890 REPORT
06891 i = l1-f1; while (i--) *el++ = *el1++;
06892 i = f2-l1; while (i--) *el++ = 0.0;
06893 i = l2-f2; while (i--) *el++ = *el2++;
06894 i = l-l2; while (i--) *el++ = 0.0;
06895 }
06896 else
06897 {
06898 i = f2-f1; while (i--) *el++ = *el1++;
06899 if (l1<=l2)
06900 {
06901 REPORT
06902 i = l1-f2; while (i--) *el++ = *el1++ + *el2++;
06903 i = l2-l1; while (i--) *el++ = *el2++;
06904 i = l-l2; while (i--) *el++ = 0.0;
06905 }
06906 else
06907 {
06908 REPORT
06909 i = l2-f2; while (i--) *el++ = *el1++ + *el2++;
06910 i = l1-l2; while (i--) *el++ = *el1++;
06911 i = l-l1; while (i--) *el++ = 0.0;
06912 }
06913 }
06914 }
06915 else
06916 {
06917 int i = f2-f; while (i--) *el++ = 0.0;
06918 if (l2<=f1)
06919 {
06920 REPORT
06921 i = l2-f2; while (i--) *el++ = *el2++;
06922 i = f1-l2; while (i--) *el++ = 0.0;
06923 i = l1-f1; while (i--) *el++ = *el1++;
06924 i = l-l1; while (i--) *el++ = 0.0;
06925 }
06926 else
06927 {
06928 i = f1-f2; while (i--) *el++ = *el2++;
06929 if (l2<=l1)
06930 {
06931 REPORT
06932 i = l2-f1; while (i--) *el++ = *el1++ + *el2++;
06933 i = l1-l2; while (i--) *el++ = *el1++;
06934 i = l-l1; while (i--) *el++ = 0.0;
06935 }
06936 else
06937 {
06938 REPORT
06939 i = l1-f1; while (i--) *el++ = *el1++ + *el2++;
06940 i = l2-l1; while (i--) *el++ = *el2++;
06941 i = l-l2; while (i--) *el++ = 0.0;
06942 }
06943 }
06944 }
06945 }
06946
06947 void MatrixRowCol::Sub(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
06948 {
06949
06950 int f = skip; int l = skip + storage;
06951 int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
06952 if (f1<f) f1=f; if (l1>l) l1=l;
06953 int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
06954 if (f2<f) f2=f; if (l2>l) l2=l;
06955 Real* el = data + (f-skip);
06956 Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
06957 if (f1<f2)
06958 {
06959 int i = f1-f; while (i--) *el++ = 0.0;
06960 if (l1<=f2)
06961 {
06962 REPORT
06963 i = l1-f1; while (i--) *el++ = *el1++;
06964 i = f2-l1; while (i--) *el++ = 0.0;
06965 i = l2-f2; while (i--) *el++ = - *el2++;
06966 i = l-l2; while (i--) *el++ = 0.0;
06967 }
06968 else
06969 {
06970 i = f2-f1; while (i--) *el++ = *el1++;
06971 if (l1<=l2)
06972 {
06973 REPORT
06974 i = l1-f2; while (i--) *el++ = *el1++ - *el2++;
06975 i = l2-l1; while (i--) *el++ = - *el2++;
06976 i = l-l2; while (i--) *el++ = 0.0;
06977 }
06978 else
06979 {
06980 REPORT
06981 i = l2-f2; while (i--) *el++ = *el1++ - *el2++;
06982 i = l1-l2; while (i--) *el++ = *el1++;
06983 i = l-l1; while (i--) *el++ = 0.0;
06984 }
06985 }
06986 }
06987 else
06988 {
06989 int i = f2-f; while (i--) *el++ = 0.0;
06990 if (l2<=f1)
06991 {
06992 REPORT
06993 i = l2-f2; while (i--) *el++ = - *el2++;
06994 i = f1-l2; while (i--) *el++ = 0.0;
06995 i = l1-f1; while (i--) *el++ = *el1++;
06996 i = l-l1; while (i--) *el++ = 0.0;
06997 }
06998 else
06999 {
07000 i = f1-f2; while (i--) *el++ = - *el2++;
07001 if (l2<=l1)
07002 {
07003 REPORT
07004 i = l2-f1; while (i--) *el++ = *el1++ - *el2++;
07005 i = l1-l2; while (i--) *el++ = *el1++;
07006 i = l-l1; while (i--) *el++ = 0.0;
07007 }
07008 else
07009 {
07010 REPORT
07011 i = l1-f1; while (i--) *el++ = *el1++ - *el2++;
07012 i = l2-l1; while (i--) *el++ = - *el2++;
07013 i = l-l2; while (i--) *el++ = 0.0;
07014 }
07015 }
07016 }
07017 }
07018
07019
07020 void MatrixRowCol::Add(const MatrixRowCol& mrc1, Real x)
07021 {
07022
07023 REPORT
07024 if (!storage) return;
07025 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07026 if (f < skip) { f = skip; if (l < f) l = f; }
07027 if (l > lx) { l = lx; if (f > lx) f = lx; }
07028
07029 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07030
07031 int l1 = f-skip; while (l1--) *elx++ = x;
07032 l1 = l-f; while (l1--) *elx++ = *ely++ + x;
07033 lx -= l; while (lx--) *elx++ = x;
07034 }
07035
07036 void MatrixRowCol::NegAdd(const MatrixRowCol& mrc1, Real x)
07037 {
07038
07039 REPORT
07040 if (!storage) return;
07041 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07042 if (f < skip) { f = skip; if (l < f) l = f; }
07043 if (l > lx) { l = lx; if (f > lx) f = lx; }
07044
07045 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07046
07047 int l1 = f-skip; while (l1--) *elx++ = x;
07048 l1 = l-f; while (l1--) *elx++ = x - *ely++;
07049 lx -= l; while (lx--) *elx++ = x;
07050 }
07051
07052 void MatrixRowCol::RevSub(const MatrixRowCol& mrc1)
07053 {
07054
07055 REPORT
07056 if (!storage) return;
07057 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07058 if (f < skip) { f = skip; if (l < f) l = f; }
07059 if (l > lx) { l = lx; if (f > lx) f = lx; }
07060
07061 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07062
07063 int l1 = f-skip; while (l1--) { *elx = - *elx; elx++; }
07064 l1 = l-f; while (l1--) { *elx = *ely++ - *elx; elx++; }
07065 lx -= l; while (lx--) { *elx = - *elx; elx++; }
07066 }
07067
07068 void MatrixRowCol::ConCat(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
07069 {
07070
07071 REPORT
07072 int f1 = mrc1.skip; int l1 = f1 + mrc1.storage; int lx = skip + storage;
07073 if (f1 < skip) { f1 = skip; if (l1 < f1) l1 = f1; }
07074 if (l1 > lx) { l1 = lx; if (f1 > lx) f1 = lx; }
07075
07076 Real* elx = data;
07077
07078 int i = f1-skip; while (i--) *elx++ =0.0;
07079 i = l1-f1;
07080 if (i)
07081 { Real* ely = mrc1.data+(f1-mrc1.skip); while (i--) *elx++ = *ely++; }
07082
07083 int f2 = mrc2.skip; int l2 = f2 + mrc2.storage; i = mrc1.length;
07084 int skipx = l1 - i; lx -= i;
07085 if (f2 < skipx) { f2 = skipx; if (l2 < f2) l2 = f2; }
07086 if (l2 > lx) { l2 = lx; if (f2 > lx) f2 = lx; }
07087
07088 i = f2-skipx; while (i--) *elx++ = 0.0;
07089 i = l2-f2;
07090 if (i)
07091 { Real* ely = mrc2.data+(f2-mrc2.skip); while (i--) *elx++ = *ely++; }
07092 lx -= l2; while (lx--) *elx++ = 0.0;
07093 }
07094
07095 void MatrixRowCol::Multiply(const MatrixRowCol& mrc1)
07096
07097 {
07098 REPORT
07099 if (!storage) return;
07100 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07101 if (f < skip) { f = skip; if (l < f) l = f; }
07102 if (l > lx) { l = lx; if (f > lx) f = lx; }
07103
07104 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07105
07106 int l1 = f-skip; while (l1--) *elx++ = 0;
07107 l1 = l-f; while (l1--) *elx++ *= *ely++;
07108 lx -= l; while (lx--) *elx++ = 0;
07109 }
07110
07111 void MatrixRowCol::Multiply(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
07112
07113 {
07114 int f = skip; int l = skip + storage;
07115 int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
07116 if (f1<f) f1=f; if (l1>l) l1=l;
07117 int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
07118 if (f2<f) f2=f; if (l2>l) l2=l;
07119 Real* el = data + (f-skip); int i;
07120 if (f1<f2) f1 = f2; if (l1>l2) l1 = l2;
07121 if (l1<=f1) { REPORT i = l-f; while (i--) *el++ = 0.0; }
07122 else
07123 {
07124 REPORT
07125 Real* el1 = mrc1.data+(f1-mrc1.skip);
07126 Real* el2 = mrc2.data+(f1-mrc2.skip);
07127 i = f1-f ; while (i--) *el++ = 0.0;
07128 i = l1-f1; while (i--) *el++ = *el1++ * *el2++;
07129 i = l-l1; while (i--) *el++ = 0.0;
07130 }
07131 }
07132
07133 void MatrixRowCol::KP(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
07134
07135 {
07136 int f = skip; int s = storage; Real* el = data; int i;
07137
07138 i = mrc1.skip * mrc2.length;
07139 if (i > f)
07140 {
07141 i -= f; f = 0; if (i > s) { i = s; s = 0; } else s -= i;
07142 while (i--) *el++ = 0.0;
07143 if (s == 0) return;
07144 }
07145 else f -= i;
07146
07147 i = mrc1.storage; Real* el1 = mrc1.data;
07148 int mrc2_skip = mrc2.skip; int mrc2_storage = mrc2.storage;
07149 int mrc2_length = mrc2.length;
07150 int mrc2_remain = mrc2_length - mrc2_skip - mrc2_storage;
07151 while (i--)
07152 {
07153 int j; Real* el2 = mrc2.data; Real vel1 = *el1;
07154 if (f == 0 && mrc2_length <= s)
07155 {
07156 j = mrc2_skip; s -= j; while (j--) *el++ = 0.0;
07157 j = mrc2_storage; s -= j; while (j--) *el++ = vel1 * *el2++;
07158 j = mrc2_remain; s -= j; while (j--) *el++ = 0.0;
07159 }
07160 else if (f >= mrc2_length) f -= mrc2_length;
07161 else
07162 {
07163 j = mrc2_skip;
07164 if (j > f)
07165 {
07166 j -= f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
07167 while (j--) *el++ = 0.0;
07168 }
07169 else f -= j;
07170
07171 j = mrc2_storage;
07172 if (j > f)
07173 {
07174 j -= f; el2 += f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
07175 while (j--) *el++ = vel1 * *el2++;
07176 }
07177 else f -= j;
07178
07179 j = mrc2_remain;
07180 if (j > f)
07181 {
07182 j -= f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
07183 while (j--) *el++ = 0.0;
07184 }
07185 else f -= j;
07186 }
07187 if (s == 0) return;
07188 ++el1;
07189 }
07190
07191 i = (mrc1.length - mrc1.skip - mrc1.storage) * mrc2.length;
07192 if (i > f)
07193 {
07194 i -= f; if (i > s) i = s;
07195 while (i--) *el++ = 0.0;
07196 }
07197 }
07198
07199
07200 void MatrixRowCol::Copy(const MatrixRowCol& mrc1)
07201 {
07202
07203 REPORT
07204 if (!storage) return;
07205 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07206 if (f < skip) { f = skip; if (l < f) l = f; }
07207 if (l > lx) { l = lx; if (f > lx) f = lx; }
07208
07209 Real* elx = data; Real* ely = 0;
07210
07211 if (l-f) ely = mrc1.data+(f-mrc1.skip);
07212
07213 int l1 = f-skip; while (l1--) *elx++ = 0.0;
07214 l1 = l-f; while (l1--) *elx++ = *ely++;
07215 lx -= l; while (lx--) *elx++ = 0.0;
07216 }
07217
07218 void MatrixRowCol::CopyCheck(const MatrixRowCol& mrc1)
07219
07220 {
07221 REPORT
07222 if (!storage) return;
07223 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07224 if (f < skip || l > lx) Throw(ProgramException("Illegal Conversion"));
07225
07226 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07227
07228 int l1 = f-skip; while (l1--) *elx++ = 0.0;
07229 l1 = l-f; while (l1--) *elx++ = *ely++;
07230 lx -= l; while (lx--) *elx++ = 0.0;
07231 }
07232
07233 void MatrixRowCol::Check(const MatrixRowCol& mrc1)
07234
07235 {
07236 REPORT
07237 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07238 if (f < skip || l > lx) Throw(ProgramException("Illegal Conversion"));
07239 }
07240
07241 void MatrixRowCol::Check()
07242
07243
07244
07245 {
07246 REPORT
07247 if (skip!=0 || storage!=length)
07248 Throw(ProgramException("Illegal Conversion"));
07249 }
07250
07251 void MatrixRowCol::Negate(const MatrixRowCol& mrc1)
07252 {
07253
07254 REPORT
07255 if (!storage) return;
07256 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07257 if (f < skip) { f = skip; if (l < f) l = f; }
07258 if (l > lx) { l = lx; if (f > lx) f = lx; }
07259
07260 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07261
07262 int l1 = f-skip; while (l1--) *elx++ = 0.0;
07263 l1 = l-f; while (l1--) *elx++ = - *ely++;
07264 lx -= l; while (lx--) *elx++ = 0.0;
07265 }
07266
07267 void MatrixRowCol::Multiply(const MatrixRowCol& mrc1, Real s)
07268 {
07269
07270 REPORT
07271 if (!storage) return;
07272 int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
07273 if (f < skip) { f = skip; if (l < f) l = f; }
07274 if (l > lx) { l = lx; if (f > lx) f = lx; }
07275
07276 Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
07277
07278 int l1 = f-skip; while (l1--) *elx++ = 0.0;
07279 l1 = l-f; while (l1--) *elx++ = *ely++ * s;
07280 lx -= l; while (lx--) *elx++ = 0.0;
07281 }
07282
07283 void DiagonalMatrix::Solver(MatrixColX& mrc, const MatrixColX& mrc1)
07284 {
07285
07286 REPORT
07287 int f = mrc1.skip; int f0 = mrc.skip;
07288 int l = f + mrc1.storage; int lx = f0 + mrc.storage;
07289 if (f < f0) { f = f0; if (l < f) l = f; }
07290 if (l > lx) { l = lx; if (f > lx) f = lx; }
07291
07292 Real* elx = mrc.data; Real* eld = store+f;
07293
07294 int l1 = f-f0; while (l1--) *elx++ = 0.0;
07295 l1 = l-f; while (l1--) *elx++ /= *eld++;
07296 lx -= l; while (lx--) *elx++ = 0.0;
07297
07298 }
07299
07300 void IdentityMatrix::Solver(MatrixColX& mrc, const MatrixColX& mrc1)
07301 {
07302
07303 REPORT
07304 int f = mrc1.skip; int f0 = mrc.skip;
07305 int l = f + mrc1.storage; int lx = f0 + mrc.storage;
07306 if (f < f0) { f = f0; if (l < f) l = f; }
07307 if (l > lx) { l = lx; if (f > lx) f = lx; }
07308
07309 Real* elx = mrc.data; Real eldv = *store;
07310
07311 int l1 = f-f0; while (l1--) *elx++ = 0.0;
07312 l1 = l-f; while (l1--) *elx++ /= eldv;
07313 lx -= l; while (lx--) *elx++ = 0.0;
07314
07315 }
07316
07317 void MatrixRowCol::Copy(const double*& r)
07318 {
07319
07320 REPORT
07321 Real* elx = data; const double* ely = r+skip; r += length;
07322 int l = storage; while (l--) *elx++ = (Real)*ely++;
07323 }
07324
07325 void MatrixRowCol::Copy(const float*& r)
07326 {
07327
07328 REPORT
07329 Real* elx = data; const float* ely = r+skip; r += length;
07330 int l = storage; while (l--) *elx++ = (Real)*ely++;
07331 }
07332
07333 void MatrixRowCol::Copy(const int*& r)
07334 {
07335
07336 REPORT
07337 Real* elx = data; const int* ely = r+skip; r += length;
07338 int l = storage; while (l--) *elx++ = (Real)*ely++;
07339 }
07340
07341 void MatrixRowCol::Copy(Real r)
07342 {
07343
07344 REPORT Real* elx = data; int l = storage; while (l--) *elx++ = r;
07345 }
07346
07347 void MatrixRowCol::Zero()
07348 {
07349
07350 REPORT Real* elx = data; int l = storage; while (l--) *elx++ = 0;
07351 }
07352
07353 void MatrixRowCol::Multiply(Real r)
07354 {
07355
07356 REPORT Real* elx = data; int l = storage; while (l--) *elx++ *= r;
07357 }
07358
07359 void MatrixRowCol::Add(Real r)
07360 {
07361
07362 REPORT
07363 Real* elx = data; int l = storage; while (l--) *elx++ += r;
07364 }
07365
07366 Real MatrixRowCol::SumAbsoluteValue()
07367 {
07368 REPORT
07369 Real sum = 0.0; Real* elx = data; int l = storage;
07370 while (l--) sum += fabs(*elx++);
07371 return sum;
07372 }
07373
07374
07375
07376
07377 Real MatrixRowCol::MaximumAbsoluteValue1(Real r, int& i)
07378 {
07379 REPORT
07380 Real* elx = data; int l = storage; int li = -1;
07381 while (l--) { Real f = fabs(*elx++); if (r <= f) { r = f; li = l; } }
07382 i = (li >= 0) ? storage - li + skip : 0;
07383 return r;
07384 }
07385
07386
07387 Real MatrixRowCol::MinimumAbsoluteValue1(Real r, int& i)
07388 {
07389 REPORT
07390 Real* elx = data; int l = storage; int li = -1;
07391 while (l--) { Real f = fabs(*elx++); if (r >= f) { r = f; li = l; } }
07392 i = (li >= 0) ? storage - li + skip : 0;
07393 return r;
07394 }
07395
07396
07397 Real MatrixRowCol::Maximum1(Real r, int& i)
07398 {
07399 REPORT
07400 Real* elx = data; int l = storage; int li = -1;
07401 while (l--) { Real f = *elx++; if (r <= f) { r = f; li = l; } }
07402 i = (li >= 0) ? storage - li + skip : 0;
07403 return r;
07404 }
07405
07406
07407 Real MatrixRowCol::Minimum1(Real r, int& i)
07408 {
07409 REPORT
07410 Real* elx = data; int l = storage; int li = -1;
07411 while (l--) { Real f = *elx++; if (r >= f) { r = f; li = l; } }
07412 i = (li >= 0) ? storage - li + skip : 0;
07413 return r;
07414 }
07415
07416 Real MatrixRowCol::Sum()
07417 {
07418 REPORT
07419 Real sum = 0.0; Real* elx = data; int l = storage;
07420 while (l--) sum += *elx++;
07421 return sum;
07422 }
07423
07424 void MatrixRowCol::SubRowCol(MatrixRowCol& mrc, int skip1, int l1) const
07425 {
07426 mrc.length = l1; int d = skip - skip1;
07427 if (d<0) { mrc.skip = 0; mrc.data = data - d; }
07428 else { mrc.skip = d; mrc.data = data; }
07429 d = skip + storage - skip1;
07430 d = ((l1 < d) ? l1 : d) - mrc.skip; mrc.storage = (d < 0) ? 0 : d;
07431 mrc.cw = 0;
07432 }
07433
07434 #ifdef use_namespace
07435 }
07436 #endif
07437
07438
07442
07445
07446
07447
07448
07449 #define WANT_MATH
07450
07451 #ifdef use_namespace
07452 namespace NEWMAT {
07453 #endif
07454
07455 #ifdef DO_REPORT
07456 #define REPORT { static ExeCounter ExeCount(__LINE__,15); ++ExeCount; }
07457 #else
07458 #define REPORT {}
07459 #endif
07460
07461 void SVD(const Matrix& A, DiagonalMatrix& Q, Matrix& U, Matrix& V,
07462 bool withU, bool withV)
07463
07464 {
07465 REPORT
07466 Tracer trace("SVD");
07467 Real eps = FloatingPointPrecision::Epsilon();
07468 Real tol = FloatingPointPrecision::Minimum()/eps;
07469
07470 int m = A.Nrows(); int n = A.Ncols();
07471 if (m<n)
07472 Throw(ProgramException("Want no. Rows >= no. Cols", A));
07473 if (withV && &U == &V)
07474 Throw(ProgramException("Need different matrices for U and V", U, V));
07475 U = A; Real g = 0.0; Real f,h; Real x = 0.0; int i;
07476 RowVector E(n); RectMatrixRow EI(E,0); Q.ReSize(n);
07477 RectMatrixCol UCI(U,0); RectMatrixRow URI(U,0,1,n-1);
07478
07479 if (n) for (i=0;;)
07480 {
07481 EI.First() = g; Real ei = g; EI.Right(); Real s = UCI.SumSquare();
07482 if (s<tol) { REPORT Q.element(i) = 0.0; }
07483 else
07484 {
07485 REPORT
07486 f = UCI.First(); g = -sign(sqrt(s), f); h = f*g-s; UCI.First() = f-g;
07487 Q.element(i) = g; RectMatrixCol UCJ = UCI; int j=n-i;
07488 while (--j) { UCJ.Right(); UCJ.AddScaled(UCI, (UCI*UCJ)/h); }
07489 }
07490
07491 s = URI.SumSquare();
07492 if (s<tol) { REPORT g = 0.0; }
07493 else
07494 {
07495 REPORT
07496 f = URI.First(); g = -sign(sqrt(s), f); URI.First() = f-g;
07497 EI.Divide(URI,f*g-s); RectMatrixRow URJ = URI; int j=m-i;
07498 while (--j) { URJ.Down(); URJ.AddScaled(EI, URI*URJ); }
07499 }
07500
07501 Real y = fabs(Q.element(i)) + fabs(ei); if (x<y) { REPORT x = y; }
07502 if (++i == n) { REPORT break; }
07503 UCI.DownDiag(); URI.DownDiag();
07504 }
07505
07506 if (withV)
07507 {
07508 REPORT
07509 V.ReSize(n,n); V = 0.0; RectMatrixCol VCI(V,n-1,n-1,1);
07510 if (n) { VCI.First() = 1.0; g=E.element(n-1); if (n!=1) URI.UpDiag(); }
07511 for (i=n-2; i>=0; i--)
07512 {
07513 VCI.Left();
07514 if (g!=0.0)
07515 {
07516 VCI.Divide(URI, URI.First()*g); int j = n-i;
07517 RectMatrixCol VCJ = VCI;
07518 while (--j) { VCJ.Right(); VCJ.AddScaled( VCI, (URI*VCJ) ); }
07519 }
07520 VCI.Zero(); VCI.Up(); VCI.First() = 1.0; g=E.element(i);
07521 if (i==0) break;
07522 URI.UpDiag();
07523 }
07524 }
07525
07526 if (withU)
07527 {
07528 REPORT
07529 for (i=n-1; i>=0; i--)
07530 {
07531 g = Q.element(i); URI.Reset(U,i,i+1,n-i-1); URI.Zero();
07532 if (g!=0.0)
07533 {
07534 h=UCI.First()*g; int j=n-i; RectMatrixCol UCJ = UCI;
07535 while (--j)
07536 {
07537 UCJ.Right(); UCI.Down(); UCJ.Down(); Real s = UCI*UCJ;
07538 UCI.Up(); UCJ.Up(); UCJ.AddScaled(UCI,s/h);
07539 }
07540 UCI.Divide(g);
07541 }
07542 else UCI.Zero();
07543 UCI.First() += 1.0;
07544 if (i==0) break;
07545 UCI.UpDiag();
07546 }
07547 }
07548
07549 eps *= x;
07550 for (int k=n-1; k>=0; k--)
07551 {
07552 Real z = -FloatingPointPrecision::Maximum();
07553 Real y; int limit = 50; int l = 0;
07554 while (limit--)
07555 {
07556 Real c, s; int i; int l1=k; bool tfc=false;
07557 for (l=k; l>=0; l--)
07558 {
07559
07560 if (fabs(E.element(l))<=eps) { REPORT tfc=true; break; }
07561 if (fabs(Q.element(l-1))<=eps) { REPORT l1=l; break; }
07562 REPORT
07563 }
07564 if (!tfc)
07565 {
07566 REPORT
07567 l=l1; l1=l-1; s = -1.0; c = 0.0;
07568 for (i=l; i<=k; i++)
07569 {
07570 f = - s * E.element(i); E.element(i) *= c;
07571
07572 if (fabs(f)<=eps) { REPORT break; }
07573 g = Q.element(i); h = pythag(g,f,c,s); Q.element(i) = h;
07574 if (withU)
07575 {
07576 REPORT
07577 RectMatrixCol UCI(U,i); RectMatrixCol UCJ(U,l1);
07578 ComplexScale(UCJ, UCI, c, s);
07579 }
07580 }
07581 }
07582
07583 z = Q.element(k); if (l==k) { REPORT break; }
07584
07585 x = Q.element(l); y = Q.element(k-1);
07586 g = E.element(k-1); h = E.element(k);
07587 f = ((y-z)*(y+z) + (g-h)*(g+h)) / (2*h*y);
07588 if (f>1) { REPORT g = f * sqrt(1 + square(1/f)); }
07589 else if (f<-1) { REPORT g = -f * sqrt(1 + square(1/f)); }
07590 else { REPORT g = sqrt(f*f + 1); }
07591 { REPORT f = ((x-z)*(x+z) + h*(y / ((f<0.0) ? f-g : f+g)-h)) / x; }
07592
07593 c = 1.0; s = 1.0;
07594 for (i=l+1; i<=k; i++)
07595 {
07596 g = E.element(i); y = Q.element(i); h = s*g; g *= c;
07597 z = pythag(f,h,c,s); E.element(i-1) = z;
07598 f = x*c + g*s; g = -x*s + g*c; h = y*s; y *= c;
07599 if (withV)
07600 {
07601 REPORT
07602 RectMatrixCol VCI(V,i); RectMatrixCol VCJ(V,i-1);
07603 ComplexScale(VCI, VCJ, c, s);
07604 }
07605 z = pythag(f,h,c,s); Q.element(i-1) = z;
07606 f = c*g + s*y; x = -s*g + c*y;
07607 if (withU)
07608 {
07609 REPORT
07610 RectMatrixCol UCI(U,i); RectMatrixCol UCJ(U,i-1);
07611 ComplexScale(UCI, UCJ, c, s);
07612 }
07613 }
07614 E.element(l) = 0.0; E.element(k) = f; Q.element(k) = x;
07615 }
07616 if (l!=k) { Throw(ConvergenceException(A)); }
07617
07618 if (z < 0.0)
07619 {
07620 REPORT
07621 Q.element(k) = -z;
07622 if (withV) { RectMatrixCol VCI(V,k); VCI.Negate(); }
07623 }
07624 }
07625 if (withU & withV) SortSV(Q, U, V);
07626 else if (withU) SortSV(Q, U);
07627 else if (withV) SortSV(Q, V);
07628 else sort_descending(Q);
07629 }
07630
07631 void SVD(const Matrix& A, DiagonalMatrix& D)
07632 { REPORT Matrix U; SVD(A, D, U, U, false, false); }
07633
07634
07635
07636 #ifdef use_namespace
07637 }
07638 #endif
07639
07643
07644
07645
07646 #define WANT_STREAM // include.h will get stream fns
07647
07648
07649 #ifdef use_namespace
07650 namespace NEWMAT {
07651 #endif
07652
07653 unsigned long OverflowException::Select;
07654 unsigned long SingularException::Select;
07655 unsigned long NPDException::Select;
07656 unsigned long ConvergenceException::Select;
07657 unsigned long ProgramException::Select;
07658 unsigned long IndexException::Select;
07659 unsigned long VectorException::Select;
07660 unsigned long NotSquareException::Select;
07661 unsigned long SubMatrixDimensionException::Select;
07662 unsigned long IncompatibleDimensionsException::Select;
07663 unsigned long NotDefinedException::Select;
07664 unsigned long CannotBuildException::Select;
07665 unsigned long InternalException::Select;
07666
07667
07668
07669 static void MatrixDetails(const GeneralMatrix& A)
07670
07671 {
07672 MatrixBandWidth bw = A.bandwidth();
07673 int ubw = bw.upper_val; int lbw = bw.lower_val;
07674 BaseException::AddMessage("MatrixType = ");
07675 BaseException::AddMessage(A.Type().Value());
07676 BaseException::AddMessage(" # Rows = "); BaseException::AddInt(A.Nrows());
07677 BaseException::AddMessage("; # Cols = "); BaseException::AddInt(A.Ncols());
07678 if (lbw >=0)
07679 {
07680 BaseException::AddMessage("; lower BW = ");
07681 BaseException::AddInt(lbw);
07682 }
07683 if (ubw >=0)
07684 {
07685 BaseException::AddMessage("; upper BW = ");
07686 BaseException::AddInt(ubw);
07687 }
07688 BaseException::AddMessage("\n");
07689 }
07690
07691 NPDException::NPDException(const GeneralMatrix& A)
07692 : Runtime_error()
07693 {
07694 Select = BaseException::Select;
07695 AddMessage("detected by Newmat: matrix not positive definite\n\n");
07696 MatrixDetails(A);
07697
07698 }
07699
07700 SingularException::SingularException(const GeneralMatrix& A)
07701 : Runtime_error()
07702 {
07703 Select = BaseException::Select;
07704 AddMessage("detected by Newmat: matrix is singular\n\n");
07705 MatrixDetails(A);
07706
07707 }
07708
07709 ConvergenceException::ConvergenceException(const GeneralMatrix& A)
07710 : Runtime_error()
07711 {
07712 Select = BaseException::Select;
07713 AddMessage("detected by Newmat: process fails to converge\n\n");
07714 MatrixDetails(A);
07715
07716 }
07717
07718 ConvergenceException::ConvergenceException(const char* c) : Runtime_error()
07719 {
07720 Select = BaseException::Select;
07721 AddMessage("detected by Newmat: ");
07722 AddMessage(c); AddMessage("\n\n");
07723
07724 }
07725
07726 OverflowException::OverflowException(const char* c) : Runtime_error()
07727 {
07728 Select = BaseException::Select;
07729 AddMessage("detected by Newmat: ");
07730 AddMessage(c); AddMessage("\n\n");
07731
07732 }
07733
07734 ProgramException::ProgramException(const char* c) : Logic_error()
07735 {
07736 Select = BaseException::Select;
07737 AddMessage("detected by Newmat: ");
07738 AddMessage(c); AddMessage("\n\n");
07739
07740 }
07741
07742 ProgramException::ProgramException(const char* c, const GeneralMatrix& A)
07743 : Logic_error()
07744 {
07745 Select = BaseException::Select;
07746 AddMessage("detected by Newmat: ");
07747 AddMessage(c); AddMessage("\n\n");
07748 MatrixDetails(A);
07749
07750 }
07751
07752 ProgramException::ProgramException(const char* c, const GeneralMatrix& A,
07753 const GeneralMatrix& B) : Logic_error()
07754 {
07755 Select = BaseException::Select;
07756 AddMessage("detected by Newmat: ");
07757 AddMessage(c); AddMessage("\n\n");
07758 MatrixDetails(A); MatrixDetails(B);
07759
07760 }
07761
07762 ProgramException::ProgramException(const char* c, MatrixType a, MatrixType b)
07763 : Logic_error()
07764 {
07765 Select = BaseException::Select;
07766 AddMessage("detected by Newmat: ");
07767 AddMessage(c); AddMessage("\nMatrixTypes = ");
07768 AddMessage(a.Value()); AddMessage("; ");
07769 AddMessage(b.Value()); AddMessage("\n\n");
07770
07771 }
07772
07773 VectorException::VectorException() : Logic_error()
07774 {
07775 Select = BaseException::Select;
07776 AddMessage("detected by Newmat: cannot convert matrix to vector\n\n");
07777
07778 }
07779
07780 VectorException::VectorException(const GeneralMatrix& A)
07781 : Logic_error()
07782 {
07783 Select = BaseException::Select;
07784 AddMessage("detected by Newmat: cannot convert matrix to vector\n\n");
07785 MatrixDetails(A);
07786
07787 }
07788
07789 NotSquareException::NotSquareException(const GeneralMatrix& A)
07790 : Logic_error()
07791 {
07792 Select = BaseException::Select;
07793 AddMessage("detected by Newmat: matrix is not square\n\n");
07794 MatrixDetails(A);
07795
07796 }
07797
07798 NotSquareException::NotSquareException()
07799 : Logic_error()
07800 {
07801 Select = BaseException::Select;
07802 AddMessage("detected by Newmat: matrix is not square\n\n");
07803
07804 }
07805
07806 SubMatrixDimensionException::SubMatrixDimensionException()
07807 : Logic_error()
07808 {
07809 Select = BaseException::Select;
07810 AddMessage("detected by Newmat: incompatible submatrix dimension\n\n");
07811
07812 }
07813
07814 IncompatibleDimensionsException::IncompatibleDimensionsException()
07815 : Logic_error()
07816 {
07817 Select = BaseException::Select;
07818 AddMessage("detected by Newmat: incompatible dimensions\n\n");
07819
07820 }
07821
07822 IncompatibleDimensionsException::IncompatibleDimensionsException
07823 (const GeneralMatrix& A, const GeneralMatrix& B)
07824 : Logic_error()
07825 {
07826 Select = BaseException::Select;
07827 AddMessage("detected by Newmat: incompatible dimensions\n\n");
07828 MatrixDetails(A); MatrixDetails(B);
07829
07830 }
07831
07832 IncompatibleDimensionsException::IncompatibleDimensionsException
07833 (const GeneralMatrix& A)
07834 : Logic_error()
07835 {
07836 Select = BaseException::Select;
07837 AddMessage("detected by Newmat: incompatible dimensions\n\n");
07838 MatrixDetails(A);
07839
07840 }
07841
07842 NotDefinedException::NotDefinedException(const char* op, const char* matrix)
07843 : Logic_error()
07844 {
07845 Select = BaseException::Select;
07846 AddMessage("detected by Newmat: ");
07847 AddMessage(op);
07848 AddMessage(" not defined for ");
07849 AddMessage(matrix);
07850 AddMessage("\n\n");
07851
07852 }
07853
07854 CannotBuildException::CannotBuildException(const char* matrix)
07855 : Logic_error()
07856 {
07857 Select = BaseException::Select;
07858 AddMessage("detected by Newmat: cannot build matrix type ");
07859 AddMessage(matrix); AddMessage("\n\n");
07860
07861 }
07862
07863 IndexException::IndexException(int i, const GeneralMatrix& A)
07864 : Logic_error()
07865 {
07866 Select = BaseException::Select;
07867 AddMessage("detected by Newmat: index error: requested index = ");
07868 AddInt(i); AddMessage("\n\n");
07869 MatrixDetails(A);
07870
07871 }
07872
07873 IndexException::IndexException(int i, int j, const GeneralMatrix& A)
07874 : Logic_error()
07875 {
07876 Select = BaseException::Select;
07877 AddMessage("detected by Newmat: index error: requested indices = ");
07878 AddInt(i); AddMessage(", "); AddInt(j);
07879 AddMessage("\n\n");
07880 MatrixDetails(A);
07881
07882 }
07883
07884
07885 IndexException::IndexException(int i, const GeneralMatrix& A, bool)
07886 : Logic_error()
07887 {
07888 Select = BaseException::Select;
07889 AddMessage("detected by Newmat: element error: requested index (wrt 0) = ");
07890 AddInt(i);
07891 AddMessage("\n\n");
07892 MatrixDetails(A);
07893
07894 }
07895
07896 IndexException::IndexException(int i, int j, const GeneralMatrix& A, bool)
07897 : Logic_error()
07898 {
07899 Select = BaseException::Select;
07900 AddMessage(
07901 "detected by Newmat: element error: requested indices (wrt 0) = ");
07902 AddInt(i); AddMessage(", "); AddInt(j);
07903 AddMessage("\n\n");
07904 MatrixDetails(A);
07905
07906 }
07907
07908 InternalException::InternalException(const char* c) : Logic_error()
07909 {
07910 Select = BaseException::Select;
07911 AddMessage("internal error detected by Newmat: please inform author\n");
07912 AddMessage(c); AddMessage("\n\n");
07913
07914 }
07915
07916
07917
07918
07919
07920
07921 #ifdef DO_REPORT
07922
07923 int ExeCounter::nreports;
07924
07925 ExeCounter::ExeCounter(int xl, int xf) : line(xl), fileid(xf), nexe(0) {}
07926
07927 ExeCounter::~ExeCounter()
07928 {
07929 nreports++;
07930 cout << "REPORT " << setw(6) << nreports << " "
07931 << setw(6) << fileid << " " << setw(6) << line
07932 << " " << setw(6) << nexe << "\n";
07933 }
07934
07935 #endif
07936
07937
07938
07939 void MatrixErrorNoSpace(const void* v) { if (!v) Throw(Bad_alloc()); }
07940
07941
07942
07943
07944
07945
07946
07947
07948 void CroutMatrix::GetRow(MatrixRowCol&)
07949 { Throw(NotDefinedException("GetRow","Crout")); }
07950 void CroutMatrix::GetCol(MatrixRowCol&)
07951 { Throw(NotDefinedException("GetCol","Crout")); }
07952 void BandLUMatrix::GetRow(MatrixRowCol&)
07953 { Throw(NotDefinedException("GetRow","BandLUMatrix")); }
07954 void BandLUMatrix::GetCol(MatrixRowCol&)
07955 { Throw(NotDefinedException("GetCol","BandLUMatrix")); }
07956 void BaseMatrix::IEQND() const
07957 { Throw(NotDefinedException("inequalities", "matrices")); }
07958
07959
07960 #ifdef use_namespace
07961 }
07962 #endif
07963
07966
07975
07976
07977
07978
07979 #define WANT_STREAM // include.h will get stream fns
07980 #define WANT_STRING
07981
07982
07983 #ifdef use_namespace
07984 namespace RBD_COMMON {
07985 #endif
07986
07987
07988
07989
07990
07991
07992 #ifdef SimulateExceptions
07993
07994 void Throw()
07995 {
07996 for (Janitor* jan = JumpBase::jl->janitor; jan; jan = jan->NextJanitor)
07997 jan->CleanUp();
07998 JumpItem* jx = JumpBase::jl->ji;
07999 if ( !jx ) { Terminate(); }
08000 JumpBase::jl = jx;
08001
08002 Tracer::last = JumpBase::jl->trace;
08003 longjmp(JumpBase::jl->env, 1);
08004 }
08005
08006 #endif // end of simulate exceptions
08007
08008
08009 unsigned long BaseException::Select;
08010 char* BaseException::what_error;
08011 int BaseException::SoFar;
08012 int BaseException::LastOne;
08013
08014 BaseException::BaseException(const char* a_what)
08015 {
08016 Select++; SoFar = 0;
08017 if (!what_error)
08018 {
08019 LastOne = 511;
08020 what_error = new char[512];
08021 if (!what_error)
08022 {
08023 LastOne = 0;
08024 what_error = (char *)"No heap space for exception message\n";
08025 }
08026 }
08027 AddMessage("\n\nAn exception has been thrown\n");
08028 AddMessage(a_what);
08029
08030 }
08031
08032 void BaseException::AddMessage(const char* a_what)
08033 {
08034 if (a_what)
08035 {
08036 int l = (int) strlen(a_what); int r = LastOne - SoFar;
08037 if (l < r) { strcpy(what_error+SoFar, a_what); SoFar += l; }
08038 else if (r > 0)
08039 {
08040 strncpy(what_error+SoFar, a_what, r);
08041 what_error[LastOne] = 0;
08042 SoFar = LastOne;
08043 }
08044 }
08045 }
08046
08047 void BaseException::AddInt(int value)
08048 {
08049 bool negative;
08050 if (value == 0) { AddMessage("0"); return; }
08051 else if (value < 0) { value = -value; negative = true; }
08052 else negative = false;
08053 int n = 0; int v = value;
08054 while (v > 0) { v /= 10; n++; }
08055 if (negative) n++;
08056 if (LastOne-SoFar < n) { AddMessage("***"); return; }
08057
08058 SoFar += n; n = SoFar; what_error[n] = 0;
08059 while (value > 0)
08060 {
08061 int nv = value / 10; int rm = value - nv * 10; value = nv;
08062 what_error[--n] = (char)(rm + '0');
08063 }
08064 if (negative) what_error[--n] = '-';
08065 return;
08066 }
08067
08068 void Tracer::PrintTrace()
08069 {
08070 cout << "\n";
08071 for (Tracer* et = last; et; et=et->previous)
08072 cout << " * " << et->entry << "\n";
08073 }
08074
08075 void Tracer::AddTrace()
08076 {
08077 if (last)
08078 {
08079 BaseException::AddMessage("Trace: ");
08080 BaseException::AddMessage(last->entry);
08081 for (Tracer* et = last->previous; et; et=et->previous)
08082 {
08083 if(et)
08084 {
08085 BaseException::AddMessage("; ");
08086 BaseException::AddMessage(et->entry);
08087 }
08088 }
08089 BaseException::AddMessage(".\n");
08090 }
08091 }
08092
08093 #ifdef SimulateExceptions
08094
08095
08096 Janitor::Janitor()
08097 {
08098 if (do_not_link)
08099 {
08100 do_not_link = false; NextJanitor = 0; OnStack = false;
08101 #ifdef CLEAN_LIST
08102 cout << "Not added to clean-list " << (unsigned long)this << "\n";
08103 #endif
08104 }
08105 else
08106 {
08107 OnStack = true;
08108 #ifdef CLEAN_LIST
08109 cout << "Add to clean-list " << (unsigned long)this << "\n";
08110 #endif
08111 NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
08112 }
08113 }
08114
08115 Janitor::~Janitor()
08116 {
08117
08118
08119 if (OnStack)
08120 {
08121 #ifdef CLEAN_LIST
08122 cout << "Delete from clean-list " << (unsigned long)this << "\n";
08123 #endif
08124 Janitor* lastjan = JumpBase::jl->janitor;
08125 if (this == lastjan) JumpBase::jl->janitor = NextJanitor;
08126 else
08127 {
08128 for (Janitor* jan = lastjan->NextJanitor; jan;
08129 jan = lastjan->NextJanitor)
08130 {
08131 if (jan==this)
08132 { lastjan->NextJanitor = jan->NextJanitor; return; }
08133 lastjan=jan;
08134 }
08135
08136 Throw(BaseException(
08137 "Cannot resolve memory linked list\nSee notes in myexcept.cpp for details\n"
08138 ));
08139
08140
08141
08142
08143
08144
08145
08146
08147
08148
08149
08150
08151
08152
08153
08154
08155
08156
08157
08158
08159
08160
08161
08162
08163
08164
08165
08166 }
08167 }
08168 }
08169
08170 JumpItem* JumpBase::jl;
08171 jmp_buf JumpBase::env;
08172 bool Janitor::do_not_link;
08173
08174
08175 int JanitorInitializer::ref_count;
08176
08177 JanitorInitializer::JanitorInitializer()
08178 {
08179 if (ref_count++ == 0) new JumpItem;
08180
08181 }
08182
08183 #endif // end of SimulateExceptions
08184
08185 Tracer* Tracer::last;
08186
08187
08188 void Terminate()
08189 {
08190 cout << "\n\nThere has been an exception with no handler - exiting";
08191 const char* what = BaseException::what();
08192 if (what) cout << what << "\n";
08193 exit(1);
08194 }
08195
08196
08197
08198 #ifdef DO_FREE_CHECK
08199
08200
08201 FreeCheckLink::FreeCheckLink() : next(FreeCheck::next)
08202 { FreeCheck::next = this; }
08203
08204 FCLClass::FCLClass(void* t, char* name) : ClassName(name) { ClassStore=t; }
08205
08206 FCLRealArray::FCLRealArray(void* t, char* o, int s)
08207 : Operation(o), size(s) { ClassStore=t; }
08208
08209 FCLIntArray::FCLIntArray(void* t, char* o, int s)
08210 : Operation(o), size(s) { ClassStore=t; }
08211
08212 FreeCheckLink* FreeCheck::next;
08213 int FreeCheck::BadDelete;
08214
08215 void FCLClass::Report()
08216 { cout << " " << ClassName << " " << (unsigned long)ClassStore << "\n"; }
08217
08218 void FCLRealArray::Report()
08219 {
08220 cout << " " << Operation << " " << (unsigned long)ClassStore <<
08221 " " << size << "\n";
08222 }
08223
08224 void FCLIntArray::Report()
08225 {
08226 cout << " " << Operation << " " << (unsigned long)ClassStore <<
08227 " " << size << "\n";
08228 }
08229
08230 void FreeCheck::Register(void* t, char* name)
08231 {
08232 FCLClass* f = new FCLClass(t,name);
08233 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
08234 #ifdef REG_DEREG
08235 cout << "Registering " << name << " " << (unsigned long)t << "\n";
08236 #endif
08237 }
08238
08239 void FreeCheck::RegisterR(void* t, char* o, int s)
08240 {
08241 FCLRealArray* f = new FCLRealArray(t,o,s);
08242 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
08243 #ifdef REG_DEREG
08244 cout << o << " " << s << " " << (unsigned long)t << "\n";
08245 #endif
08246 }
08247
08248 void FreeCheck::RegisterI(void* t, char* o, int s)
08249 {
08250 FCLIntArray* f = new FCLIntArray(t,o,s);
08251 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
08252 #ifdef REG_DEREG
08253 cout << o << " " << s << " " << (unsigned long)t << "\n";
08254 #endif
08255 }
08256
08257 void FreeCheck::DeRegister(void* t, char* name)
08258 {
08259 FreeCheckLink* last = 0;
08260 #ifdef REG_DEREG
08261 cout << "Deregistering " << name << " " << (unsigned long)t << "\n";
08262 #endif
08263 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
08264 {
08265 if (fcl->ClassStore==t)
08266 {
08267 if (last) last->next = fcl->next; else next = fcl->next;
08268 delete fcl; return;
08269 }
08270 last = fcl;
08271 }
08272 cout << "\nRequest to delete non-existent object of class and location:\n";
08273 cout << " " << name << " " << (unsigned long)t << "\n";
08274 BadDelete++;
08275 Tracer::PrintTrace();
08276 cout << "\n";
08277 }
08278
08279 void FreeCheck::DeRegisterR(void* t, char* o, int s)
08280 {
08281 FreeCheckLink* last = 0;
08282 #ifdef REG_DEREG
08283 cout << o << " " << s << " " << (unsigned long)t << "\n";
08284 #endif
08285 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
08286 {
08287 if (fcl->ClassStore==t)
08288 {
08289 if (last) last->next = fcl->next; else next = fcl->next;
08290 if (s >= 0 && ((FCLRealArray*)fcl)->size != s)
08291 {
08292 cout << "\nArray sizes do not agree:\n";
08293 cout << " " << o << " " << (unsigned long)t
08294 << " " << ((FCLRealArray*)fcl)->size << " " << s << "\n";
08295 Tracer::PrintTrace();
08296 cout << "\n";
08297 }
08298 delete fcl; return;
08299 }
08300 last = fcl;
08301 }
08302 cout << "\nRequest to delete non-existent real array:\n";
08303 cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
08304 BadDelete++;
08305 Tracer::PrintTrace();
08306 cout << "\n";
08307 }
08308
08309 void FreeCheck::DeRegisterI(void* t, char* o, int s)
08310 {
08311 FreeCheckLink* last = 0;
08312 #ifdef REG_DEREG
08313 cout << o << " " << s << " " << (unsigned long)t << "\n";
08314 #endif
08315 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
08316 {
08317 if (fcl->ClassStore==t)
08318 {
08319 if (last) last->next = fcl->next; else next = fcl->next;
08320 if (s >= 0 && ((FCLIntArray*)fcl)->size != s)
08321 {
08322 cout << "\nArray sizes do not agree:\n";
08323 cout << " " << o << " " << (unsigned long)t
08324 << " " << ((FCLIntArray*)fcl)->size << " " << s << "\n";
08325 Tracer::PrintTrace();
08326 cout << "\n";
08327 }
08328 delete fcl; return;
08329 }
08330 last = fcl;
08331 }
08332 cout << "\nRequest to delete non-existent int array:\n";
08333 cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
08334 BadDelete++;
08335 Tracer::PrintTrace();
08336 cout << "\n";
08337 }
08338
08339 void FreeCheck::Status()
08340 {
08341 if (next)
08342 {
08343 cout << "\nObjects of the following classes remain undeleted:\n";
08344 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next) fcl->Report();
08345 cout << "\n";
08346 }
08347 else cout << "\nNo objects remain undeleted\n\n";
08348 if (BadDelete)
08349 {
08350 cout << "\nThere were " << BadDelete <<
08351 " requests to delete non-existent items\n\n";
08352 }
08353 }
08354
08355 #endif // end of DO_FREE_CHECK
08356
08357
08358
08359 Logic_error::Logic_error(const char* a_what) : BaseException()
08360 {
08361 Select = BaseException::Select;
08362 AddMessage("Logic error:- "); AddMessage(a_what);
08363 if (a_what) Tracer::AddTrace();
08364 }
08365
08366 Runtime_error::Runtime_error(const char* a_what)
08367 : BaseException()
08368 {
08369 Select = BaseException::Select;
08370 AddMessage("Runtime error:- "); AddMessage(a_what);
08371 if (a_what) Tracer::AddTrace();
08372 }
08373
08374 Domain_error::Domain_error(const char* a_what) : Logic_error()
08375 {
08376 Select = BaseException::Select;
08377 AddMessage("domain error\n"); AddMessage(a_what);
08378 if (a_what) Tracer::AddTrace();
08379 }
08380
08381 Invalid_argument::Invalid_argument(const char* a_what) : Logic_error()
08382 {
08383 Select = BaseException::Select;
08384 AddMessage("invalid argument\n"); AddMessage(a_what);
08385 if (a_what) Tracer::AddTrace();
08386 }
08387
08388 Length_error::Length_error(const char* a_what) : Logic_error()
08389 {
08390 Select = BaseException::Select;
08391 AddMessage("length error\n"); AddMessage(a_what);
08392 if (a_what) Tracer::AddTrace();
08393 }
08394
08395 Out_of_range::Out_of_range(const char* a_what) : Logic_error()
08396 {
08397 Select = BaseException::Select;
08398 AddMessage("out of range\n"); AddMessage(a_what);
08399 if (a_what) Tracer::AddTrace();
08400 }
08401
08402
08403
08404
08405
08406
08407
08408
08409
08410
08411
08412
08413
08414
08415
08416 Range_error::Range_error(const char* a_what) : Runtime_error()
08417 {
08418 Select = BaseException::Select;
08419 AddMessage("range error\n"); AddMessage(a_what);
08420 if (a_what) Tracer::AddTrace();
08421 }
08422
08423 Overflow_error::Overflow_error(const char* a_what) : Runtime_error()
08424 {
08425 Select = BaseException::Select;
08426 AddMessage("overflow error\n"); AddMessage(a_what);
08427 if (a_what) Tracer::AddTrace();
08428 }
08429
08430 Bad_alloc::Bad_alloc(const char* a_what) : BaseException()
08431 {
08432 Select = BaseException::Select;
08433 AddMessage("bad allocation\n"); AddMessage(a_what);
08434 if (a_what) Tracer::AddTrace();
08435 }
08436
08437
08438
08439
08440 unsigned long Logic_error::Select;
08441 unsigned long Runtime_error::Select;
08442 unsigned long Domain_error::Select;
08443 unsigned long Invalid_argument::Select;
08444 unsigned long Length_error::Select;
08445 unsigned long Out_of_range::Select;
08446
08447
08448 unsigned long Range_error::Select;
08449 unsigned long Overflow_error::Select;
08450 unsigned long Bad_alloc::Select;
08451
08452 #ifdef use_namespace
08453 }
08454 #endif
08455
08456
08458
08461
08464
08465
08466
08467
08468 #define WANT_MATH // include.h will get math fns
08469
08470
08471
08472
08473 #ifdef use_namespace
08474 namespace NEWMAT {
08475 #endif
08476
08477
08478
08479 #ifdef DO_REPORT
08480 #define REPORT { static ExeCounter ExeCount(__LINE__,10); ++ExeCount; }
08481 #else
08482 #define REPORT {}
08483 #endif
08484
08485 static inline int my_min(int x, int y) { return x < y ? x : y; }
08486 static inline int my_max(int x, int y) { return x > y ? x : y; }
08487
08488
08489 BandMatrix::BandMatrix(const BaseMatrix& M)
08490 {
08491 REPORT
08492
08493 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::BM);
08494 GetMatrix(gmx); CornerClear();
08495 }
08496
08497 void BandMatrix::SetParameters(const GeneralMatrix* gmx)
08498 {
08499 REPORT
08500 MatrixBandWidth bw = gmx->bandwidth();
08501 lower_val = bw.lower_val; upper_val = bw.upper_val;
08502 }
08503
08504 void BandMatrix::resize(int n, int lb, int ub)
08505 {
08506 REPORT
08507 Tracer tr("BandMatrix::resize");
08508 if (lb<0 || ub<0) Throw(ProgramException("Undefined bandwidth"));
08509 lower_val = (lb<=n) ? lb : n-1; upper_val = (ub<=n) ? ub : n-1;
08510 GeneralMatrix::resize(n,n,n*(lower_val+1+upper_val)); CornerClear();
08511 }
08512
08513
08514
08515
08516
08517
08518
08519
08520
08521
08522
08523
08527
08528 short BandMatrix::SimpleAddOK(const GeneralMatrix* gm)
08529 {
08530 const BandMatrix* bm = (const BandMatrix*)gm;
08531 if (bm->lower_val == lower_val && bm->upper_val == upper_val)
08532 { REPORT return 0; }
08533 else if (bm->lower_val >= lower_val && bm->upper_val >= upper_val)
08534 { REPORT return 1; }
08535 else if (bm->lower_val <= lower_val && bm->upper_val <= upper_val)
08536 { REPORT return 2; }
08537 else { REPORT return 3; }
08538 }
08539
08543
08544 short SymmetricBandMatrix::SimpleAddOK(const GeneralMatrix* gm)
08545 {
08546 const SymmetricBandMatrix* bm = (const SymmetricBandMatrix*)gm;
08547 if (bm->lower_val == lower_val) { REPORT return 0; }
08548 else if (bm->lower_val > lower_val) { REPORT return 1; }
08549 else { REPORT return 2; }
08550 }
08551
08553 void UpperBandMatrix::resize(int n, int lb, int ub)
08554 {
08555 REPORT
08556 if (lb != 0)
08557 {
08558 Tracer tr("UpperBandMatrix::resize");
08559 Throw(ProgramException("UpperBandMatrix with non-zero lower band" ));
08560 }
08561 BandMatrix::resize(n, lb, ub);
08562 }
08563
08565 void LowerBandMatrix::resize(int n, int lb, int ub)
08566 {
08567 REPORT
08568 if (ub != 0)
08569 {
08570 Tracer tr("LowerBandMatrix::resize");
08571 Throw(ProgramException("LowerBandMatrix with non-zero upper band" ));
08572 }
08573 BandMatrix::resize(n, lb, ub);
08574 }
08575
08577 void BandMatrix::resize(const GeneralMatrix& A)
08578 {
08579 REPORT
08580 int n = A.Nrows();
08581 if (n != A.Ncols())
08582 {
08583 Tracer tr("BandMatrix::resize(GM)");
08584 Throw(NotSquareException(*this));
08585 }
08586 MatrixBandWidth mbw = A.bandwidth();
08587 resize(n, mbw.Lower(), mbw.Upper());
08588 }
08589
08590
08591
08592
08593
08594
08595
08596
08597
08598
08599
08600
08601
08602
08603
08604
08605
08606
08607
08608
08609
08610
08611
08612
08613
08614
08615
08616
08617
08618
08619
08620
08621
08622
08623
08624
08626 void BandMatrix::operator=(const BaseMatrix& X)
08627 {
08628 REPORT
08629
08630 Eq(X,MatrixType::BM); CornerClear();
08631 }
08632
08634 void BandMatrix::CornerClear() const
08635 {
08636 REPORT
08637 int i = lower_val; Real* s = store; int bw = lower_val + 1 + upper_val;
08638 while (i)
08639 { int j = i--; Real* sj = s; s += bw; while (j--) *sj++ = 0.0; }
08640 i = upper_val; s = store + storage;
08641 while (i)
08642 { int j = i--; Real* sj = s; s -= bw; while (j--) *(--sj) = 0.0; }
08643 }
08644
08645 MatrixBandWidth MatrixBandWidth::operator+(const MatrixBandWidth& bw) const
08646 {
08647 REPORT
08648 int l = bw.lower_val; int u = bw.upper_val;
08649 l = (lower_val < 0 || l < 0) ? -1 : (lower_val > l) ? lower_val : l;
08650 u = (upper_val < 0 || u < 0) ? -1 : (upper_val > u) ? upper_val : u;
08651 return MatrixBandWidth(l,u);
08652 }
08653
08654 MatrixBandWidth MatrixBandWidth::operator*(const MatrixBandWidth& bw) const
08655 {
08656 REPORT
08657 int l = bw.lower_val; int u = bw.upper_val;
08658 l = (lower_val < 0 || l < 0) ? -1 : lower_val+l;
08659 u = (upper_val < 0 || u < 0) ? -1 : upper_val+u;
08660 return MatrixBandWidth(l,u);
08661 }
08662
08663 MatrixBandWidth MatrixBandWidth::minimum(const MatrixBandWidth& bw) const
08664 {
08665 REPORT
08666 int l = bw.lower_val; int u = bw.upper_val;
08667 if ((lower_val >= 0) && ( (l < 0) || (l > lower_val) )) l = lower_val;
08668 if ((upper_val >= 0) && ( (u < 0) || (u > upper_val) )) u = upper_val;
08669 return MatrixBandWidth(l,u);
08670 }
08671
08672 UpperBandMatrix::UpperBandMatrix(const BaseMatrix& M)
08673 {
08674 REPORT
08675
08676 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UB);
08677 GetMatrix(gmx); CornerClear();
08678 }
08679
08680 void UpperBandMatrix::operator=(const BaseMatrix& X)
08681 {
08682 REPORT
08683
08684 Eq(X,MatrixType::UB); CornerClear();
08685 }
08686
08687 LowerBandMatrix::LowerBandMatrix(const BaseMatrix& M)
08688 {
08689 REPORT
08690
08691 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LB);
08692 GetMatrix(gmx); CornerClear();
08693 }
08694
08695 void LowerBandMatrix::operator=(const BaseMatrix& X)
08696 {
08697 REPORT
08698
08699 Eq(X,MatrixType::LB); CornerClear();
08700 }
08701
08702 BandLUMatrix::BandLUMatrix(const BaseMatrix& m)
08703 {
08704 REPORT
08705 Tracer tr("BandLUMatrix");
08706 storage2 = 0; store2 = 0; indx = 0;
08707 GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate();
08708 if (gm->nrows() != gm->ncols())
08709 { gm->tDelete(); Throw(NotSquareException(*this)); }
08710 if (gm->type() == MatrixType::BC)
08711 { REPORT ((BandLUMatrix*)gm)->get_aux(*this); GetMatrix(gm); }
08712 else
08713 {
08714 REPORT
08715 BandMatrix* gm1 = (BandMatrix*)(gm->Evaluate(MatrixType::BM));
08716 m1 = gm1->lower_val; m2 = gm1->upper_val;
08717 GetMatrix(gm1);
08718 d = true; sing = false;
08719 indx = new int [nrows_val]; MatrixErrorNoSpace(indx);
08720 MONITOR_INT_NEW("Index (BndLUMat)",nrows_val,indx)
08721 storage2 = nrows_val * m1;
08722 store2 = new Real [storage2]; MatrixErrorNoSpace(store2);
08723 MONITOR_REAL_NEW("Make (BandLUMat)",storage2,store2)
08724 ludcmp();
08725 }
08726 }
08727
08728 GeneralMatrix* BandLUMatrix::Evaluate(MatrixType mt)
08729 {
08730 if (Compare(this->Type(),mt)) { REPORT return this; }
08731 REPORT
08732 Tracer et("BandLUMatrix::Evaluate");
08733 bool dummy = true;
08734 if (dummy) Throw(ProgramException("Illegal use of BandLUMatrix", *this));
08735 return this;
08736 }
08737
08738
08739 void BandLUMatrix::get_aux(BandLUMatrix& X)
08740 {
08741 X.d = d; X.sing = sing; X.storage2 = storage2; X.m1 = m1; X.m2 = m2;
08742 if (tag_val == 0 || tag_val == 1)
08743 {
08744 REPORT
08745 X.indx = indx; indx = 0;
08746 X.store2 = store2; store2 = 0;
08747 d = true; sing = true; storage2 = 0; m1 = 0; m2 = 0;
08748 return;
08749 }
08750 else if (nrows_val == 0)
08751 {
08752 REPORT
08753 indx = 0; store2 = 0; storage2 = 0;
08754 d = true; sing = true; m1 = m2 = 0;
08755 return;
08756 }
08757 else
08758 {
08759 REPORT
08760 Tracer tr("BandLUMatrix::get_aux");
08761 int *ix = new int [nrows_val]; MatrixErrorNoSpace(ix);
08762 MONITOR_INT_NEW("Index (BLUM::get_aux)", nrows_val, ix)
08763 int n = nrows_val; int* i = ix; int* j = indx;
08764 while(n--) *i++ = *j++;
08765 X.indx = ix;
08766 Real *rx = new Real [storage2]; MatrixErrorNoSpace(indx);
08767 MONITOR_REAL_NEW("Index (BLUM::get_aux)", storage2, rx)
08768 newmat_block_copy(storage2, store2, rx);
08769 X.store2 = rx;
08770 }
08771 }
08772
08773 BandLUMatrix::BandLUMatrix(const BandLUMatrix& gm) : GeneralMatrix()
08774 {
08775 REPORT
08776 Tracer tr("BandLUMatrix(const BandLUMatrix&)");
08777 ((BandLUMatrix&)gm).get_aux(*this);
08778 GetMatrix(&gm);
08779 }
08780
08781 void BandLUMatrix::operator=(const BandLUMatrix& gm)
08782 {
08783 if (&gm == this) { REPORT tag_val = -1; return; }
08784 REPORT
08785 delete [] indx; indx = 0;
08786 delete [] store2; store2 = 0; storage2 = 0;
08787 ((BandLUMatrix&)gm).get_aux(*this);
08788 Eq(gm);
08789 }
08790
08791
08792
08793
08794
08795
08796
08797
08798 BandLUMatrix::~BandLUMatrix()
08799 {
08800 REPORT
08801 MONITOR_INT_DELETE("Index (BndLUMat)",nrows_val,indx)
08802 MONITOR_REAL_DELETE("Delete (BndLUMt)",storage2,store2)
08803 delete [] indx; delete [] store2;
08804 }
08805
08806 MatrixType BandLUMatrix::type() const { REPORT return MatrixType::BC; }
08807
08808
08809 LogAndSign BandLUMatrix::log_determinant() const
08810 {
08811 REPORT
08812 if (sing) return 0.0;
08813 Real* a = store; int w = m1+1+m2; LogAndSign sum; int i = nrows_val;
08814
08815 if (i) for (;;) { sum *= *a; if (!(--i)) break; a += w; }
08816 if (!d) sum.ChangeSign(); return sum;
08817 }
08818
08819 GeneralMatrix* BandMatrix::MakeSolver()
08820 {
08821 REPORT
08822 GeneralMatrix* gm = new BandLUMatrix(*this);
08823 MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
08824 }
08825
08826
08827 void BandLUMatrix::ludcmp()
08828 {
08829 REPORT
08830 Real* a = store2; int i = storage2;
08831
08832
08833 while (i--) *a++ = 0.0;
08834 a = store;
08835 i = m1; int j = m2; int k; int n = nrows_val; int w = m1 + 1 + m2;
08836 while (i)
08837 {
08838 Real* ai = a + i;
08839 k = ++j; while (k--) *a++ = *ai++;
08840 k = i--; while (k--) *a++ = 0.0;
08841 }
08842
08843 a = store; int l = m1;
08844 for (k=0; k<n; k++)
08845 {
08846 Real x = *a; i = k; Real* aj = a;
08847 if (l < n) l++;
08848 for (j=k+1; j<l; j++)
08849 { aj += w; if (fabs(x) < fabs(*aj)) { x = *aj; i = j; } }
08850 indx[k] = i;
08851 if (x==0) { sing = true; return; }
08852 if (i!=k)
08853 {
08854 d = !d; Real* ak = a; Real* ai = store + i * w; j = w;
08855 while (j--) { x = *ak; *ak++ = *ai; *ai++ = x; }
08856 }
08857 aj = a + w; Real* m = store2 + m1 * k;
08858 for (j=k+1; j<l; j++)
08859 {
08860 *m++ = x = *aj / *a; i = w; Real* ak = a;
08861 while (--i) { Real* aj1 = aj++; *aj1 = *aj - x * *(++ak); }
08862 *aj++ = 0.0;
08863 }
08864 a += w;
08865 }
08866 }
08867
08868 void BandLUMatrix::lubksb(Real* B, int mini)
08869 {
08870 REPORT
08871 Tracer tr("BandLUMatrix::lubksb");
08872 if (sing) Throw(SingularException(*this));
08873 int n = nrows_val; int l = m1; int w = m1 + 1 + m2;
08874
08875 for (int k=0; k<n; k++)
08876 {
08877 int i = indx[k];
08878 if (i!=k) { Real x=B[k]; B[k]=B[i]; B[i]=x; }
08879 if (l<n) l++;
08880 Real* m = store2 + k*m1; Real* b = B+k; Real* bi = b;
08881 for (i=k+1; i<l; i++) *(++bi) -= *m++ * *b;
08882 }
08883
08884 l = -m1;
08885 for (int i = n-1; i>=mini; i--)
08886 {
08887 Real* b = B + i; Real* bk = b; Real x = *bk;
08888 Real* a = store + w*i; Real y = *a;
08889 int k = l+m1; while (k--) x -= *(++a) * *(++bk);
08890 *b = x / y;
08891 if (l < m2) l++;
08892 }
08893 }
08894
08895 void BandLUMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin)
08896 {
08897 REPORT
08898 int i = mcin.skip; Real* el = mcin.data-i; Real* el1=el;
08899 while (i--) *el++ = 0.0;
08900 el += mcin.storage; i = nrows_val - mcin.skip - mcin.storage;
08901 while (i--) *el++ = 0.0;
08902 lubksb(el1, mcout.skip);
08903 }
08904
08905
08906
08907
08908 void UpperBandMatrix::Solver(MatrixColX& mcout,
08909 const MatrixColX& mcin)
08910 {
08911 REPORT
08912 int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
08913 while (i-- > 0) *elx++ = 0.0;
08914 int nr = mcin.skip+mcin.storage;
08915 elx = mcin.data+mcin.storage; Real* el = elx;
08916 int j = mcout.skip+mcout.storage-nr; i = nr-mcout.skip;
08917 while (j-- > 0) *elx++ = 0.0;
08918
08919 Real* Ael = store + (upper_val+1)*(i-1)+1; j = 0;
08920 if (i > 0) for(;;)
08921 {
08922 elx = el; Real sum = 0.0; int jx = j;
08923 while (jx--) sum += *(--Ael) * *(--elx);
08924 elx--; *elx = (*elx - sum) / *(--Ael);
08925 if (--i <= 0) break;
08926 if (j<upper_val) Ael -= upper_val - (++j); else el--;
08927 }
08928 }
08929
08930 void LowerBandMatrix::Solver(MatrixColX& mcout,
08931 const MatrixColX& mcin)
08932 {
08933 REPORT
08934 int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
08935 while (i-- > 0) *elx++ = 0.0;
08936 int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage;
08937 int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
08938 while (j-- > 0) *elx++ = 0.0;
08939
08940 Real* el = mcin.data;
08941 Real* Ael = store + (lower_val+1)*nc + lower_val;
08942 j = 0;
08943 if (i > 0) for(;;)
08944 {
08945 elx = el; Real sum = 0.0; int jx = j;
08946 while (jx--) sum += *Ael++ * *elx++;
08947 *elx = (*elx - sum) / *Ael++;
08948 if (--i <= 0) break;
08949 if (j<lower_val) Ael += lower_val - (++j); else el++;
08950 }
08951 }
08952
08953
08954 LogAndSign BandMatrix::log_determinant() const
08955 {
08956 REPORT
08957 BandLUMatrix C(*this); return C.log_determinant();
08958 }
08959
08960 LogAndSign LowerBandMatrix::log_determinant() const
08961 {
08962 REPORT
08963 int i = nrows_val; LogAndSign sum;
08964 Real* s = store + lower_val; int j = lower_val + 1;
08965
08966 if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
08967 ((GeneralMatrix&)*this).tDelete(); return sum;
08968 }
08969
08970 LogAndSign UpperBandMatrix::log_determinant() const
08971 {
08972 REPORT
08973 int i = nrows_val; LogAndSign sum; Real* s = store; int j = upper_val + 1;
08974
08975 if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
08976 ((GeneralMatrix&)*this).tDelete(); return sum;
08977 }
08978
08979 GeneralMatrix* SymmetricBandMatrix::MakeSolver()
08980 {
08981 REPORT
08982 GeneralMatrix* gm = new BandLUMatrix(*this);
08983 MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
08984 }
08985
08986 SymmetricBandMatrix::SymmetricBandMatrix(const BaseMatrix& M)
08987 {
08988 REPORT
08989
08990 GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::SB);
08991 GetMatrix(gmx);
08992 }
08993
08994 GeneralMatrix* SymmetricBandMatrix::Transpose(TransposedMatrix*, MatrixType mt)
08995 { REPORT return Evaluate(mt); }
08996
08997 LogAndSign SymmetricBandMatrix::log_determinant() const
08998 {
08999 REPORT
09000 BandLUMatrix C(*this); return C.log_determinant();
09001 }
09002
09003 void SymmetricBandMatrix::SetParameters(const GeneralMatrix* gmx)
09004 { REPORT lower_val = gmx->bandwidth().lower_val; }
09005
09006 void SymmetricBandMatrix::resize(int n, int lb)
09007 {
09008 REPORT
09009 Tracer tr("SymmetricBandMatrix::resize");
09010 if (lb<0) Throw(ProgramException("Undefined bandwidth"));
09011 lower_val = (lb<=n) ? lb : n-1;
09012 GeneralMatrix::resize(n,n,n*(lower_val+1));
09013 }
09014
09015 void SymmetricBandMatrix::resize(const GeneralMatrix& A)
09016 {
09017 REPORT
09018 int n = A.Nrows();
09019 if (n != A.Ncols())
09020 {
09021 Tracer tr("SymmetricBandMatrix::resize(GM)");
09022 Throw(NotSquareException(*this));
09023 }
09024 MatrixBandWidth mbw = A.bandwidth(); int b = mbw.Lower();
09025 if (b != mbw.Upper())
09026 {
09027 Tracer tr("SymmetricBandMatrix::resize(GM)");
09028 Throw(ProgramException("Upper and lower band-widths not equal"));
09029 }
09030 resize(n, b);
09031 }
09032
09033
09034
09035
09036
09037
09038
09039
09040
09041
09042
09043
09044
09045
09046
09047
09048
09049
09050
09051
09052
09053
09054
09055
09056
09057
09058
09059
09060
09061
09062
09063
09064
09065 void SymmetricBandMatrix::operator=(const BaseMatrix& X)
09066 {
09067 REPORT
09068
09069 Eq(X,MatrixType::SB);
09070 }
09071
09072 void SymmetricBandMatrix::CornerClear() const
09073 {
09074
09075 REPORT
09076 int i = lower_val; Real* s = store; int bw = lower_val + 1;
09077 if (i) for(;;)
09078 {
09079 int j = i;
09080 Real* sj = s;
09081 while (j--) *sj++ = 0.0;
09082 if (!(--i)) break;
09083 s += bw;
09084 }
09085 }
09086
09087 MatrixBandWidth SymmetricBandMatrix::bandwidth() const
09088 { REPORT return MatrixBandWidth(lower_val,lower_val); }
09089
09090 GeneralMatrix* BandMatrix::Image() const
09091 {
09092 REPORT
09093 GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm);
09094 return gm;
09095 }
09096
09097 GeneralMatrix* UpperBandMatrix::Image() const
09098 {
09099 REPORT
09100 GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm);
09101 return gm;
09102 }
09103
09104 GeneralMatrix* LowerBandMatrix::Image() const
09105 {
09106 REPORT
09107 GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm);
09108 return gm;
09109 }
09110
09111 GeneralMatrix* SymmetricBandMatrix::Image() const
09112 {
09113 REPORT
09114 GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm);
09115 return gm;
09116 }
09117
09118 GeneralMatrix* BandLUMatrix::Image() const
09119 {
09120 REPORT
09121 GeneralMatrix* gm = new BandLUMatrix(*this); MatrixErrorNoSpace(gm);
09122 return gm;
09123 }
09124
09125
09126 Real SymmetricBandMatrix::sum_square() const
09127 {
09128 REPORT
09129 CornerClear();
09130 Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows_val;
09131 int l=lower_val;
09132 while (i--)
09133 { int j = l; while (j--) sum2 += square(*s++); sum1 += square(*s++); }
09134 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
09135 }
09136
09137 Real SymmetricBandMatrix::sum_absolute_value() const
09138 {
09139 REPORT
09140 CornerClear();
09141 Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows_val;
09142 int l=lower_val;
09143 while (i--)
09144 { int j = l; while (j--) sum2 += fabs(*s++); sum1 += fabs(*s++); }
09145 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
09146 }
09147
09148 Real SymmetricBandMatrix::sum() const
09149 {
09150 REPORT
09151 CornerClear();
09152 Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows_val;
09153 int l=lower_val;
09154 while (i--)
09155 { int j = l; while (j--) sum2 += *s++; sum1 += *s++; }
09156 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
09157 }
09158
09159
09160
09161
09162
09163 #ifdef use_namespace
09164 }
09165 #endif
09166
09168
09169
09172
09175
09176
09177
09178 #ifdef use_namespace
09179 namespace NEWMAT {
09180 #endif
09181
09182 #ifdef DO_REPORT
09183 #define REPORT { static ExeCounter ExeCount(__LINE__,11); ++ExeCount; }
09184 #else
09185 #define REPORT {}
09186 #endif
09187
09188
09189
09190
09191 GetSubMatrix BaseMatrix::submatrix(int first_row, int last_row, int first_col,
09192 int last_col) const
09193 {
09194 REPORT
09195 Tracer tr("submatrix");
09196 int a = first_row - 1; int b = last_row - first_row + 1;
09197 int c = first_col - 1; int d = last_col - first_col + 1;
09198 if (a<0 || b<0 || c<0 || d<0) Throw(SubMatrixDimensionException());
09199
09200 return GetSubMatrix(this, a, b, c, d, false);
09201 }
09202
09203 GetSubMatrix BaseMatrix::sym_submatrix(int first_row, int last_row) const
09204 {
09205 REPORT
09206 Tracer tr("sym_submatrix");
09207 int a = first_row - 1; int b = last_row - first_row + 1;
09208 if (a<0 || b<0) Throw(SubMatrixDimensionException());
09209
09210 return GetSubMatrix( this, a, b, a, b, true);
09211 }
09212
09213 GetSubMatrix BaseMatrix::row(int first_row) const
09214 {
09215 REPORT
09216 Tracer tr("SubMatrix(row)");
09217 int a = first_row - 1;
09218 if (a<0) Throw(SubMatrixDimensionException());
09219 return GetSubMatrix(this, a, 1, 0, -1, false);
09220 }
09221
09222 GetSubMatrix BaseMatrix::rows(int first_row, int last_row) const
09223 {
09224 REPORT
09225 Tracer tr("SubMatrix(rows)");
09226 int a = first_row - 1; int b = last_row - first_row + 1;
09227 if (a<0 || b<0) Throw(SubMatrixDimensionException());
09228
09229 return GetSubMatrix(this, a, b, 0, -1, false);
09230 }
09231
09232 GetSubMatrix BaseMatrix::column(int first_col) const
09233 {
09234 REPORT
09235 Tracer tr("SubMatrix(column)");
09236 int c = first_col - 1;
09237 if (c<0) Throw(SubMatrixDimensionException());
09238 return GetSubMatrix(this, 0, -1, c, 1, false);
09239 }
09240
09241 GetSubMatrix BaseMatrix::columns(int first_col, int last_col) const
09242 {
09243 REPORT
09244 Tracer tr("SubMatrix(columns)");
09245 int c = first_col - 1; int d = last_col - first_col + 1;
09246 if (c<0 || d<0) Throw(SubMatrixDimensionException());
09247
09248 return GetSubMatrix(this, 0, -1, c, d, false);
09249 }
09250
09251 void GetSubMatrix::SetUpLHS()
09252 {
09253 REPORT
09254 Tracer tr("SubMatrix(LHS)");
09255 const BaseMatrix* bm1 = bm;
09256 GeneralMatrix* gm1 = ((BaseMatrix*&)bm)->Evaluate();
09257 if ((BaseMatrix*)gm1!=bm1)
09258 Throw(ProgramException("Invalid LHS"));
09259 if (row_number < 0) row_number = gm1->Nrows();
09260 if (col_number < 0) col_number = gm1->Ncols();
09261 if (row_skip+row_number > gm1->Nrows()
09262 || col_skip+col_number > gm1->Ncols())
09263 Throw(SubMatrixDimensionException());
09264 }
09265
09266 void GetSubMatrix::operator<<(const BaseMatrix& bmx)
09267 {
09268 REPORT
09269 Tracer tr("SubMatrix(<<)"); GeneralMatrix* gmx = 0;
09270 Try
09271 {
09272 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
09273 if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
09274 Throw(IncompatibleDimensionsException());
09275 MatrixRow mrx(gmx, LoadOnEntry);
09276 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09277
09278 MatrixRowCol sub; int i = row_number;
09279 while (i--)
09280 {
09281 mr.SubRowCol(sub, col_skip, col_number);
09282 sub.Copy(mrx); mr.Next(); mrx.Next();
09283 }
09284 gmx->tDelete();
09285 }
09286
09287 CatchAll
09288 {
09289 if (gmx) gmx->tDelete();
09290 ReThrow;
09291 }
09292 }
09293
09294 void GetSubMatrix::operator=(const BaseMatrix& bmx)
09295 {
09296 REPORT
09297 Tracer tr("SubMatrix(=)"); GeneralMatrix* gmx = 0;
09298
09299 Try
09300 {
09301 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
09302 if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
09303 Throw(IncompatibleDimensionsException());
09304 LoadAndStoreFlag lasf =
09305 ( row_skip == col_skip
09306 && gm->type().is_symmetric()
09307 && gmx->type().is_symmetric() )
09308 ? LoadOnEntry+DirectPart
09309 : LoadOnEntry;
09310 MatrixRow mrx(gmx, lasf);
09311 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09312
09313 MatrixRowCol sub; int i = row_number;
09314 while (i--)
09315 {
09316 mr.SubRowCol(sub, col_skip, col_number);
09317 sub.CopyCheck(mrx); mr.Next(); mrx.Next();
09318 }
09319 gmx->tDelete();
09320 }
09321
09322 CatchAll
09323 {
09324 if (gmx) gmx->tDelete();
09325 ReThrow;
09326 }
09327 }
09328
09329 void GetSubMatrix::operator<<(const double* r)
09330 {
09331 REPORT
09332 Tracer tr("SubMatrix(<<double*)");
09333 SetUpLHS();
09334 if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
09335 Throw(SubMatrixDimensionException());
09336 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09337
09338 MatrixRowCol sub; int i = row_number;
09339 while (i--)
09340 {
09341 mr.SubRowCol(sub, col_skip, col_number);
09342 sub.Copy(r); mr.Next();
09343 }
09344 }
09345
09346 void GetSubMatrix::operator<<(const float* r)
09347 {
09348 REPORT
09349 Tracer tr("SubMatrix(<<float*)");
09350 SetUpLHS();
09351 if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
09352 Throw(SubMatrixDimensionException());
09353 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09354
09355 MatrixRowCol sub; int i = row_number;
09356 while (i--)
09357 {
09358 mr.SubRowCol(sub, col_skip, col_number);
09359 sub.Copy(r); mr.Next();
09360 }
09361 }
09362
09363 void GetSubMatrix::operator<<(const int* r)
09364 {
09365 REPORT
09366 Tracer tr("SubMatrix(<<int*)");
09367 SetUpLHS();
09368 if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
09369 Throw(SubMatrixDimensionException());
09370 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09371
09372 MatrixRowCol sub; int i = row_number;
09373 while (i--)
09374 {
09375 mr.SubRowCol(sub, col_skip, col_number);
09376 sub.Copy(r); mr.Next();
09377 }
09378 }
09379
09380 void GetSubMatrix::operator=(Real r)
09381 {
09382 REPORT
09383 Tracer tr("SubMatrix(=Real)");
09384 SetUpLHS();
09385 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09386
09387 MatrixRowCol sub; int i = row_number;
09388 while (i--)
09389 {
09390 mr.SubRowCol(sub, col_skip, col_number);
09391 sub.Copy(r); mr.Next();
09392 }
09393 }
09394
09395 void GetSubMatrix::inject(const GeneralMatrix& gmx)
09396 {
09397 REPORT
09398 Tracer tr("SubMatrix(inject)");
09399 SetUpLHS();
09400 if (row_number != gmx.Nrows() || col_number != gmx.Ncols())
09401 Throw(IncompatibleDimensionsException());
09402 MatrixRow mrx((GeneralMatrix*)(&gmx), LoadOnEntry);
09403 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09404
09405 MatrixRowCol sub; int i = row_number;
09406 while (i--)
09407 {
09408 mr.SubRowCol(sub, col_skip, col_number);
09409 sub.Inject(mrx); mr.Next(); mrx.Next();
09410 }
09411 }
09412
09413 void GetSubMatrix::operator+=(const BaseMatrix& bmx)
09414 {
09415 REPORT
09416 Tracer tr("SubMatrix(+=)"); GeneralMatrix* gmx = 0;
09417
09418 Try
09419 {
09420 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
09421 if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
09422 Throw(IncompatibleDimensionsException());
09423 MatrixRow mrx(gmx, LoadOnEntry);
09424 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09425
09426 MatrixRowCol sub; int i = row_number;
09427 while (i--)
09428 {
09429 mr.SubRowCol(sub, col_skip, col_number);
09430 sub.Check(mrx);
09431 sub.Add(mrx); mr.Next(); mrx.Next();
09432 }
09433 gmx->tDelete();
09434 }
09435
09436 CatchAll
09437 {
09438 if (gmx) gmx->tDelete();
09439 ReThrow;
09440 }
09441 }
09442
09443 void GetSubMatrix::operator-=(const BaseMatrix& bmx)
09444 {
09445 REPORT
09446 Tracer tr("SubMatrix(-=)"); GeneralMatrix* gmx = 0;
09447
09448 Try
09449 {
09450 SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
09451 if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
09452 Throw(IncompatibleDimensionsException());
09453 MatrixRow mrx(gmx, LoadOnEntry);
09454 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09455
09456 MatrixRowCol sub; int i = row_number;
09457 while (i--)
09458 {
09459 mr.SubRowCol(sub, col_skip, col_number);
09460 sub.Check(mrx);
09461 sub.Sub(mrx); mr.Next(); mrx.Next();
09462 }
09463 gmx->tDelete();
09464 }
09465
09466 CatchAll
09467 {
09468 if (gmx) gmx->tDelete();
09469 ReThrow;
09470 }
09471 }
09472
09473 void GetSubMatrix::operator+=(Real r)
09474 {
09475 REPORT
09476 Tracer tr("SubMatrix(+= or -= Real)");
09477
09478 Try
09479 {
09480 SetUpLHS();
09481 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09482
09483 MatrixRowCol sub; int i = row_number;
09484 while (i--)
09485 {
09486 mr.SubRowCol(sub, col_skip, col_number);
09487 sub.Check();
09488 sub.Add(r); mr.Next();
09489 }
09490 }
09491
09492 CatchAll
09493 {
09494 ReThrow;
09495 }
09496 }
09497
09498 void GetSubMatrix::operator*=(Real r)
09499 {
09500 REPORT
09501 Tracer tr("SubMatrix(*= or /= Real)");
09502
09503 Try
09504 {
09505 SetUpLHS();
09506 MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
09507
09508 MatrixRowCol sub; int i = row_number;
09509 while (i--)
09510 {
09511 mr.SubRowCol(sub, col_skip, col_number);
09512 sub.Multiply(r); mr.Next();
09513 }
09514 }
09515
09516 CatchAll
09517 {
09518 ReThrow;
09519 }
09520 }
09521
09522 #ifdef use_namespace
09523 }
09524 #endif
09525
09527
09530
09533
09534
09535
09536 #define WANT_MATH
09537
09538 #ifdef use_namespace
09539 namespace NEWMAT {
09540 #endif
09541
09542 #ifdef DO_REPORT
09543 #define REPORT { static ExeCounter ExeCount(__LINE__,13); ++ExeCount; }
09544 #else
09545 #define REPORT {}
09546 #endif
09547
09548
09549
09550
09551
09552
09553
09554
09555
09556
09557
09558
09559 #define DoSimpleSort 17 // when to switch to insert sort
09560 #define MaxDepth 50 // maximum recursion depth
09561
09562 static void MyQuickSortDescending(Real* first, Real* last, int depth);
09563 static void InsertionSortDescending(Real* first, const int length,
09564 int guard);
09565 static Real SortThreeDescending(Real* a, Real* b, Real* c);
09566
09567 static void MyQuickSortAscending(Real* first, Real* last, int depth);
09568 static void InsertionSortAscending(Real* first, const int length,
09569 int guard);
09570
09571
09572 void sort_descending(GeneralMatrix& GM)
09573 {
09574 REPORT
09575 Tracer et("sort_descending");
09576
09577 Real* data = GM.Store(); int max = GM.Storage();
09578
09579 if (max > DoSimpleSort) MyQuickSortDescending(data, data + max - 1, 0);
09580 InsertionSortDescending(data, max, DoSimpleSort);
09581
09582 }
09583
09584 static Real SortThreeDescending(Real* a, Real* b, Real* c)
09585 {
09586
09587 if (*a >= *b)
09588 {
09589 if (*b >= *c) { REPORT return *b; }
09590 else if (*a >= *c) { REPORT Real x = *c; *c = *b; *b = x; return x; }
09591 else { REPORT Real x = *a; *a = *c; *c = *b; *b = x; return x; }
09592 }
09593 else if (*c >= *b) { REPORT Real x = *c; *c = *a; *a = x; return *b; }
09594 else if (*a >= *c) { REPORT Real x = *a; *a = *b; *b = x; return x; }
09595 else { REPORT Real x = *c; *c = *a; *a = *b; *b = x; return x; }
09596 }
09597
09598 static void InsertionSortDescending(Real* first, const int length,
09599 int guard)
09600
09601
09602 {
09603 REPORT
09604 if (length <= 1) return;
09605
09606
09607 Real* f = first; Real v = *f; Real* h = f;
09608 if (guard > length) { REPORT guard = length; }
09609 int i = guard - 1;
09610 while (i--) if (v < *(++f)) { v = *f; h = f; }
09611 *h = *first; *first = v;
09612
09613
09614 i = length - 1; f = first;
09615 while (i--)
09616 {
09617 Real* g = f++; h = f; v = *h;
09618 while (*g < v) *h-- = *g--;
09619 *h = v;
09620 }
09621 }
09622
09623 static void MyQuickSortDescending(Real* first, Real* last, int depth)
09624 {
09625 REPORT
09626 for (;;)
09627 {
09628 const int length = last - first + 1;
09629 if (length < DoSimpleSort) { REPORT return; }
09630 if (depth++ > MaxDepth)
09631 Throw(ConvergenceException("QuickSortDescending fails: "));
09632 Real* centre = first + length/2;
09633 const Real test = SortThreeDescending(first, centre, last);
09634 Real* f = first; Real* l = last;
09635 for (;;)
09636 {
09637 while (*(++f) > test) {}
09638 while (*(--l) < test) {}
09639 if (l <= f) break;
09640 const Real temp = *f; *f = *l; *l = temp;
09641 }
09642 if (f > centre)
09643 { REPORT MyQuickSortDescending(l+1, last, depth); last = f-1; }
09644 else { REPORT MyQuickSortDescending(first, f-1, depth); first = l+1; }
09645 }
09646 }
09647
09648 void sort_ascending(GeneralMatrix& GM)
09649 {
09650 REPORT
09651 Tracer et("sort_ascending");
09652
09653 Real* data = GM.Store(); int max = GM.Storage();
09654
09655 if (max > DoSimpleSort) MyQuickSortAscending(data, data + max - 1, 0);
09656 InsertionSortAscending(data, max, DoSimpleSort);
09657
09658 }
09659
09660 static void InsertionSortAscending(Real* first, const int length,
09661 int guard)
09662
09663
09664 {
09665 REPORT
09666 if (length <= 1) return;
09667
09668
09669 Real* f = first; Real v = *f; Real* h = f;
09670 if (guard > length) { REPORT guard = length; }
09671 int i = guard - 1;
09672 while (i--) if (v > *(++f)) { v = *f; h = f; }
09673 *h = *first; *first = v;
09674
09675
09676 i = length - 1; f = first;
09677 while (i--)
09678 {
09679 Real* g = f++; h = f; v = *h;
09680 while (*g > v) *h-- = *g--;
09681 *h = v;
09682 }
09683 }
09684 static void MyQuickSortAscending(Real* first, Real* last, int depth)
09685 {
09686 REPORT
09687 for (;;)
09688 {
09689 const int length = last - first + 1;
09690 if (length < DoSimpleSort) { REPORT return; }
09691 if (depth++ > MaxDepth)
09692 Throw(ConvergenceException("QuickSortAscending fails: "));
09693 Real* centre = first + length/2;
09694 const Real test = SortThreeDescending(last, centre, first);
09695 Real* f = first; Real* l = last;
09696 for (;;)
09697 {
09698 while (*(++f) < test) {}
09699 while (*(--l) > test) {}
09700 if (l <= f) break;
09701 const Real temp = *f; *f = *l; *l = temp;
09702 }
09703 if (f > centre)
09704 { REPORT MyQuickSortAscending(l+1, last, depth); last = f-1; }
09705 else { REPORT MyQuickSortAscending(first, f-1, depth); first = l+1; }
09706 }
09707 }
09708
09709
09710
09711
09712
09713
09714
09715
09716
09717 void SortSV(DiagonalMatrix& D, Matrix& U, bool ascending)
09718 {
09719 REPORT
09720 Tracer trace("SortSV_DU");
09721 int m = U.Nrows(); int n = U.Ncols();
09722 if (n != D.Nrows()) Throw(IncompatibleDimensionsException(D,U));
09723 Real* u = U.Store();
09724 for (int i=0; i<n; i++)
09725 {
09726 int k = i; Real p = D.element(i);
09727 if (ascending)
09728 {
09729 for (int j=i+1; j<n; j++)
09730 { if (D.element(j) < p) { k = j; p = D.element(j); } }
09731 }
09732 else
09733 {
09734 for (int j=i+1; j<n; j++)
09735 { if (D.element(j) > p) { k = j; p = D.element(j); } }
09736 }
09737 if (k != i)
09738 {
09739 D.element(k) = D.element(i); D.element(i) = p; int j = m;
09740 Real* uji = u + i; Real* ujk = u + k;
09741 if (j) for(;;)
09742 {
09743 p = *uji; *uji = *ujk; *ujk = p;
09744 if (!(--j)) break;
09745 uji += n; ujk += n;
09746 }
09747 }
09748 }
09749 }
09750
09751 void SortSV(DiagonalMatrix& D, Matrix& U, Matrix& V, bool ascending)
09752 {
09753 REPORT
09754 Tracer trace("SortSV_DUV");
09755 int mu = U.Nrows(); int mv = V.Nrows(); int n = D.Nrows();
09756 if (n != U.Ncols()) Throw(IncompatibleDimensionsException(D,U));
09757 if (n != V.Ncols()) Throw(IncompatibleDimensionsException(D,V));
09758 Real* u = U.Store(); Real* v = V.Store();
09759 for (int i=0; i<n; i++)
09760 {
09761 int k = i; Real p = D.element(i);
09762 if (ascending)
09763 {
09764 for (int j=i+1; j<n; j++)
09765 { if (D.element(j) < p) { k = j; p = D.element(j); } }
09766 }
09767 else
09768 {
09769 for (int j=i+1; j<n; j++)
09770 { if (D.element(j) > p) { k = j; p = D.element(j); } }
09771 }
09772 if (k != i)
09773 {
09774 D.element(k) = D.element(i); D.element(i) = p;
09775 Real* uji = u + i; Real* ujk = u + k;
09776 Real* vji = v + i; Real* vjk = v + k;
09777 int j = mu;
09778 if (j) for(;;)
09779 {
09780 p = *uji; *uji = *ujk; *ujk = p; if (!(--j)) break;
09781 uji += n; ujk += n;
09782 }
09783 j = mv;
09784 if (j) for(;;)
09785 {
09786 p = *vji; *vji = *vjk; *vjk = p; if (!(--j)) break;
09787 vji += n; vjk += n;
09788 }
09789 }
09790 }
09791 }
09792
09793
09794
09795
09796 #ifdef use_namespace
09797 }
09798 #endif
09799
09803
09806
09807
09808
09809
09810 #define WANT_FSTREAM
09811
09812 #ifdef use_namespace
09813 namespace NEWMAT {
09814 #endif
09815
09816
09817
09818 #ifdef DO_REPORT
09819 #define REPORT { static ExeCounter ExeCount(__LINE__,9); ++ExeCount; }
09820 #else
09821 #define REPORT {}
09822 #endif
09823
09824
09825 #ifndef ios_format_flags
09826 #define ios_format_flags long
09827 #endif
09828
09829 ostream& operator<<(ostream& s, const BaseMatrix& X)
09830 {
09831 GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate(); operator<<(s, *gm);
09832 gm->tDelete(); return s;
09833 }
09834
09835
09836 ostream& operator<<(ostream& s, const GeneralMatrix& X)
09837 {
09838 MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
09839 int w = s.width(); int nr = X.Nrows(); ios_format_flags f = s.flags();
09840 s.setf(ios::fixed, ios::floatfield);
09841 for (int i=1; i<=nr; i++)
09842 {
09843 int skip = mr.skip; int storage = mr.storage;
09844 Real* store = mr.data; skip *= w+1;
09845 while (skip--) s << " ";
09846 while (storage--) { s.width(w); s << *store++ << " "; }
09847
09848 mr.Next(); s << "\n";
09849 }
09850 s << flush; s.flags(f); return s;
09851 }
09852
09853
09854
09855
09856
09857
09858
09859
09860
09861
09862
09863
09864
09865
09866
09867
09868
09869
09870 static void tred2(const SymmetricMatrix& A, DiagonalMatrix& D,
09871 DiagonalMatrix& E, Matrix& Z)
09872 {
09873 Tracer et("Evalue(tred2)");
09874 REPORT
09875 Real tol =
09876 FloatingPointPrecision::Minimum()/FloatingPointPrecision::Epsilon();
09877 int n = A.Nrows(); Z.resize(n,n); Z.Inject(A);
09878 D.resize(n); E.resize(n);
09879 Real* z = Z.Store(); int i;
09880
09881 for (i=n-1; i > 0; i--)
09882 {
09883 Real f = Z.element(i,i-1); Real g = 0.0;
09884 int k = i-1; Real* zik = z + i*n;
09885 while (k--) g += square(*zik++);
09886 Real h = g + square(f);
09887 if (g <= tol) { REPORT E.element(i) = f; h = 0.0; }
09888 else
09889 {
09890 REPORT
09891 g = sign(-sqrt(h), f); E.element(i) = g; h -= f*g;
09892 Z.element(i,i-1) = f-g; f = 0.0;
09893 Real* zji = z + i; Real* zij = z + i*n; Real* ej = E.Store();
09894 int j;
09895 for (j=0; j<i; j++)
09896 {
09897 *zji = (*zij++)/h; g = 0.0;
09898 Real* zjk = z + j*n; zik = z + i*n;
09899 k = j; while (k--) g += *zjk++ * (*zik++);
09900 k = i-j;
09901 if (k) for(;;)
09902 { g += *zjk * (*zik++); if (!(--k)) break; zjk += n; }
09903 *ej++ = g/h; f += g * (*zji); zji += n;
09904 }
09905 Real hh = f / (h + h); zij = z + i*n; ej = E.Store();
09906 for (j=0; j<i; j++)
09907 {
09908 f = *zij++; g = *ej - hh * f; *ej++ = g;
09909 Real* zjk = z + j*n; Real* zik = z + i*n;
09910 Real* ek = E.Store(); k = j+1;
09911 while (k--) *zjk++ -= ( f*(*ek++) + g*(*zik++) );
09912 }
09913 }
09914 D.element(i) = h;
09915 }
09916
09917 D.element(0) = 0.0; E.element(0) = 0.0;
09918 for (i=0; i<n; i++)
09919 {
09920 if (D.element(i) != 0.0)
09921 {
09922 REPORT
09923 for (int j=0; j<i; j++)
09924 {
09925 Real g = 0.0;
09926 Real* zik = z + i*n; Real* zkj = z + j;
09927 int k = i;
09928 if (k) for (;;)
09929 { g += *zik++ * (*zkj); if (!(--k)) break; zkj += n; }
09930 Real* zki = z + i; zkj = z + j;
09931 k = i;
09932 if (k) for (;;)
09933 { *zkj -= g * (*zki); if (!(--k)) break; zkj += n; zki += n; }
09934 }
09935 }
09936 Real* zij = z + i*n; Real* zji = z + i;
09937 int j = i;
09938 if (j) for (;;)
09939 { *zij++ = 0.0; *zji = 0.0; if (!(--j)) break; zji += n; }
09940 D.element(i) = *zij; *zij = 1.0;
09941 }
09942 }
09943
09944 static void tql2(DiagonalMatrix& D, DiagonalMatrix& E, Matrix& Z)
09945 {
09946 Tracer et("Evalue(tql2)");
09947 REPORT
09948 Real eps = FloatingPointPrecision::Epsilon();
09949 int n = D.Nrows(); Real* z = Z.Store(); int l;
09950 for (l=1; l<n; l++) E.element(l-1) = E.element(l);
09951 Real b = 0.0; Real f = 0.0; E.element(n-1) = 0.0;
09952 for (l=0; l<n; l++)
09953 {
09954 int i,j;
09955 Real& dl = D.element(l); Real& el = E.element(l);
09956 Real h = eps * ( fabs(dl) + fabs(el) );
09957 if (b < h) { REPORT b = h; }
09958 int m;
09959 for (m=l; m<n; m++) if (fabs(E.element(m)) <= b) break;
09960 bool test = false;
09961 for (j=0; j<30; j++)
09962 {
09963 if (m==l) { REPORT test = true; break; }
09964 Real& dl1 = D.element(l+1);
09965 Real g = dl; Real p = (dl1-g) / (2.0*el); Real r = sqrt(p*p + 1.0);
09966 dl = el / (p < 0.0 ? p-r : p+r); Real h = g - dl; f += h;
09967 Real* dlx = &dl1; i = n-l-1; while (i--) *dlx++ -= h;
09968
09969 p = D.element(m); Real c = 1.0; Real s = 0.0;
09970 for (i=m-1; i>=l; i--)
09971 {
09972 Real ei = E.element(i); Real di = D.element(i);
09973 Real& ei1 = E.element(i+1);
09974 g = c * ei; h = c * p;
09975 if ( fabs(p) >= fabs(ei))
09976 {
09977 REPORT
09978 c = ei / p; r = sqrt(c*c + 1.0);
09979 ei1 = s*p*r; s = c/r; c = 1.0/r;
09980 }
09981 else
09982 {
09983 REPORT
09984 c = p / ei; r = sqrt(c*c + 1.0);
09985 ei1 = s * ei * r; s = 1.0/r; c /= r;
09986 }
09987 p = c * di - s*g; D.element(i+1) = h + s * (c*g + s*di);
09988
09989 Real* zki = z + i; Real* zki1 = zki + 1; int k = n;
09990 if (k) for (;;)
09991 {
09992 REPORT
09993 h = *zki1; *zki1 = s*(*zki) + c*h; *zki = c*(*zki) - s*h;
09994 if (!(--k)) break;
09995 zki += n; zki1 += n;
09996 }
09997 }
09998 el = s*p; dl = c*p;
09999 if (fabs(el) <= b) { REPORT; test = true; break; }
10000 }
10001 if (!test) Throw ( ConvergenceException(D) );
10002 dl += f;
10003 }
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023 }
10024
10025 static void tred3(const SymmetricMatrix& X, DiagonalMatrix& D,
10026 DiagonalMatrix& E, SymmetricMatrix& A)
10027 {
10028 Tracer et("Evalue(tred3)");
10029 REPORT
10030 Real tol =
10031 FloatingPointPrecision::Minimum()/FloatingPointPrecision::Epsilon();
10032 int n = X.Nrows(); A = X; D.resize(n); E.resize(n);
10033 Real* ei = E.Store() + n;
10034 for (int i = n-1; i >= 0; i--)
10035 {
10036 Real h = 0.0; Real f = - FloatingPointPrecision::Maximum();
10037 Real* d = D.Store(); Real* a = A.Store() + (i*(i+1))/2; int k = i;
10038 while (k--) { f = *a++; *d++ = f; h += square(f); }
10039 if (h <= tol) { REPORT *(--ei) = 0.0; h = 0.0; }
10040 else
10041 {
10042 REPORT
10043 Real g = sign(-sqrt(h), f); *(--ei) = g; h -= f*g;
10044 f -= g; *(d-1) = f; *(a-1) = f; f = 0.0;
10045 Real* dj = D.Store(); Real* ej = E.Store(); int j;
10046 for (j = 0; j < i; j++)
10047 {
10048 Real* dk = D.Store(); Real* ak = A.Store()+(j*(j+1))/2;
10049 Real g = 0.0; k = j;
10050 while (k--) g += *ak++ * *dk++;
10051 k = i-j; int l = j;
10052 if (k) for (;;) { g += *ak * *dk++; if (!(--k)) break; ak += ++l; }
10053 g /= h; *ej++ = g; f += g * *dj++;
10054 }
10055 Real hh = f / (2 * h); Real* ak = A.Store();
10056 dj = D.Store(); ej = E.Store();
10057 for (j = 0; j < i; j++)
10058 {
10059 f = *dj++; g = *ej - hh * f; *ej++ = g;
10060 Real* dk = D.Store(); Real* ek = E.Store(); k = j+1;
10061 while (k--) { *ak++ -= (f * *ek++ + g * *dk++); }
10062 }
10063 }
10064 *d = *a; *a = h;
10065 }
10066 }
10067
10068 static void tql1(DiagonalMatrix& D, DiagonalMatrix& E)
10069 {
10070 Tracer et("Evalue(tql1)");
10071 REPORT
10072 Real eps = FloatingPointPrecision::Epsilon();
10073 int n = D.Nrows(); int l;
10074 for (l=1; l<n; l++) E.element(l-1) = E.element(l);
10075 Real b = 0.0; Real f = 0.0; E.element(n-1) = 0.0;
10076 for (l=0; l<n; l++)
10077 {
10078 int i,j;
10079 Real& dl = D.element(l); Real& el = E.element(l);
10080 Real h = eps * ( fabs(dl) + fabs(el) );
10081 if (b < h) b = h;
10082 int m;
10083 for (m=l; m<n; m++) if (fabs(E.element(m)) <= b) break;
10084 bool test = false;
10085 for (j=0; j<30; j++)
10086 {
10087 if (m==l) { REPORT test = true; break; }
10088 Real& dl1 = D.element(l+1);
10089 Real g = dl; Real p = (dl1-g) / (2.0*el); Real r = sqrt(p*p + 1.0);
10090 dl = el / (p < 0.0 ? p-r : p+r); Real h = g - dl; f += h;
10091 Real* dlx = &dl1; i = n-l-1; while (i--) *dlx++ -= h;
10092
10093 p = D.element(m); Real c = 1.0; Real s = 0.0;
10094 for (i=m-1; i>=l; i--)
10095 {
10096 Real ei = E.element(i); Real di = D.element(i);
10097 Real& ei1 = E.element(i+1);
10098 g = c * ei; h = c * p;
10099 if ( fabs(p) >= fabs(ei))
10100 {
10101 REPORT
10102 c = ei / p; r = sqrt(c*c + 1.0);
10103 ei1 = s*p*r; s = c/r; c = 1.0/r;
10104 }
10105 else
10106 {
10107 REPORT
10108 c = p / ei; r = sqrt(c*c + 1.0);
10109 ei1 = s * ei * r; s = 1.0/r; c /= r;
10110 }
10111 p = c * di - s*g; D.element(i+1) = h + s * (c*g + s*di);
10112 }
10113 el = s*p; dl = c*p;
10114 if (fabs(el) <= b) { REPORT test = true; break; }
10115 }
10116 if (!test) Throw ( ConvergenceException(D) );
10117 Real p = dl + f;
10118 test = false;
10119 for (i=l; i>0; i--)
10120 {
10121 if (p < D.element(i-1)) { REPORT D.element(i) = D.element(i-1); }
10122 else { REPORT test = true; break; }
10123 }
10124 if (!test) i=0;
10125 D.element(i) = p;
10126 }
10127 }
10128
10129 void eigenvalues(const SymmetricMatrix& A, DiagonalMatrix& D, Matrix& Z)
10130 { REPORT DiagonalMatrix E; tred2(A, D, E, Z); tql2(D, E, Z); SortSV(D,Z,true); }
10131
10132 void eigenvalues(const SymmetricMatrix& X, DiagonalMatrix& D)
10133 { REPORT DiagonalMatrix E; SymmetricMatrix A; tred3(X,D,E,A); tql1(D,E); }
10134
10135 void eigenvalues(const SymmetricMatrix& X, DiagonalMatrix& D,
10136 SymmetricMatrix& A)
10137 { REPORT DiagonalMatrix E; tred3(X,D,E,A); tql1(D,E); }
10138
10139
10140
10141 #ifdef use_namespace
10142 }
10143 #endif
10144
10145