Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/newmat/newmat8.cpp @ 4618

Last change on this file since 4618 was 4565, checked in by patrick, 19 years ago

orxonox/trunk: added the newmat library to the project. needs some translation in directory, temp under util/newmat. is needed by the collision detection engine to perform lin alg operations such as eigenvector decomposition. perhaps we will make our own library to do that later.

File size: 19.4 KB
Line 
1//$$ newmat8.cpp         Advanced LU transform, scalar functions
2
3// Copyright (C) 1991,2,3,4,8: R B Davies
4
5#define WANT_MATH
6
7#include "include.h"
8
9#include "newmat.h"
10#include "newmatrc.h"
11#include "precisio.h"
12
13#ifdef use_namespace
14namespace NEWMAT {
15#endif
16
17
18#ifdef DO_REPORT
19#define REPORT { static ExeCounter ExeCount(__LINE__,8); ++ExeCount; }
20#else
21#define REPORT {}
22#endif
23
24
25/************************** LU transformation ****************************/
26
27void CroutMatrix::ludcmp()
28// LU decomposition from Golub & Van Loan, algorithm 3.4.1, (the "outer
29// product" version).
30// This replaces the code derived from Numerical Recipes in C in previous
31// versions of newmat and being row oriented runs much faster with large
32// matrices.
33{
34   REPORT
35   Tracer trace( "Crout(ludcmp)" ); sing = false;
36   Real* akk = store;                    // runs down diagonal
37
38   Real big = fabs(*akk); int mu = 0; Real* ai = akk; int k;
39
40   for (k = 1; k < nrows; k++)
41   {
42      ai += nrows; const Real trybig = fabs(*ai);
43      if (big < trybig) { big = trybig; mu = k; }
44   }
45
46
47   if (nrows) for (k = 0;;)
48   {
49      /*
50      int mu1;
51      {
52         Real big = fabs(*akk); mu1 = k; Real* ai = akk; int i;
53
54         for (i = k+1; i < nrows; i++)
55         {
56            ai += nrows; const Real trybig = fabs(*ai);
57            if (big < trybig) { big = trybig; mu1 = i; }
58         }
59      }
60      if (mu1 != mu) cout << k << " " << mu << " " << mu1 << endl;
61      */
62
63      indx[k] = mu;
64
65      if (mu != k)                       //row swap
66      {
67         Real* a1 = store + nrows * k; Real* a2 = store + nrows * mu; d = !d;
68         int j = nrows;
69         while (j--) { const Real temp = *a1; *a1++ = *a2; *a2++ = temp; }
70      }
71
72      Real diag = *akk; big = 0; mu = k + 1;
73      if (diag != 0)
74      {
75         ai = akk; int i = nrows - k - 1;
76         while (i--)
77         {
78            ai += nrows; Real* al = ai; Real mult = *al / diag; *al = mult;
79            int l = nrows - k - 1; Real* aj = akk;
80            // work out the next pivot as part of this loop
81            // this saves a column operation
82            if (l-- != 0)
83            {
84               *(++al) -= (mult * *(++aj));
85               const Real trybig = fabs(*al);
86               if (big < trybig) { big = trybig; mu = nrows - i - 1; }
87               while (l--) *(++al) -= (mult * *(++aj));
88            }
89         }
90      }
91      else sing = true;
92      if (++k == nrows) break;          // so next line won't overflow
93      akk += nrows + 1;
94   }
95}
96
97void CroutMatrix::lubksb(Real* B, int mini)
98{
99   REPORT
100   // this has been adapted from Numerical Recipes in C. The code has been
101   // substantially streamlined, so I do not think much of the original
102   // copyright remains. However there is not much opportunity for
103   // variation in the code, so it is still similar to the NR code.
104   // I follow the NR code in skipping over initial zeros in the B vector.
105
106   Tracer trace("Crout(lubksb)");
107   if (sing) Throw(SingularException(*this));
108   int i, j, ii = nrows;            // ii initialised : B might be all zeros
109
110
111   // scan for first non-zero in B
112   for (i = 0; i < nrows; i++)
113   {
114      int ip = indx[i]; Real temp = B[ip]; B[ip] = B[i]; B[i] = temp;
115      if (temp != 0.0) { ii = i; break; }
116   }
117
118   Real* bi; Real* ai;
119   i = ii + 1;
120
121   if (i < nrows)
122   {
123      bi = B + ii; ai = store + ii + i * nrows;
124      for (;;)
125      {
126         int ip = indx[i]; Real sum = B[ip]; B[ip] = B[i];
127         Real* aij = ai; Real* bj = bi; j = i - ii;
128         while (j--) sum -= *aij++ * *bj++;
129         B[i] = sum;
130         if (++i == nrows) break;
131         ai += nrows;
132      }
133   }
134
135   ai = store + nrows * nrows;
136
137   for (i = nrows - 1; i >= mini; i--)
138   {
139      Real* bj = B+i; ai -= nrows; Real* ajx = ai+i;
140      Real sum = *bj; Real diag = *ajx;
141      j = nrows - i; while(--j) sum -= *(++ajx) * *(++bj);
142      B[i] = sum / diag;
143   }
144}
145
146/****************************** scalar functions ****************************/
147
148inline Real square(Real x) { return x*x; }
149
150Real GeneralMatrix::SumSquare() const
151{
152   REPORT
153   Real sum = 0.0; int i = storage; Real* s = store;
154   while (i--) sum += square(*s++);
155   ((GeneralMatrix&)*this).tDelete(); return sum;
156}
157
158Real GeneralMatrix::SumAbsoluteValue() const
159{
160   REPORT
161   Real sum = 0.0; int i = storage; Real* s = store;
162   while (i--) sum += fabs(*s++);
163   ((GeneralMatrix&)*this).tDelete(); return sum;
164}
165
166Real GeneralMatrix::Sum() const
167{
168   REPORT
169   Real sum = 0.0; int i = storage; Real* s = store;
170   while (i--) sum += *s++;
171   ((GeneralMatrix&)*this).tDelete(); return sum;
172}
173
174// maxima and minima
175
176// There are three sets of routines
177// MaximumAbsoluteValue, MinimumAbsoluteValue, Maximum, Minimum
178// ... these find just the maxima and minima
179// MaximumAbsoluteValue1, MinimumAbsoluteValue1, Maximum1, Minimum1
180// ... these find the maxima and minima and their locations in a
181//     one dimensional object
182// MaximumAbsoluteValue2, MinimumAbsoluteValue2, Maximum2, Minimum2
183// ... these find the maxima and minima and their locations in a
184//     two dimensional object
185
186// If the matrix has no values throw an exception
187
188// If we do not want the location find the maximum or minimum on the
189// array stored by GeneralMatrix
190// This won't work for BandMatrices. We call ClearCorner for
191// MaximumAbsoluteValue but for the others use the AbsoluteMinimumValue2
192// version and discard the location.
193
194// For one dimensional objects, when we want the location of the
195// maximum or minimum, work with the array stored by GeneralMatrix
196
197// For two dimensional objects where we want the location of the maximum or
198// minimum proceed as follows:
199
200// For rectangular matrices use the array stored by GeneralMatrix and
201// deduce the location from the location in the GeneralMatrix
202
203// For other two dimensional matrices use the Matrix Row routine to find the
204// maximum or minimum for each row.
205
206static void NullMatrixError(const GeneralMatrix* gm)
207{
208   ((GeneralMatrix&)*gm).tDelete();
209   Throw(ProgramException("Maximum or minimum of null matrix"));
210}
211
212Real GeneralMatrix::MaximumAbsoluteValue() const
213{
214   REPORT
215   if (storage == 0) NullMatrixError(this);
216   Real maxval = 0.0; int l = storage; Real* s = store;
217   while (l--) { Real a = fabs(*s++); if (maxval < a) maxval = a; }
218   ((GeneralMatrix&)*this).tDelete(); return maxval;
219}
220
221Real GeneralMatrix::MaximumAbsoluteValue1(int& i) const
222{
223   REPORT
224   if (storage == 0) NullMatrixError(this);
225   Real maxval = 0.0; int l = storage; Real* s = store; int li = storage;
226   while (l--)
227      { Real a = fabs(*s++); if (maxval <= a) { maxval = a; li = l; }  }
228   i = storage - li;
229   ((GeneralMatrix&)*this).tDelete(); return maxval;
230}
231
232Real GeneralMatrix::MinimumAbsoluteValue() const
233{
234   REPORT
235   if (storage == 0) NullMatrixError(this);
236   int l = storage - 1; Real* s = store; Real minval = fabs(*s++);
237   while (l--) { Real a = fabs(*s++); if (minval > a) minval = a; }
238   ((GeneralMatrix&)*this).tDelete(); return minval;
239}
240
241Real GeneralMatrix::MinimumAbsoluteValue1(int& i) const
242{
243   REPORT
244   if (storage == 0) NullMatrixError(this);
245   int l = storage - 1; Real* s = store; Real minval = fabs(*s++); int li = l;
246   while (l--)
247      { Real a = fabs(*s++); if (minval >= a) { minval = a; li = l; }  }
248   i = storage - li;
249   ((GeneralMatrix&)*this).tDelete(); return minval;
250}
251
252Real GeneralMatrix::Maximum() const
253{
254   REPORT
255   if (storage == 0) NullMatrixError(this);
256   int l = storage - 1; Real* s = store; Real maxval = *s++;
257   while (l--) { Real a = *s++; if (maxval < a) maxval = a; }
258   ((GeneralMatrix&)*this).tDelete(); return maxval;
259}
260
261Real GeneralMatrix::Maximum1(int& i) const
262{
263   REPORT
264   if (storage == 0) NullMatrixError(this);
265   int l = storage - 1; Real* s = store; Real maxval = *s++; int li = l;
266   while (l--) { Real a = *s++; if (maxval <= a) { maxval = a; li = l; } }
267   i = storage - li;
268   ((GeneralMatrix&)*this).tDelete(); return maxval;
269}
270
271Real GeneralMatrix::Minimum() const
272{
273   REPORT
274   if (storage == 0) NullMatrixError(this);
275   int l = storage - 1; Real* s = store; Real minval = *s++;
276   while (l--) { Real a = *s++; if (minval > a) minval = a; }
277   ((GeneralMatrix&)*this).tDelete(); return minval;
278}
279
280Real GeneralMatrix::Minimum1(int& i) const
281{
282   REPORT
283   if (storage == 0) NullMatrixError(this);
284   int l = storage - 1; Real* s = store; Real minval = *s++; int li = l;
285   while (l--) { Real a = *s++; if (minval >= a) { minval = a; li = l; } }
286   i = storage - li;
287   ((GeneralMatrix&)*this).tDelete(); return minval;
288}
289
290Real GeneralMatrix::MaximumAbsoluteValue2(int& i, int& j) const
291{
292   REPORT
293   if (storage == 0) NullMatrixError(this);
294   Real maxval = 0.0; int nr = Nrows();
295   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
296   for (int r = 1; r <= nr; r++)
297   {
298      int c; maxval = mr.MaximumAbsoluteValue1(maxval, c);
299      if (c > 0) { i = r; j = c; }
300      mr.Next();
301   }
302   ((GeneralMatrix&)*this).tDelete(); return maxval;
303}
304
305Real GeneralMatrix::MinimumAbsoluteValue2(int& i, int& j) const
306{
307   REPORT
308   if (storage == 0)  NullMatrixError(this);
309   Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
310   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
311   for (int r = 1; r <= nr; r++)
312   {
313      int c; minval = mr.MinimumAbsoluteValue1(minval, c);
314      if (c > 0) { i = r; j = c; }
315      mr.Next();
316   }
317   ((GeneralMatrix&)*this).tDelete(); return minval;
318}
319
320Real GeneralMatrix::Maximum2(int& i, int& j) const
321{
322   REPORT
323   if (storage == 0) NullMatrixError(this);
324   Real maxval = -FloatingPointPrecision::Maximum(); int nr = Nrows();
325   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
326   for (int r = 1; r <= nr; r++)
327   {
328      int c; maxval = mr.Maximum1(maxval, c);
329      if (c > 0) { i = r; j = c; }
330      mr.Next();
331   }
332   ((GeneralMatrix&)*this).tDelete(); return maxval;
333}
334
335Real GeneralMatrix::Minimum2(int& i, int& j) const
336{
337   REPORT
338   if (storage == 0) NullMatrixError(this);
339   Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
340   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
341   for (int r = 1; r <= nr; r++)
342   {
343      int c; minval = mr.Minimum1(minval, c);
344      if (c > 0) { i = r; j = c; }
345      mr.Next();
346   }
347   ((GeneralMatrix&)*this).tDelete(); return minval;
348}
349
350Real Matrix::MaximumAbsoluteValue2(int& i, int& j) const
351{
352   REPORT
353   int k; Real m = GeneralMatrix::MaximumAbsoluteValue1(k); k--;
354   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
355   return m;
356}
357
358Real Matrix::MinimumAbsoluteValue2(int& i, int& j) const
359{
360   REPORT
361   int k; Real m = GeneralMatrix::MinimumAbsoluteValue1(k); k--;
362   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
363   return m;
364}
365
366Real Matrix::Maximum2(int& i, int& j) const
367{
368   REPORT
369   int k; Real m = GeneralMatrix::Maximum1(k); k--;
370   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
371   return m;
372}
373
374Real Matrix::Minimum2(int& i, int& j) const
375{
376   REPORT
377   int k; Real m = GeneralMatrix::Minimum1(k); k--;
378   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
379   return m;
380}
381
382Real SymmetricMatrix::SumSquare() const
383{
384   REPORT
385   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
386   for (int i = 0; i<nr; i++)
387   {
388      int j = i;
389      while (j--) sum2 += square(*s++);
390      sum1 += square(*s++);
391   }
392   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
393}
394
395Real SymmetricMatrix::SumAbsoluteValue() const
396{
397   REPORT
398   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
399   for (int i = 0; i<nr; i++)
400   {
401      int j = i;
402      while (j--) sum2 += fabs(*s++);
403      sum1 += fabs(*s++);
404   }
405   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
406}
407
408Real IdentityMatrix::SumAbsoluteValue() const
409   { REPORT  return fabs(Trace()); }    // no need to do tDelete?
410
411Real SymmetricMatrix::Sum() const
412{
413   REPORT
414   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
415   for (int i = 0; i<nr; i++)
416   {
417      int j = i;
418      while (j--) sum2 += *s++;
419      sum1 += *s++;
420   }
421   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
422}
423
424Real IdentityMatrix::SumSquare() const
425{
426   Real sum = *store * *store * nrows;
427   ((GeneralMatrix&)*this).tDelete(); return sum;
428}
429
430
431Real BaseMatrix::SumSquare() const
432{
433   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
434   Real s = gm->SumSquare(); return s;
435}
436
437Real BaseMatrix::NormFrobenius() const
438   { REPORT  return sqrt(SumSquare()); }
439
440Real BaseMatrix::SumAbsoluteValue() const
441{
442   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
443   Real s = gm->SumAbsoluteValue(); return s;
444}
445
446Real BaseMatrix::Sum() const
447{
448   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
449   Real s = gm->Sum(); return s;
450}
451
452Real BaseMatrix::MaximumAbsoluteValue() const
453{
454   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
455   Real s = gm->MaximumAbsoluteValue(); return s;
456}
457
458Real BaseMatrix::MaximumAbsoluteValue1(int& i) const
459{
460   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
461   Real s = gm->MaximumAbsoluteValue1(i); return s;
462}
463
464Real BaseMatrix::MaximumAbsoluteValue2(int& i, int& j) const
465{
466   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
467   Real s = gm->MaximumAbsoluteValue2(i, j); return s;
468}
469
470Real BaseMatrix::MinimumAbsoluteValue() const
471{
472   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
473   Real s = gm->MinimumAbsoluteValue(); return s;
474}
475
476Real BaseMatrix::MinimumAbsoluteValue1(int& i) const
477{
478   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
479   Real s = gm->MinimumAbsoluteValue1(i); return s;
480}
481
482Real BaseMatrix::MinimumAbsoluteValue2(int& i, int& j) const
483{
484   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
485   Real s = gm->MinimumAbsoluteValue2(i, j); return s;
486}
487
488Real BaseMatrix::Maximum() const
489{
490   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
491   Real s = gm->Maximum(); return s;
492}
493
494Real BaseMatrix::Maximum1(int& i) const
495{
496   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
497   Real s = gm->Maximum1(i); return s;
498}
499
500Real BaseMatrix::Maximum2(int& i, int& j) const
501{
502   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
503   Real s = gm->Maximum2(i, j); return s;
504}
505
506Real BaseMatrix::Minimum() const
507{
508   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
509   Real s = gm->Minimum(); return s;
510}
511
512Real BaseMatrix::Minimum1(int& i) const
513{
514   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
515   Real s = gm->Minimum1(i); return s;
516}
517
518Real BaseMatrix::Minimum2(int& i, int& j) const
519{
520   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
521   Real s = gm->Minimum2(i, j); return s;
522}
523
524Real DotProduct(const Matrix& A, const Matrix& B)
525{
526   REPORT
527   int n = A.storage;
528   if (n != B.storage) Throw(IncompatibleDimensionsException(A,B));
529   Real sum = 0.0; Real* a = A.store; Real* b = B.store;
530   while (n--) sum += *a++ * *b++;
531   return sum;
532}
533
534Real Matrix::Trace() const
535{
536   REPORT
537   Tracer trace("Trace");
538   int i = nrows; int d = i+1;
539   if (i != ncols) Throw(NotSquareException(*this));
540   Real sum = 0.0; Real* s = store;
541//   while (i--) { sum += *s; s += d; }
542   if (i) for (;;) { sum += *s; if (!(--i)) break; s += d; }
543   ((GeneralMatrix&)*this).tDelete(); return sum;
544}
545
546Real DiagonalMatrix::Trace() const
547{
548   REPORT
549   int i = nrows; Real sum = 0.0; Real* s = store;
550   while (i--) sum += *s++;
551   ((GeneralMatrix&)*this).tDelete(); return sum;
552}
553
554Real SymmetricMatrix::Trace() const
555{
556   REPORT
557   int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
558   // while (i--) { sum += *s; s += j++; }
559   if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
560   ((GeneralMatrix&)*this).tDelete(); return sum;
561}
562
563Real LowerTriangularMatrix::Trace() const
564{
565   REPORT
566   int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
567   // while (i--) { sum += *s; s += j++; }
568   if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
569   ((GeneralMatrix&)*this).tDelete(); return sum;
570}
571
572Real UpperTriangularMatrix::Trace() const
573{
574   REPORT
575   int i = nrows; Real sum = 0.0; Real* s = store;
576   while (i) { sum += *s; s += i--; }             // won t cause a problem
577   ((GeneralMatrix&)*this).tDelete(); return sum;
578}
579
580Real BandMatrix::Trace() const
581{
582   REPORT
583   int i = nrows; int w = lower+upper+1;
584   Real sum = 0.0; Real* s = store+lower;
585   // while (i--) { sum += *s; s += w; }
586   if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
587   ((GeneralMatrix&)*this).tDelete(); return sum;
588}
589
590Real SymmetricBandMatrix::Trace() const
591{
592   REPORT
593   int i = nrows; int w = lower+1;
594   Real sum = 0.0; Real* s = store+lower;
595   // while (i--) { sum += *s; s += w; }
596   if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
597   ((GeneralMatrix&)*this).tDelete(); return sum;
598}
599
600Real IdentityMatrix::Trace() const
601{
602   Real sum = *store * nrows;
603   ((GeneralMatrix&)*this).tDelete(); return sum;
604}
605
606
607Real BaseMatrix::Trace() const
608{
609   REPORT
610   MatrixType Diag = MatrixType::Dg; Diag.SetDataLossOK();
611   GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(Diag);
612   Real sum = gm->Trace(); return sum;
613}
614
615void LogAndSign::operator*=(Real x)
616{
617   if (x > 0.0) { log_value += log(x); }
618   else if (x < 0.0) { log_value += log(-x); sign = -sign; }
619   else sign = 0;
620}
621
622void LogAndSign::PowEq(int k)
623{
624   if (sign)
625   {
626      log_value *= k;
627      if ( (k & 1) == 0 ) sign = 1;
628   }
629}
630
631Real LogAndSign::Value() const
632{
633   Tracer et("LogAndSign::Value");
634   if (log_value >= FloatingPointPrecision::LnMaximum())
635      Throw(OverflowException("Overflow in exponential"));
636   return sign * exp(log_value);
637}
638
639LogAndSign::LogAndSign(Real f)
640{
641   if (f == 0.0) { log_value = 0.0; sign = 0; return; }
642   else if (f < 0.0) { sign = -1; f = -f; }
643   else sign = 1;
644   log_value = log(f);
645}
646
647LogAndSign DiagonalMatrix::LogDeterminant() const
648{
649   REPORT
650   int i = nrows; LogAndSign sum; Real* s = store;
651   while (i--) sum *= *s++;
652   ((GeneralMatrix&)*this).tDelete(); return sum;
653}
654
655LogAndSign LowerTriangularMatrix::LogDeterminant() const
656{
657   REPORT
658   int i = nrows; LogAndSign sum; Real* s = store; int j = 2;
659   // while (i--) { sum *= *s; s += j++; }
660   if (i) for(;;) { sum *= *s; if (!(--i)) break; s += j++; }
661   ((GeneralMatrix&)*this).tDelete(); return sum;
662}
663
664LogAndSign UpperTriangularMatrix::LogDeterminant() const
665{
666   REPORT
667   int i = nrows; LogAndSign sum; Real* s = store;
668   while (i) { sum *= *s; s += i--; }
669   ((GeneralMatrix&)*this).tDelete(); return sum;
670}
671
672LogAndSign IdentityMatrix::LogDeterminant() const
673{
674   REPORT
675   int i = nrows; LogAndSign sum;
676   if (i > 0) { sum = *store; sum.PowEq(i); }
677   ((GeneralMatrix&)*this).tDelete(); return sum;
678}
679
680LogAndSign BaseMatrix::LogDeterminant() const
681{
682   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
683   LogAndSign sum = gm->LogDeterminant(); return sum;
684}
685
686LogAndSign GeneralMatrix::LogDeterminant() const
687{
688   REPORT
689   Tracer tr("LogDeterminant");
690   if (nrows != ncols) Throw(NotSquareException(*this));
691   CroutMatrix C(*this); return C.LogDeterminant();
692}
693
694LogAndSign CroutMatrix::LogDeterminant() const
695{
696   REPORT
697   if (sing) return 0.0;
698   int i = nrows; int dd = i+1; LogAndSign sum; Real* s = store;
699   if (i) for(;;)
700   {
701      sum *= *s;
702      if (!(--i)) break;
703      s += dd;
704   }
705   if (!d) sum.ChangeSign(); return sum;
706
707}
708
709Real BaseMatrix::Determinant() const
710{
711   REPORT
712   Tracer tr("Determinant");
713   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
714   LogAndSign ld = gm->LogDeterminant();
715   return ld.Value();
716}
717
718
719
720
721
722LinearEquationSolver::LinearEquationSolver(const BaseMatrix& bm)
723: gm( ( ((BaseMatrix&)bm).Evaluate() )->MakeSolver() )
724{
725   if (gm==&bm) { REPORT  gm = gm->Image(); }
726   // want a copy if  *gm is actually bm
727   else { REPORT  gm->Protect(); }
728}
729
730
731#ifdef use_namespace
732}
733#endif
734
Note: See TracBrowser for help on using the repository browser.