OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
bandmat.cpp
Go to the documentation of this file.
1 //$$ bandmat.cpp Band matrix definitions
2 
3 // Copyright (C) 1991,2,3,4,9: R B Davies
4 
5 #define WANT_MATH // include.h will get math fns
6 
7 //#define WANT_STREAM
8 
9 #include <cmath>
10 #include <ossim/matrix/include.h>
11 
12 #include <ossim/matrix/newmat.h>
13 #include <ossim/matrix/newmatrc.h>
14 
15 #ifdef use_namespace
16 namespace NEWMAT {
17 #endif
18 
19 
20 
21 #ifdef DO_REPORT
22 #define REPORT { static ExeCounter ExeCount(__LINE__,10); ++ExeCount; }
23 #else
24 #define REPORT {}
25 #endif
26 
27 static inline int my_min(int x, int y) { return x < y ? x : y; }
28 static inline int my_max(int x, int y) { return x > y ? x : y; }
29 
30 
32 {
33  REPORT // CheckConversion(M);
34  // MatrixConversionCheck mcc;
36  GetMatrix(gmx); CornerClear();
37 }
38 
40 {
41  REPORT
42  MatrixBandWidth bw = gmx->BandWidth();
43  lower = bw.lower; upper = bw.upper;
44 }
45 
46 void BandMatrix::ReSize(int n, int lb, int ub)
47 {
48  REPORT
49  Tracer tr("BandMatrix::ReSize");
50  if (lb<0 || ub<0) Throw(ProgramException("Undefined bandwidth"));
51  lower = (lb<=n) ? lb : n-1; upper = (ub<=n) ? ub : n-1;
52  GeneralMatrix::ReSize(n,n,n*(lower+1+upper)); CornerClear();
53 }
54 
55 // SimpleAddOK shows when we can add etc two matrices by a simple vector add
56 // and when we can add one matrix into another
57 // *gm must be the same type as *this
58 // return 0 if simple add is OK
59 // return 1 if we can add into *gm only
60 // return 2 if we can add into *this only
61 // return 3 if we can't add either way
62 // For SP this will still be valid if we swap 1 and 2
63 
65 {
66  const BandMatrix* bm = (const BandMatrix*)gm;
67  if (bm->lower == lower && bm->upper == upper) { REPORT return 0; }
68  else if (bm->lower >= lower && bm->upper >= upper) { REPORT return 1; }
69  else if (bm->lower <= lower && bm->upper <= upper) { REPORT return 2; }
70  else { REPORT return 3; }
71 }
72 
74 {
75  const SymmetricBandMatrix* bm = (const SymmetricBandMatrix*)gm;
76  if (bm->lower == lower) { REPORT return 0; }
77  else if (bm->lower > lower) { REPORT return 1; }
78  else { REPORT return 2; }
79 }
80 
81 void UpperBandMatrix::ReSize(int n, int lb, int ub)
82 {
83  REPORT
84  if (lb != 0)
85  {
86  Tracer tr("UpperBandMatrix::ReSize");
87  Throw(ProgramException("UpperBandMatrix with non-zero lower band" ));
88  }
89  BandMatrix::ReSize(n, lb, ub);
90 }
91 
92 void LowerBandMatrix::ReSize(int n, int lb, int ub)
93 {
94  REPORT
95  if (ub != 0)
96  {
97  Tracer tr("LowerBandMatrix::ReSize");
98  Throw(ProgramException("LowerBandMatrix with non-zero upper band" ));
99  }
100  BandMatrix::ReSize(n, lb, ub);
101 }
102 
104 {
105  REPORT
106  int n = A.Nrows();
107  if (n != A.Ncols())
108  {
109  Tracer tr("BandMatrix::ReSize(GM)");
110  Throw(NotSquareException(*this));
111  }
112  MatrixBandWidth mbw = A.BandWidth();
113  ReSize(n, mbw.Lower(), mbw.Upper());
114 }
115 
117 {
118  if (Type() != A.Type()) { REPORT return false; }
119  REPORT
120  return BandWidth() == A.BandWidth();
121 }
122 
124 {
125  REPORT
126  Tracer tr("BandMatrix::ReSizeForAdd");
127  MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
128  if ((A_BW.Lower() < 0) | (A_BW.Upper() < 0) | (B_BW.Lower() < 0)
129  | (A_BW.Upper() < 0))
130  Throw(ProgramException("Can't ReSize to BandMatrix" ));
131  // already know A and B are square
132  ReSize(A.Nrows(), my_max(A_BW.Lower(), B_BW.Lower()),
133  my_max(A_BW.Upper(), B_BW.Upper()));
134 }
135 
137 {
138  REPORT
139  Tracer tr("BandMatrix::ReSizeForSP");
140  MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
141  if ((A_BW.Lower() < 0) | (A_BW.Upper() < 0) | (B_BW.Lower() < 0)
142  | (A_BW.Upper() < 0))
143  Throw(ProgramException("Can't ReSize to BandMatrix" ));
144  // already know A and B are square
145  ReSize(A.Nrows(), my_min(A_BW.Lower(), B_BW.Lower()),
146  my_min(A_BW.Upper(), B_BW.Upper()));
147 }
148 
149 
151 {
152  REPORT // CheckConversion(X);
153  // MatrixConversionCheck mcc;
154  Eq(X,MatrixType::BM); CornerClear();
155 }
156 
158 {
159  // set unused parts of BandMatrix to zero
160  REPORT
161  int i = lower; Real* s = store; int bw = lower + 1 + upper;
162  while (i)
163  { int j = i--; Real* sj = s; s += bw; while (j--) *sj++ = 0.0; }
164  i = upper; s = store + storage;
165  while (i)
166  { int j = i--; Real* sj = s; s -= bw; while (j--) *(--sj) = 0.0; }
167 }
168 
170 {
171  REPORT
172  int l = bw.lower; int u = bw.upper;
173  l = (lower < 0 || l < 0) ? -1 : (lower > l) ? lower : l;
174  u = (upper < 0 || u < 0) ? -1 : (upper > u) ? upper : u;
175  return MatrixBandWidth(l,u);
176 }
177 
179 {
180  REPORT
181  int l = bw.lower; int u = bw.upper;
182  l = (lower < 0 || l < 0) ? -1 : lower+l;
183  u = (upper < 0 || u < 0) ? -1 : upper+u;
184  return MatrixBandWidth(l,u);
185 }
186 
188 {
189  REPORT
190  int l = bw.lower; int u = bw.upper;
191  if ((lower >= 0) && ( (l < 0) || (l > lower) )) l = lower;
192  if ((upper >= 0) && ( (u < 0) || (u > upper) )) u = upper;
193  return MatrixBandWidth(l,u);
194 }
195 
197 {
198  REPORT // CheckConversion(M);
199  // MatrixConversionCheck mcc;
201  GetMatrix(gmx); CornerClear();
202 }
203 
205 {
206  REPORT // CheckConversion(X);
207  // MatrixConversionCheck mcc;
208  Eq(X,MatrixType::UB); CornerClear();
209 }
210 
212 {
213  REPORT // CheckConversion(M);
214  // MatrixConversionCheck mcc;
216  GetMatrix(gmx); CornerClear();
217 }
218 
220 {
221  REPORT // CheckConversion(X);
222  // MatrixConversionCheck mcc;
223  Eq(X,MatrixType::LB); CornerClear();
224 }
225 
227 {
228  REPORT
229  Tracer tr("BandLUMatrix");
230  storage2 = 0; store2 = 0; // in event of exception during build
232  m1 = ((BandMatrix*)gm)->lower; m2 = ((BandMatrix*)gm)->upper;
233  GetMatrix(gm);
234  if (nrows!=ncols) Throw(NotSquareException(*this));
235  d = true; sing = false;
236  indx = new int [nrows]; MatrixErrorNoSpace(indx);
237  MONITOR_INT_NEW("Index (BndLUMat)",nrows,indx)
238  storage2 = nrows * m1;
239  store2 = new Real [storage2]; MatrixErrorNoSpace(store2);
240  MONITOR_REAL_NEW("Make (BandLUMat)",storage2,store2)
241  ludcmp();
242 }
243 
245 {
246  REPORT
247  MONITOR_INT_DELETE("Index (BndLUMat)",nrows,indx)
248  MONITOR_REAL_DELETE("Delete (BndLUMt)",storage2,store2)
249  delete [] indx; delete [] store2;
250 }
251 
253 
254 
256 {
257  REPORT
258  if (sing) return 0.0;
259  Real* a = store; int w = m1+1+m2; LogAndSign sum; int i = nrows;
260  // while (i--) { sum *= *a; a += w; }
261  if (i) for (;;) { sum *= *a; if (!(--i)) break; a += w; }
262  if (!d) sum.ChangeSign(); return sum;
263 }
264 
266 {
267  REPORT
268  GeneralMatrix* gm = new BandLUMatrix(*this);
269  MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
270 }
271 
272 
274 {
275  REPORT
276  Real* a = store2; int i = storage2;
277  // clear store2 - so unused locations are always zero -
278  // required by operator==
279  while (i--) *a++ = 0.0;
280  a = store;
281  i = m1; int j = m2; int k; int n = nrows; int w = m1 + 1 + m2;
282  while (i)
283  {
284  Real* ai = a + i;
285  k = ++j; while (k--) *a++ = *ai++;
286  k = i--; while (k--) *a++ = 0.0;
287  }
288 
289  a = store; int l = m1;
290  for (k=0; k<n; k++)
291  {
292  Real x = *a; i = k; Real* aj = a;
293  if (l < n) l++;
294  for (j=k+1; j<l; j++)
295  { aj += w; if (std::fabs(x) < std::fabs(*aj)) { x = *aj; i = j; } }
296  indx[k] = i;
297  if (x==0) { sing = true; return; }
298  if (i!=k)
299  {
300  d = !d; Real* ak = a; Real* ai = store + i * w; j = w;
301  while (j--) { x = *ak; *ak++ = *ai; *ai++ = x; }
302  }
303  aj = a + w; Real* m = store2 + m1 * k;
304  for (j=k+1; j<l; j++)
305  {
306  *m++ = x = *aj / *a; i = w; Real* ak = a;
307  while (--i) { Real* aj1 = aj++; *aj1 = *aj - x * *(++ak); }
308  *aj++ = 0.0;
309  }
310  a += w;
311  }
312 }
313 
314 void BandLUMatrix::lubksb(Real* B, int mini)
315 {
316  REPORT
317  Tracer tr("BandLUMatrix::lubksb");
318  if (sing) Throw(SingularException(*this));
319  int n = nrows; int l = m1; int w = m1 + 1 + m2;
320 
321  for (int k=0; k<n; k++)
322  {
323  int i = indx[k];
324  if (i!=k) { Real x=B[k]; B[k]=B[i]; B[i]=x; }
325  if (l<n) l++;
326  Real* m = store2 + k*m1; Real* b = B+k; Real* bi = b;
327  for (i=k+1; i<l; i++) *(++bi) -= *m++ * *b;
328  }
329 
330  l = -m1;
331  for (int i = n-1; i>=mini; i--)
332  {
333  Real* b = B + i; Real* bk = b; Real x = *bk;
334  Real* a = store + w*i; Real y = *a;
335  int k = l+m1; while (k--) x -= *(++a) * *(++bk);
336  *b = x / y;
337  if (l < m2) l++;
338  }
339 }
340 
341 void BandLUMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin)
342 {
343  REPORT
344  int i = mcin.skip; Real* el = mcin.data-i; Real* el1=el;
345  while (i--) *el++ = 0.0;
346  el += mcin.storage; i = nrows - mcin.skip - mcin.storage;
347  while (i--) *el++ = 0.0;
348  lubksb(el1, mcout.skip);
349 }
350 
351 // Do we need check for entirely zero output?
352 
353 
355  const MatrixColX& mcin)
356 {
357  REPORT
358  int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
359  while (i-- > 0) *elx++ = 0.0;
360  int nr = mcin.skip+mcin.storage;
361  elx = mcin.data+mcin.storage; Real* el = elx;
362  int j = mcout.skip+mcout.storage-nr; i = nr-mcout.skip;
363  while (j-- > 0) *elx++ = 0.0;
364 
365  Real* Ael = store + (upper+1)*(i-1)+1; j = 0;
366  if (i > 0) for(;;)
367  {
368  elx = el; Real sum = 0.0; int jx = j;
369  while (jx--) sum += *(--Ael) * *(--elx);
370  elx--; *elx = (*elx - sum) / *(--Ael);
371  if (--i <= 0) break;
372  if (j<upper) Ael -= upper - (++j); else el--;
373  }
374 }
375 
377  const MatrixColX& mcin)
378 {
379  REPORT
380  int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
381  while (i-- > 0) *elx++ = 0.0;
382  int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage;
383  int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
384  while (j-- > 0) *elx++ = 0.0;
385 
386  Real* el = mcin.data; Real* Ael = store + (lower+1)*nc + lower; j = 0;
387  if (i > 0) for(;;)
388  {
389  elx = el; Real sum = 0.0; int jx = j;
390  while (jx--) sum += *Ael++ * *elx++;
391  *elx = (*elx - sum) / *Ael++;
392  if (--i <= 0) break;
393  if (j<lower) Ael += lower - (++j); else el++;
394  }
395 }
396 
397 
399 {
400  REPORT
401  BandLUMatrix C(*this); return C.LogDeterminant();
402 }
403 
405 {
406  REPORT
407  int i = nrows; LogAndSign sum; Real* s = store + lower; int j = lower + 1;
408 // while (i--) { sum *= *s; s += j; }
409  if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
410  ((GeneralMatrix&)*this).tDelete(); return sum;
411 }
412 
414 {
415  REPORT
416  int i = nrows; LogAndSign sum; Real* s = store; int j = upper + 1;
417 // while (i--) { sum *= *s; s += j; }
418  if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
419  ((GeneralMatrix&)*this).tDelete(); return sum;
420 }
421 
423 {
424  REPORT
425  GeneralMatrix* gm = new BandLUMatrix(*this);
426  MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
427 }
428 
430 {
431  REPORT // CheckConversion(M);
432  // MatrixConversionCheck mcc;
434  GetMatrix(gmx);
435 }
436 
438 { REPORT return Evaluate(mt); }
439 
441 {
442  REPORT
443  BandLUMatrix C(*this); return C.LogDeterminant();
444 }
445 
447 { REPORT lower = gmx->BandWidth().lower; }
448 
450 {
451  REPORT
452  Tracer tr("SymmetricBandMatrix::ReSize");
453  if (lb<0) Throw(ProgramException("Undefined bandwidth"));
454  lower = (lb<=n) ? lb : n-1;
455  GeneralMatrix::ReSize(n,n,n*(lower+1));
456 }
457 
459 {
460  REPORT
461  int n = A.Nrows();
462  if (n != A.Ncols())
463  {
464  Tracer tr("SymmetricBandMatrix::ReSize(GM)");
465  Throw(NotSquareException(*this));
466  }
467  MatrixBandWidth mbw = A.BandWidth(); int b = mbw.Lower();
468  if (b != mbw.Upper())
469  {
470  Tracer tr("SymmetricBandMatrix::ReSize(GM)");
471  Throw(ProgramException("Upper and lower band-widths not equal"));
472  }
473  ReSize(n, b);
474 }
475 
477 {
478  if (Type() != A.Type()) { REPORT return false; }
479  REPORT
480  return BandWidth() == A.BandWidth();
481 }
482 
484  const GeneralMatrix& B)
485 {
486  REPORT
487  Tracer tr("SymmetricBandMatrix::ReSizeForAdd");
488  MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
489  if ((A_BW.Lower() < 0) | (B_BW.Lower() < 0))
490  Throw(ProgramException("Can't ReSize to SymmetricBandMatrix" ));
491  // already know A and B are square
492  ReSize(A.Nrows(), my_max(A_BW.Lower(), B_BW.Lower()));
493 }
494 
496  const GeneralMatrix& B)
497 {
498  REPORT
499  Tracer tr("SymmetricBandMatrix::ReSizeForSP");
500  MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
501  if ((A_BW.Lower() < 0) | (B_BW.Lower() < 0))
502  Throw(ProgramException("Can't ReSize to SymmetricBandMatrix" ));
503  // already know A and B are square
504  ReSize(A.Nrows(), my_min(A_BW.Lower(), B_BW.Lower()));
505 }
506 
507 
509 {
510  REPORT // CheckConversion(X);
511  // MatrixConversionCheck mcc;
512  Eq(X,MatrixType::SB);
513 }
514 
516 {
517  // set unused parts of BandMatrix to zero
518  REPORT
519  int i = lower; Real* s = store; int bw = lower + 1;
520  if (i) for(;;)
521  {
522  int j = i;
523  Real* sj = s;
524  while (j--) *sj++ = 0.0;
525  if (!(--i)) break;
526  s += bw;
527  }
528 }
529 
531  { REPORT return MatrixBandWidth(lower,lower); }
532 
533 inline Real square(Real x) { return x*x; }
534 
535 
537 {
538  REPORT
539  CornerClear();
540  Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
541  while (i--)
542  { int j = l; while (j--) sum2 += square(*s++); sum1 += square(*s++); }
543  ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
544 }
545 
547 {
548  REPORT
549  CornerClear();
550  Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
551  while (i--)
552  { int j = l; while (j--) sum2 += std::fabs(*s++); sum1 += std::fabs(*s++); }
553  ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
554 }
555 
557 {
558  REPORT
559  CornerClear();
560  Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
561  while (i--)
562  { int j = l; while (j--) sum2 += *s++; sum1 += *s++; }
563  ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
564 }
565 
566 
567 #ifdef use_namespace
568 }
569 #endif
570 
ossim_uint32 x
Real Sum() const
Definition: bandmat.cpp:556
Real SumAbsoluteValue() const
Definition: bandmat.cpp:546
double Real
Definition: include.h:57
void ludcmp()
Definition: bandmat.cpp:273
void SetParameters(const GeneralMatrix *)
Definition: bandmat.cpp:446
MatrixBandWidth operator*(const MatrixBandWidth &) const
Definition: bandmat.cpp:178
int lower
Definition: newmat.h:936
#define MONITOR_INT_DELETE(Operation, Size, Pointer)
Definition: myexcept.h:320
ossim_uint32 y
LogAndSign LogDeterminant() const
Definition: bandmat.cpp:440
MatrixType Type() const
Definition: bandmat.cpp:252
void CornerClear() const
Definition: bandmat.cpp:515
virtual MatrixBandWidth BandWidth() const
Definition: newmat4.cpp:431
void operator=(const BaseMatrix &)
Definition: bandmat.cpp:204
short SimpleAddOK(const GeneralMatrix *gm)
Definition: bandmat.cpp:73
GeneralMatrix * Evaluate(MatrixType mt=MatrixTypeUnSp)
Definition: newmat5.cpp:79
Real square(Real x)
Definition: bandmat.cpp:533
#define A(r, c)
virtual void ReSize(int, int, int)
Definition: bandmat.cpp:46
void CornerClear() const
Definition: bandmat.cpp:157
BandMatrix()
Definition: newmat.h:937
void ReSizeForAdd(const GeneralMatrix &A, const GeneralMatrix &B)
Definition: bandmat.cpp:123
#define MONITOR_INT_NEW(Operation, Size, Pointer)
Definition: myexcept.h:318
bool SameStorageType(const GeneralMatrix &A) const
Definition: bandmat.cpp:476
void ReSize(int, int, int)
Definition: bandmat.cpp:81
void Solver(MatrixColX &, const MatrixColX &)
Definition: bandmat.cpp:354
void MatrixErrorNoSpace(const void *)
Definition: newmatex.cpp:292
int Lower() const
Definition: newmat.h:204
void ReSizeForAdd(const GeneralMatrix &A, const GeneralMatrix &B)
Definition: bandmat.cpp:483
BandLUMatrix(const BaseMatrix &)
Definition: bandmat.cpp:226
LogAndSign LogDeterminant() const
Definition: bandmat.cpp:398
Real * data
Definition: newmatrc.h:43
int storage
Definition: newmatrc.h:40
LogAndSign LogDeterminant() const
Definition: bandmat.cpp:255
os2<< "> n<< " > nendobj n
#define MONITOR_REAL_DELETE(Operation, Size, Pointer)
Definition: myexcept.h:319
void SetParameters(const GeneralMatrix *)
Definition: bandmat.cpp:39
void ReSize(int, int, int)
Definition: bandmat.cpp:92
GeneralMatrix * Transpose(TransposedMatrix *, MatrixType)
Definition: bandmat.cpp:437
bool SameStorageType(const GeneralMatrix &A) const
Definition: bandmat.cpp:116
void ReSizeForSP(const GeneralMatrix &A, const GeneralMatrix &B)
Definition: bandmat.cpp:495
#define MONITOR_REAL_NEW(Operation, Size, Pointer)
Definition: myexcept.h:317
void operator=(const BaseMatrix &)
Definition: bandmat.cpp:508
GeneralMatrix * MakeSolver()
Definition: bandmat.cpp:265
MatrixBandWidth minimum(const MatrixBandWidth &) const
Definition: bandmat.cpp:187
GeneralMatrix * MakeSolver()
Definition: bandmat.cpp:422
Real SumSquare() const
Definition: bandmat.cpp:536
void ReSizeForSP(const GeneralMatrix &A, const GeneralMatrix &B)
Definition: bandmat.cpp:136
LogAndSign LogDeterminant() const
Definition: bandmat.cpp:413
LogAndSign LogDeterminant() const
Definition: bandmat.cpp:404
void ReSize(int, int, int)
Definition: newmat4.cpp:216
void lubksb(Real *, int=0)
Definition: bandmat.cpp:314
MatrixBandWidth BandWidth() const
Definition: bandmat.cpp:530
int Upper() const
Definition: newmat.h:203
int upper
Definition: newmat.h:936
void ChangeSign()
Definition: newmat.h:50
#define REPORT
Definition: bandmat.cpp:24
void operator=(const BaseMatrix &)
Definition: bandmat.cpp:219
void Solver(MatrixColX &, const MatrixColX &)
Definition: bandmat.cpp:376
void operator=(const BaseMatrix &)
Definition: bandmat.cpp:150
MatrixBandWidth operator+(const MatrixBandWidth &) const
Definition: bandmat.cpp:169
void ReSize(int, int)
Definition: bandmat.cpp:449
short SimpleAddOK(const GeneralMatrix *gm)
Definition: bandmat.cpp:64
void Solver(MatrixColX &, const MatrixColX &)
Definition: bandmat.cpp:341