00001
00002
00003
00004
00005
00006 #define WANT_MATH
00007
00008 #include "include.h"
00009
00010 #include "newmatap.h"
00011 #include "precisio.h"
00012
00013 #ifdef use_namespace
00014 namespace NEWMAT {
00015 #endif
00016
00017 #ifdef DO_REPORT
00018 #define REPORT { static ExeCounter ExeCount(__LINE__,8); ++ExeCount; }
00019 #else
00020 #define REPORT {}
00021 #endif
00022
00023
00024
00025 void CroutMatrix::ludcmp() {
00026
00027
00028
00029
00030
00031 REPORT
00032 Tracer trace( "Crout(ludcmp)" ); sing = false;
00033 Real* akk = store;
00034
00035 Real big = fabs(*akk); int mu = 0; Real* ai = akk; int k;
00036
00037 for (k = 1; k < nrows; k++) {
00038 ai += nrows; const Real trybig = fabs(*ai);
00039 if (big < trybig) { big = trybig; mu = k; }
00040 }
00041
00042 for (k = 0; k < nrows; k++) {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 indx[k] = mu;
00058
00059 if (mu != k) {
00060 Real* a1 = store + nrows * k; Real* a2 = store + nrows * mu; d = !d;
00061 int j = nrows;
00062 while (j--) { const Real temp = *a1; *a1++ = *a2; *a2++ = temp; }
00063 }
00064
00065 Real diag = *akk; big = 0; mu = k + 1;
00066 if (diag != 0) {
00067 ai = akk; int i = nrows - k - 1;
00068 while (i--) {
00069 ai += nrows; Real* al = ai; Real mult = *al / diag; *al = mult;
00070 int l = nrows - k - 1; Real* aj = akk;
00071
00072
00073 if (l-- != 0) {
00074 *(++al) -= (mult * *(++aj));
00075 const Real trybig = fabs(*al);
00076 if (big < trybig) { big = trybig; mu = nrows - i - 1; }
00077 while (l--) *(++al) -= (mult * *(++aj));
00078 }
00079 }
00080 }
00081 else sing = true;
00082 akk += nrows + 1;
00083 }
00084 }
00085
00086 void CroutMatrix::lubksb(Real* B, int mini) {
00087 REPORT
00088
00089
00090
00091
00092
00093
00094 Tracer trace("Crout(lubksb)");
00095 if (sing) Throw(SingularException(*this));
00096 int i, j, ii;
00097
00098
00099 for (i = 0; i < nrows; i++) {
00100 int ip = indx[i]; Real temp = B[ip]; B[ip] = B[i]; B[i] = temp;
00101 if (temp != 0.0) { ii = i; break; }
00102 }
00103
00104 Real* bi = B + ii; Real* ai = store + ii + (ii + 1) * nrows;
00105
00106 for (i = ii + 1; i < nrows; i++) {
00107 int ip = indx[i]; Real sum = B[ip]; B[ip] = B[i];
00108 Real* aij = ai; Real* bj = bi; j = i - ii;
00109 while (j--) sum -= *aij++ * *bj++;
00110 B[i] = sum; ai += nrows;
00111 }
00112
00113 ai = store + nrows * nrows;
00114
00115 for (i = nrows - 1; i >= mini; i--) {
00116 Real* bj = B+i; ai -= nrows; Real* ajx = ai+i;
00117 Real sum = *bj; Real diag = *ajx;
00118 j = nrows - i; while(--j) sum -= *(++ajx) * *(++bj);
00119 B[i] = sum / diag;
00120 }
00121 }
00122
00123
00124
00125 inline Real square(Real x) { return x*x; }
00126
00127 Real GeneralMatrix::SumSquare() const {
00128 REPORT
00129 Real sum = 0.0; int i = storage; Real* s = store;
00130 while (i--) sum += square(*s++);
00131 ((GeneralMatrix&)*this).tDelete(); return sum;
00132 }
00133
00134 Real GeneralMatrix::SumAbsoluteValue() const {
00135 REPORT
00136 Real sum = 0.0; int i = storage; Real* s = store;
00137 while (i--) sum += fabs(*s++);
00138 ((GeneralMatrix&)*this).tDelete(); return sum;
00139 }
00140
00141 Real GeneralMatrix::Sum() const {
00142 REPORT
00143 Real sum = 0.0; int i = storage; Real* s = store;
00144 while (i--) sum += *s++;
00145 ((GeneralMatrix&)*this).tDelete(); return sum;
00146 }
00147
00148 Real GeneralMatrix::MaximumAbsoluteValue() const {
00149 REPORT
00150 Real maxval = 0.0; int i = storage; Real* s = store;
00151 while (i--) { Real a = fabs(*s++); if (maxval < a) maxval = a; }
00152 ((GeneralMatrix&)*this).tDelete(); return maxval;
00153 }
00154
00155 Real GeneralMatrix::MaximumValue() const {
00156 REPORT
00157 Real maxval = 0.0; int i = storage; Real* s = store;
00158 while (i--) { Real a = *s++; if (maxval < a) maxval = a; }
00159 ((GeneralMatrix&)*this).tDelete(); return maxval;
00160 }
00161
00162 Real GeneralMatrix::MinimumValue() const {
00163 REPORT
00164 Real minval = 0.0; int i = storage; Real* s = store;
00165 while (i--) { Real a = *s++; if (minval > a) minval = a; }
00166 ((GeneralMatrix&)*this).tDelete(); return minval;
00167 }
00168
00169 Real SymmetricMatrix::SumSquare() const {
00170 REPORT
00171 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
00172 for (int i = 0; i<nr; i++) {
00173 int j = i;
00174 while (j--) sum2 += square(*s++);
00175 sum1 += square(*s++);
00176 }
00177 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00178 }
00179
00180 Real SymmetricMatrix::SumAbsoluteValue() const {
00181 REPORT
00182 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
00183 for (int i = 0; i<nr; i++) {
00184 int j = i;
00185 while (j--) sum2 += fabs(*s++);
00186 sum1 += fabs(*s++);
00187 }
00188 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00189 }
00190
00191 Real SymmetricMatrix::Sum() const {
00192 REPORT
00193 Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
00194 for (int i = 0; i<nr; i++) {
00195 int j = i;
00196 while (j--) sum2 += *s++;
00197 sum1 += *s++;
00198 }
00199 ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
00200 }
00201
00202 Real BaseMatrix::SumSquare() const {
00203 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00204 Real s = gm->SumSquare(); return s;
00205 }
00206
00207 Real BaseMatrix::SumAbsoluteValue() const {
00208 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00209 Real s = gm->SumAbsoluteValue(); return s;
00210 }
00211
00212 Real BaseMatrix::Sum() const {
00213 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00214 Real s = gm->Sum(); return s;
00215 }
00216
00217 Real BaseMatrix::MaximumAbsoluteValue() const {
00218 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00219 Real s = gm->MaximumAbsoluteValue(); return s;
00220 }
00221
00222 Real BaseMatrix::MaximumValue() const {
00223 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00224 Real s = gm->MaximumValue(); return s;
00225 }
00226 Real BaseMatrix::MinimumValue() const {
00227 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00228 Real s = gm->MinimumValue(); return s;
00229 }
00230
00231 Real Matrix::Trace() const {
00232 REPORT
00233 Tracer trace("Trace");
00234 int i = nrows; int d = i+1;
00235 if (i != ncols) Throw(NotSquareException(*this));
00236 Real sum = 0.0; Real* s = store;
00237 while (i--) { sum += *s; s += d; }
00238 ((GeneralMatrix&)*this).tDelete(); return sum;
00239 }
00240
00241 Real DiagonalMatrix::Trace() const {
00242 REPORT
00243 int i = nrows; Real sum = 0.0; Real* s = store;
00244 while (i--) sum += *s++;
00245 ((GeneralMatrix&)*this).tDelete(); return sum;
00246 }
00247
00248 Real SymmetricMatrix::Trace() const {
00249 REPORT
00250 int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
00251 while (i--) { sum += *s; s += j++; }
00252 ((GeneralMatrix&)*this).tDelete(); return sum;
00253 }
00254
00255 Real LowerTriangularMatrix::Trace() const {
00256 REPORT
00257 int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
00258 while (i--) { sum += *s; s += j++; }
00259 ((GeneralMatrix&)*this).tDelete(); return sum;
00260 }
00261
00262 Real UpperTriangularMatrix::Trace() const {
00263 REPORT
00264 int i = nrows; Real sum = 0.0; Real* s = store;
00265 while (i) { sum += *s; s += i--; }
00266 ((GeneralMatrix&)*this).tDelete(); return sum;
00267 }
00268
00269 Real BandMatrix::Trace() const {
00270 REPORT
00271 int i = nrows; int w = lower+upper+1;
00272 Real sum = 0.0; Real* s = store+lower;
00273 while (i--) { sum += *s; s += w; }
00274 ((GeneralMatrix&)*this).tDelete(); return sum;
00275 }
00276
00277 Real SymmetricBandMatrix::Trace() const {
00278 REPORT
00279 int i = nrows; int w = lower+1;
00280 Real sum = 0.0; Real* s = store+lower;
00281 while (i--) { sum += *s; s += w; }
00282 ((GeneralMatrix&)*this).tDelete(); return sum;
00283 }
00284
00285 Real BaseMatrix::Trace() const {
00286 REPORT
00287 GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(MatrixType::Dg);
00288 Real sum = gm->Trace(); return sum;
00289 }
00290
00291 void LogAndSign::operator*=(Real x) {
00292 if (x > 0.0) { log_value += log(x); }
00293 else if (x < 0.0) { log_value += log(-x); sign = -sign; }
00294 else sign = 0;
00295 }
00296
00297 Real LogAndSign::Value() const {
00298 Tracer et("LogAndSign::Value");
00299 if (log_value >= FloatingPointPrecision::LnMaximum())
00300 Throw(OverflowException("Overflow in exponential"));
00301 return sign * exp(log_value);
00302 }
00303
00304 LogAndSign::LogAndSign(Real f) {
00305 if (f == 0.0) { log_value = 0.0; sign = 0; return; }
00306 else if (f < 0.0) { sign = -1; f = -f; }
00307 else sign = 1;
00308 log_value = log(f);
00309 }
00310
00311 LogAndSign DiagonalMatrix::LogDeterminant() const {
00312 REPORT
00313 int i = nrows; LogAndSign sum; Real* s = store;
00314 while (i--) sum *= *s++;
00315 ((GeneralMatrix&)*this).tDelete(); return sum;
00316 }
00317
00318 LogAndSign LowerTriangularMatrix::LogDeterminant() const {
00319 REPORT
00320 int i = nrows; LogAndSign sum; Real* s = store; int j = 2;
00321 while (i--) { sum *= *s; s += j++; }
00322 ((GeneralMatrix&)*this).tDelete(); return sum;
00323 }
00324
00325 LogAndSign UpperTriangularMatrix::LogDeterminant() const {
00326 REPORT
00327 int i = nrows; LogAndSign sum; Real* s = store;
00328 while (i) { sum *= *s; s += i--; }
00329 ((GeneralMatrix&)*this).tDelete(); return sum;
00330 }
00331
00332 LogAndSign BaseMatrix::LogDeterminant() const {
00333 REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
00334 LogAndSign sum = gm->LogDeterminant(); return sum;
00335 }
00336
00337 LogAndSign GeneralMatrix::LogDeterminant() const {
00338 REPORT
00339 Tracer tr("Determinant");
00340 if (nrows != ncols) Throw(NotSquareException(*this));
00341 CroutMatrix C(*this); return C.LogDeterminant();
00342 }
00343
00344 LogAndSign CroutMatrix::LogDeterminant() const {
00345 REPORT
00346 if (sing) return 0.0;
00347 int i = nrows; int dd = i+1; LogAndSign sum; Real* s = store;
00348 while (i--) { sum *= *s; s += dd; }
00349 if (!d) sum.ChangeSign(); return sum;
00350
00351 }
00352
00353 LinearEquationSolver::LinearEquationSolver(const BaseMatrix& bm)
00354 : gm( ( ((BaseMatrix&)bm).Evaluate() )->MakeSolver() ) {
00355 if (gm==&bm) { REPORT gm = gm->Image(); }
00356
00357 else { REPORT gm->Protect(); }
00358 }
00359
00360 #ifdef use_namespace
00361 }
00362 #endif