newmat8.cc
Go to the documentation of this file.
00001 //$$ newmat8.cpp         Advanced LU transform, scalar functions
00002 
00003 // Copyright (C) 1991,2,3,4,8: R B Davies
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 /************************** LU transformation ****************************/
00026 
00027 void CroutMatrix::ludcmp()
00028 // LU decomposition from Golub & Van Loan, algorithm 3.4.1, (the "outer
00029 // product" version).
00030 // This replaces the code derived from Numerical Recipes in C in previous
00031 // versions of newmat and being row oriented runs much faster with large
00032 // matrices.
00033 {
00034    REPORT
00035    Tracer trace( "Crout(ludcmp)" ); sing = false;
00036    Real* akk = store;                    // runs down diagonal
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       int mu1;
00051       {
00052          Real big = fabs(*akk); mu1 = k; Real* ai = akk; int i;
00053 
00054          for (i = k+1; i < nrows; i++)
00055          {
00056             ai += nrows; const Real trybig = fabs(*ai);
00057             if (big < trybig) { big = trybig; mu1 = i; }
00058          }
00059       }
00060       if (mu1 != mu) cout << k << " " << mu << " " << mu1 << endl;
00061       */
00062 
00063       indx[k] = mu;
00064 
00065       if (mu != k)                       //row swap
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             // work out the next pivot as part of this loop
00081             // this saves a column operation
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;          // so next line won't overflow
00093       akk += nrows + 1;
00094    }
00095 }
00096 
00097 void CroutMatrix::lubksb(Real* B, int mini)
00098 {
00099    REPORT
00100    // this has been adapted from Numerical Recipes in C. The code has been
00101    // substantially streamlined, so I do not think much of the original
00102    // copyright remains. However there is not much opportunity for
00103    // variation in the code, so it is still similar to the NR code.
00104    // I follow the NR code in skipping over initial zeros in the B vector.
00105 
00106    Tracer trace("Crout(lubksb)");
00107    if (sing) Throw(SingularException(*this));
00108    int i, j, ii = nrows;            // ii initialised : B might be all zeros
00109 
00110 
00111    // scan for first non-zero in B
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 /****************************** scalar functions ****************************/
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 // maxima and minima
00175 
00176 // There are three sets of routines
00177 // MaximumAbsoluteValue, MinimumAbsoluteValue, Maximum, Minimum
00178 // ... these find just the maxima and minima
00179 // MaximumAbsoluteValue1, MinimumAbsoluteValue1, Maximum1, Minimum1
00180 // ... these find the maxima and minima and their locations in a
00181 //     one dimensional object
00182 // MaximumAbsoluteValue2, MinimumAbsoluteValue2, Maximum2, Minimum2
00183 // ... these find the maxima and minima and their locations in a
00184 //     two dimensional object
00185 
00186 // If the matrix has no values throw an exception
00187 
00188 // If we do not want the location find the maximum or minimum on the
00189 // array stored by GeneralMatrix
00190 // This won't work for BandMatrices. We call ClearCorner for
00191 // MaximumAbsoluteValue but for the others use the AbsoluteMinimumValue2
00192 // version and discard the location.
00193 
00194 // For one dimensional objects, when we want the location of the
00195 // maximum or minimum, work with the array stored by GeneralMatrix
00196 
00197 // For two dimensional objects where we want the location of the maximum or
00198 // minimum proceed as follows:
00199 
00200 // For rectangular matrices use the array stored by GeneralMatrix and
00201 // deduce the location from the location in the GeneralMatrix
00202 
00203 // For other two dimensional matrices use the Matrix Row routine to find the
00204 // maximum or minimum for each row.
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()); }    // no need to do tDelete?
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 //   while (i--) { sum += *s; s += d; }
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    // while (i--) { sum += *s; s += j++; }
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    // while (i--) { sum += *s; s += j++; }
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--; }             // won t cause a problem
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    // while (i--) { sum += *s; s += w; }
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    // while (i--) { sum += *s; s += w; }
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    // while (i--) { sum *= *s; s += j++; }
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    // want a copy if  *gm is actually bm
00727    else { REPORT  gm->Protect(); }
00728 }
00729 
00730 
00731 #ifdef use_namespace
00732 }
00733 #endif
00734 


rl_agent
Author(s): Todd Hester
autogenerated on Thu Jun 6 2019 22:00:13