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