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