00001
00002
00003
00004
00005 #define WANT_MATH
00006
00007 #include "include.h"
00008
00009 #include "newmat.h"
00010 #include "newmatrc.h"
00011 #include "precisio.h"
00012
00013 #ifdef use_namespace
00014 namespace NEWMAT {
00015 #endif
00016
00017
00018 #ifdef DO_REPORT
00019 #define REPORT { static ExeCounter ExeCount(__LINE__,8); ++ExeCount; }
00020 #else
00021 #define REPORT {}
00022 #endif
00023
00024
00025
00026
00027 void CroutMatrix::ludcmp()
00028
00029
00030
00031
00032
00033 {
00034 REPORT
00035 Tracer trace( "Crout(ludcmp)" ); sing = false;
00036 Real* akk = store;
00037
00038 Real big = fabs(*akk); int mu = 0; Real* ai = akk; int k;
00039
00040 for (k = 1; k < nrows_value; k++)
00041 {
00042 ai += nrows_value; const Real trybig = fabs(*ai);
00043 if (big < trybig) { big = trybig; mu = k; }
00044 }
00045
00046
00047 if (nrows_value) for (k = 0;;)
00048 {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 indx[k] = mu;
00064
00065 if (mu != k)
00066 {
00067 Real* a1 = store + nrows_value * k;
00068 Real* a2 = store + nrows_value * mu; d = !d;
00069 int j = nrows_value;
00070 while (j--) { const Real temp = *a1; *a1++ = *a2; *a2++ = temp; }
00071 }
00072
00073 Real diag = *akk; big = 0; mu = k + 1;
00074 if (diag != 0)
00075 {
00076 ai = akk; int i = nrows_value - k - 1;
00077 while (i--)
00078 {
00079 ai += nrows_value; Real* al = ai;
00080 Real mult = *al / diag; *al = mult;
00081 int l = nrows_value - k - 1; Real* aj = akk;
00082
00083
00084 if (l-- != 0)
00085 {
00086 *(++al) -= (mult * *(++aj));
00087 const Real trybig = fabs(*al);
00088 if (big < trybig) { big = trybig; mu = nrows_value - i - 1; }
00089 while (l--) *(++al) -= (mult * *(++aj));
00090 }
00091 }
00092 }
00093 else sing = true;
00094 if (++k == nrows_value) break;
00095 akk += nrows_value + 1;
00096 }
00097 }
00098
00099 void CroutMatrix::lubksb(Real* B, int mini)
00100 {
00101 REPORT
00102
00103
00104
00105
00106
00107
00108 Tracer trace("Crout(lubksb)");
00109 if (sing) Throw(SingularException(*this));
00110 int i, j, ii = nrows_value;
00111
00112
00113
00114 for (i = 0; i < nrows_value; i++)
00115 {
00116 int ip = indx[i]; Real temp = B[ip]; B[ip] = B[i]; B[i] = temp;
00117 if (temp != 0.0) { ii = i; break; }
00118 }
00119
00120 Real* bi; Real* ai;
00121 i = ii + 1;
00122
00123 if (i < nrows_value)
00124 {
00125 bi = B + ii; ai = store + ii + i * nrows_value;
00126 for (;;)
00127 {
00128 int ip = indx[i]; Real sum = B[ip]; B[ip] = B[i];
00129 Real* aij = ai; Real* bj = bi; j = i - ii;
00130 while (j--) sum -= *aij++ * *bj++;
00131 B[i] = sum;
00132 if (++i == nrows_value) break;
00133 ai += nrows_value;
00134 }
00135 }
00136
00137 ai = store + nrows_value * nrows_value;
00138
00139 for (i = nrows_value - 1; i >= mini; i--)
00140 {
00141 Real* bj = B+i; ai -= nrows_value; Real* ajx = ai+i;
00142 Real sum = *bj; Real diag = *ajx;
00143 j = nrows_value - i; while(--j) sum -= *(++ajx) * *(++bj);
00144 B[i] = sum / diag;
00145 }
00146 }
00147
00148
00149
00150 inline Real square(Real x) { return x*x; }
00151
00152 Real GeneralMatrix::SumSquare() const
00153 {
00154 REPORT
00155 Real sum = 0.0; int i = storage; Real* s = store;
00156 while (i--) sum += square(*s++);
00157 ((GeneralMatrix&)*this).tDelete(); return sum;
00158 }
00159
00160 Real GeneralMatrix::SumAbsoluteValue() const
00161 {
00162 REPORT
00163 Real sum = 0.0; int i = storage; Real* s = store;
00164 while (i--) sum += fabs(*s++);
00165 ((GeneralMatrix&)*this).tDelete(); return sum;
00166 }
00167
00168 Real GeneralMatrix::Sum() const
00169 {
00170 REPORT
00171 Real sum = 0.0; int i = storage; Real* s = store;
00172 while (i--) sum += *s++;
00173 ((GeneralMatrix&)*this).tDelete(); return sum;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 static void NullMatrixError(const GeneralMatrix* gm)
00209 {
00210 ((GeneralMatrix&)*gm).tDelete();
00211 Throw(ProgramException("Maximum or minimum of null matrix"));
00212 }
00213
00214 Real GeneralMatrix::MaximumAbsoluteValue() const
00215 {
00216 REPORT
00217 if (storage == 0) NullMatrixError(this);
00218 Real maxval = 0.0; int l = storage; Real* s = store;
00219 while (l--) { Real a = fabs(*s++); if (maxval < a) maxval = a; }
00220 ((GeneralMatrix&)*this).tDelete(); return maxval;
00221 }
00222
00223 Real GeneralMatrix::MaximumAbsoluteValue1(int& i) const
00224 {
00225 REPORT
00226 if (storage == 0) NullMatrixError(this);
00227 Real maxval = 0.0; int l = storage; Real* s = store; int li = storage;
00228 while (l--)
00229 { Real a = fabs(*s++); if (maxval <= a) { maxval = a; li = l; } }
00230 i = storage - li;
00231 ((GeneralMatrix&)*this).tDelete(); return maxval;
00232 }
00233
00234 Real GeneralMatrix::MinimumAbsoluteValue() const
00235 {
00236 REPORT
00237 if (storage == 0) NullMatrixError(this);
00238 int l = storage - 1; Real* s = store; Real minval = fabs(*s++);
00239 while (l--) { Real a = fabs(*s++); if (minval > a) minval = a; }
00240 ((GeneralMatrix&)*this).tDelete(); return minval;
00241 }
00242
00243 Real GeneralMatrix::MinimumAbsoluteValue1(int& i) const
00244 {
00245 REPORT
00246 if (storage == 0) NullMatrixError(this);
00247 int l = storage - 1; Real* s = store; Real minval = fabs(*s++); int li = l;
00248 while (l--)
00249 { Real a = fabs(*s++); if (minval >= a) { minval = a; li = l; } }
00250 i = storage - li;
00251 ((GeneralMatrix&)*this).tDelete(); return minval;
00252 }
00253
00254 Real GeneralMatrix::Maximum() const
00255 {
00256 REPORT
00257 if (storage == 0) NullMatrixError(this);
00258 int l = storage - 1; Real* s = store; Real maxval = *s++;
00259 while (l--) { Real a = *s++; if (maxval < a) maxval = a; }
00260 ((GeneralMatrix&)*this).tDelete(); return maxval;
00261 }
00262
00263 Real GeneralMatrix::Maximum1(int& i) const
00264 {
00265 REPORT
00266 if (storage == 0) NullMatrixError(this);
00267 int l = storage - 1; Real* s = store; Real maxval = *s++; int li = l;
00268 while (l--) { Real a = *s++; if (maxval <= a) { maxval = a; li = l; } }
00269 i = storage - li;
00270 ((GeneralMatrix&)*this).tDelete(); return maxval;
00271 }
00272
00273 Real GeneralMatrix::Minimum() const
00274 {
00275 REPORT
00276 if (storage == 0) NullMatrixError(this);
00277 int l = storage - 1; Real* s = store; Real minval = *s++;
00278 while (l--) { Real a = *s++; if (minval > a) minval = a; }
00279 ((GeneralMatrix&)*this).tDelete(); return minval;
00280 }
00281
00282 Real GeneralMatrix::Minimum1(int& i) const
00283 {
00284 REPORT
00285 if (storage == 0) NullMatrixError(this);
00286 int l = storage - 1; Real* s = store; Real minval = *s++; int li = l;
00287 while (l--) { Real a = *s++; if (minval >= a) { minval = a; li = l; } }
00288 i = storage - li;
00289 ((GeneralMatrix&)*this).tDelete(); return minval;
00290 }
00291
00292 Real GeneralMatrix::MaximumAbsoluteValue2(int& i, int& j) const
00293 {
00294 REPORT
00295 if (storage == 0) NullMatrixError(this);
00296 Real maxval = 0.0; int nr = Nrows();
00297 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
00298 for (int r = 1; r <= nr; r++)
00299 {
00300 int c; maxval = mr.MaximumAbsoluteValue1(maxval, c);
00301 if (c > 0) { i = r; j = c; }
00302 mr.Next();
00303 }
00304 ((GeneralMatrix&)*this).tDelete(); return maxval;
00305 }
00306
00307 Real GeneralMatrix::MinimumAbsoluteValue2(int& i, int& j) const
00308 {
00309 REPORT
00310 if (storage == 0) NullMatrixError(this);
00311 Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
00312 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
00313 for (int r = 1; r <= nr; r++)
00314 {
00315 int c; minval = mr.MinimumAbsoluteValue1(minval, c);
00316 if (c > 0) { i = r; j = c; }
00317 mr.Next();
00318 }
00319 ((GeneralMatrix&)*this).tDelete(); return minval;
00320 }
00321
00322 Real GeneralMatrix::Maximum2(int& i, int& j) const
00323 {
00324 REPORT
00325 if (storage == 0) NullMatrixError(this);
00326 Real maxval = -FloatingPointPrecision::Maximum(); int nr = Nrows();
00327 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
00328 for (int r = 1; r <= nr; r++)
00329 {
00330 int c; maxval = mr.Maximum1(maxval, c);
00331 if (c > 0) { i = r; j = c; }
00332 mr.Next();
00333 }
00334 ((GeneralMatrix&)*this).tDelete(); return maxval;
00335 }
00336
00337 Real GeneralMatrix::Minimum2(int& i, int& j) const
00338 {
00339 REPORT
00340 if (storage == 0) NullMatrixError(this);
00341 Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
00342 MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
00343 for (int r = 1; r <= nr; r++)
00344 {
00345 int c; minval = mr.Minimum1(minval, c);
00346 if (c > 0) { i = r; j = c; }
00347 mr.Next();
00348 }
00349 ((GeneralMatrix&)*this).tDelete(); return minval;
00350 }
00351
00352 Real Matrix::MaximumAbsoluteValue2(int& i, int& j) const
00353 {
00354 REPORT
00355 int k; Real m = GeneralMatrix::MaximumAbsoluteValue1(k); k--;
00356 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
00357 return m;
00358 }
00359
00360 Real Matrix::MinimumAbsoluteValue2(int& i, int& j) const
00361 {
00362 REPORT
00363 int k; Real m = GeneralMatrix::MinimumAbsoluteValue1(k); k--;
00364 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
00365 return m;
00366 }
00367
00368 Real Matrix::Maximum2(int& i, int& j) const
00369 {
00370 REPORT
00371 int k; Real m = GeneralMatrix::Maximum1(k); k--;
00372 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
00373 return m;
00374 }
00375
00376 Real Matrix::Minimum2(int& i, int& j) const
00377 {
00378 REPORT
00379 int k; Real m = GeneralMatrix::Minimum1(k); k--;
00380 i = k / Ncols(); j = k - i * Ncols(); i++; j++;
00381 return m;
00382 }
00383
00384 Real SymmetricMatrix::SumSquare() const
00385 {
00386 REPORT
00387 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_value;
00388 for (int i = 0; i<nr; i++)
00389 {
00390 int j = i;
00391 while (j--) sum2 += square(*s++);
00392 sum1 += square(*s++);
00393 }
00394 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00395 }
00396
00397 Real SymmetricMatrix::SumAbsoluteValue() const
00398 {
00399 REPORT
00400 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_value;
00401 for (int i = 0; i<nr; i++)
00402 {
00403 int j = i;
00404 while (j--) sum2 += fabs(*s++);
00405 sum1 += fabs(*s++);
00406 }
00407 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00408 }
00409
00410 Real IdentityMatrix::SumAbsoluteValue() const
00411 { REPORT return fabs(Trace()); }
00412
00413 Real SymmetricMatrix::Sum() const
00414 {
00415 REPORT
00416 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows_value;
00417 for (int i = 0; i<nr; i++)
00418 {
00419 int j = i;
00420 while (j--) sum2 += *s++;
00421 sum1 += *s++;
00422 }
00423 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00424 }
00425
00426 Real IdentityMatrix::SumSquare() const
00427 {
00428 Real sum = *store * *store * nrows_value;
00429 ((GeneralMatrix&)*this).tDelete(); return sum;
00430 }
00431
00432
00433 Real BaseMatrix::SumSquare() const
00434 {
00435 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00436 Real s = gm->SumSquare(); return s;
00437 }
00438
00439 Real BaseMatrix::NormFrobenius() const
00440 { REPORT return sqrt(SumSquare()); }
00441
00442 Real BaseMatrix::SumAbsoluteValue() const
00443 {
00444 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00445 Real s = gm->SumAbsoluteValue(); return s;
00446 }
00447
00448 Real BaseMatrix::Sum() const
00449 {
00450 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00451 Real s = gm->Sum(); return s;
00452 }
00453
00454 Real BaseMatrix::MaximumAbsoluteValue() const
00455 {
00456 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00457 Real s = gm->MaximumAbsoluteValue(); return s;
00458 }
00459
00460 Real BaseMatrix::MaximumAbsoluteValue1(int& i) const
00461 {
00462 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00463 Real s = gm->MaximumAbsoluteValue1(i); return s;
00464 }
00465
00466 Real BaseMatrix::MaximumAbsoluteValue2(int& i, int& j) const
00467 {
00468 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00469 Real s = gm->MaximumAbsoluteValue2(i, j); return s;
00470 }
00471
00472 Real BaseMatrix::MinimumAbsoluteValue() const
00473 {
00474 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00475 Real s = gm->MinimumAbsoluteValue(); return s;
00476 }
00477
00478 Real BaseMatrix::MinimumAbsoluteValue1(int& i) const
00479 {
00480 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00481 Real s = gm->MinimumAbsoluteValue1(i); return s;
00482 }
00483
00484 Real BaseMatrix::MinimumAbsoluteValue2(int& i, int& j) const
00485 {
00486 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00487 Real s = gm->MinimumAbsoluteValue2(i, j); return s;
00488 }
00489
00490 Real BaseMatrix::Maximum() const
00491 {
00492 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00493 Real s = gm->Maximum(); return s;
00494 }
00495
00496 Real BaseMatrix::Maximum1(int& i) const
00497 {
00498 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00499 Real s = gm->Maximum1(i); return s;
00500 }
00501
00502 Real BaseMatrix::Maximum2(int& i, int& j) const
00503 {
00504 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00505 Real s = gm->Maximum2(i, j); return s;
00506 }
00507
00508 Real BaseMatrix::Minimum() const
00509 {
00510 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00511 Real s = gm->Minimum(); return s;
00512 }
00513
00514 Real BaseMatrix::Minimum1(int& i) const
00515 {
00516 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00517 Real s = gm->Minimum1(i); return s;
00518 }
00519
00520 Real BaseMatrix::Minimum2(int& i, int& j) const
00521 {
00522 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00523 Real s = gm->Minimum2(i, j); return s;
00524 }
00525
00526 Real DotProduct(const Matrix& A, const Matrix& B)
00527 {
00528 REPORT
00529 int n = A.storage;
00530 if (n != B.storage) Throw(IncompatibleDimensionsException(A,B));
00531 Real sum = 0.0; Real* a = A.store; Real* b = B.store;
00532 while (n--) sum += *a++ * *b++;
00533 return sum;
00534 }
00535
00536 Real Matrix::Trace() const
00537 {
00538 REPORT
00539 Tracer trace("Trace");
00540 int i = nrows_value; int d = i+1;
00541 if (i != ncols_value) Throw(NotSquareException(*this));
00542 Real sum = 0.0; Real* s = store;
00543
00544 if (i) for (;;) { sum += *s; if (!(--i)) break; s += d; }
00545 ((GeneralMatrix&)*this).tDelete(); return sum;
00546 }
00547
00548 Real DiagonalMatrix::Trace() const
00549 {
00550 REPORT
00551 int i = nrows_value; Real sum = 0.0; Real* s = store;
00552 while (i--) sum += *s++;
00553 ((GeneralMatrix&)*this).tDelete(); return sum;
00554 }
00555
00556 Real SymmetricMatrix::Trace() const
00557 {
00558 REPORT
00559 int i = nrows_value; Real sum = 0.0; Real* s = store; int j = 2;
00560
00561 if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
00562 ((GeneralMatrix&)*this).tDelete(); return sum;
00563 }
00564
00565 Real LowerTriangularMatrix::Trace() const
00566 {
00567 REPORT
00568 int i = nrows_value; Real sum = 0.0; Real* s = store; int j = 2;
00569
00570 if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
00571 ((GeneralMatrix&)*this).tDelete(); return sum;
00572 }
00573
00574 Real UpperTriangularMatrix::Trace() const
00575 {
00576 REPORT
00577 int i = nrows_value; Real sum = 0.0; Real* s = store;
00578 while (i) { sum += *s; s += i--; }
00579 ((GeneralMatrix&)*this).tDelete(); return sum;
00580 }
00581
00582 Real BandMatrix::Trace() const
00583 {
00584 REPORT
00585 int i = nrows_value; int w = lower+upper+1;
00586 Real sum = 0.0; Real* s = store+lower;
00587
00588 if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
00589 ((GeneralMatrix&)*this).tDelete(); return sum;
00590 }
00591
00592 Real SymmetricBandMatrix::Trace() const
00593 {
00594 REPORT
00595 int i = nrows_value; int w = lower+1;
00596 Real sum = 0.0; Real* s = store+lower;
00597
00598 if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
00599 ((GeneralMatrix&)*this).tDelete(); return sum;
00600 }
00601
00602 Real IdentityMatrix::Trace() const
00603 {
00604 Real sum = *store * nrows_value;
00605 ((GeneralMatrix&)*this).tDelete(); return sum;
00606 }
00607
00608
00609 Real BaseMatrix::Trace() const
00610 {
00611 REPORT
00612 MatrixType Diag = MatrixType::Dg; Diag.SetDataLossOK();
00613 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(Diag);
00614 Real sum = gm->Trace(); return sum;
00615 }
00616
00617 void LogAndSign::operator*=(Real x)
00618 {
00619 if (x > 0.0) { log_value += log(x); }
00620 else if (x < 0.0) { log_value += log(-x); sign = -sign; }
00621 else sign = 0;
00622 }
00623
00624 void LogAndSign::PowEq(int k)
00625 {
00626 if (sign)
00627 {
00628 log_value *= k;
00629 if ( (k & 1) == 0 ) sign = 1;
00630 }
00631 }
00632
00633 Real LogAndSign::Value() const
00634 {
00635 Tracer et("LogAndSign::Value");
00636 if (log_value >= FloatingPointPrecision::LnMaximum())
00637 Throw(OverflowException("Overflow in exponential"));
00638 return sign * exp(log_value);
00639 }
00640
00641 LogAndSign::LogAndSign(Real f)
00642 {
00643 if (f == 0.0) { log_value = 0.0; sign = 0; return; }
00644 else if (f < 0.0) { sign = -1; f = -f; }
00645 else sign = 1;
00646 log_value = log(f);
00647 }
00648
00649 LogAndSign DiagonalMatrix::LogDeterminant() const
00650 {
00651 REPORT
00652 int i = nrows_value; LogAndSign sum; Real* s = store;
00653 while (i--) sum *= *s++;
00654 ((GeneralMatrix&)*this).tDelete(); return sum;
00655 }
00656
00657 LogAndSign LowerTriangularMatrix::LogDeterminant() const
00658 {
00659 REPORT
00660 int i = nrows_value; LogAndSign sum; Real* s = store; int j = 2;
00661
00662 if (i) for(;;) { sum *= *s; if (!(--i)) break; s += j++; }
00663 ((GeneralMatrix&)*this).tDelete(); return sum;
00664 }
00665
00666 LogAndSign UpperTriangularMatrix::LogDeterminant() const
00667 {
00668 REPORT
00669 int i = nrows_value; LogAndSign sum; Real* s = store;
00670 while (i) { sum *= *s; s += i--; }
00671 ((GeneralMatrix&)*this).tDelete(); return sum;
00672 }
00673
00674 LogAndSign IdentityMatrix::LogDeterminant() const
00675 {
00676 REPORT
00677 int i = nrows_value; LogAndSign sum;
00678 if (i > 0) { sum = *store; sum.PowEq(i); }
00679 ((GeneralMatrix&)*this).tDelete(); return sum;
00680 }
00681
00682 LogAndSign BaseMatrix::LogDeterminant() const
00683 {
00684 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00685 LogAndSign sum = gm->LogDeterminant(); return sum;
00686 }
00687
00688 LogAndSign GeneralMatrix::LogDeterminant() const
00689 {
00690 REPORT
00691 Tracer tr("LogDeterminant");
00692 if (nrows_value != ncols_value) Throw(NotSquareException(*this));
00693 CroutMatrix C(*this); return C.LogDeterminant();
00694 }
00695
00696 LogAndSign CroutMatrix::LogDeterminant() const
00697 {
00698 REPORT
00699 if (sing) return 0.0;
00700 int i = nrows_value; int dd = i+1; LogAndSign sum; Real* s = store;
00701 if (i) for(;;)
00702 {
00703 sum *= *s;
00704 if (!(--i)) break;
00705 s += dd;
00706 }
00707 if (!d) sum.ChangeSign(); return sum;
00708
00709 }
00710
00711 Real BaseMatrix::Determinant() const
00712 {
00713 REPORT
00714 Tracer tr("Determinant");
00715 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00716 LogAndSign ld = gm->LogDeterminant();
00717 return ld.Value();
00718 }
00719
00720
00721
00722
00723
00724 LinearEquationSolver::LinearEquationSolver(const BaseMatrix& bm)
00725 : gm( ( ((BaseMatrix&)bm).Evaluate() )->MakeSolver() )
00726 {
00727 if (gm==&bm) { REPORT gm = gm->Image(); }
00728
00729 else { REPORT gm->Protect(); }
00730 }
00731
00732
00733 #ifdef use_namespace
00734 }
00735 #endif
00736