OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
hholder.cpp
Go to the documentation of this file.
1 //$$ hholder.cpp QR decomposition
2 
3 // Copyright (C) 1991,2,3,4: R B Davies
4 
5 #define WANT_MATH
6 //#define WANT_STREAM
7 
8 #include <cmath>
9 #include <ossim/matrix/include.h>
10 
11 #include <ossim/matrix/newmatap.h>
12 
13 #ifdef use_namespace
14 namespace NEWMAT {
15 #endif
16 
17 #ifdef DO_REPORT
18 #define REPORT { static ExeCounter ExeCount(__LINE__,16); ++ExeCount; }
19 #else
20 #define REPORT {}
21 #endif
22 
23 
24 /*************************** QR decompositions ***************************/
25 
26 inline Real square(Real x) { return x*x; }
27 
29 {
30  REPORT
31  Tracer et("QRZT(1)");
32  int n = X.Ncols(); int s = X.Nrows(); L.ReSize(s);
33  Real* xi = X.Store(); int k;
34  for (int i=0; i<s; i++)
35  {
36  Real sum = 0.0;
37  Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
38  sum = std::sqrt(sum);
39  if (sum == 0.0)
40  {
41  REPORT
42  k=n; while(k--) { *xi0++ = 0.0; }
43  for (int j=i; j<s; j++) L.element(j,i) = 0.0;
44  }
45  else
46  {
47  L.element(i,i) = sum;
48  Real* xj0=xi0; k=n; while(k--) { *xj0++ /= sum; }
49  for (int j=i+1; j<s; j++)
50  {
51  sum=0.0;
52  xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
53  xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
54  L.element(j,i) = sum;
55  }
56  }
57  }
58 }
59 
60 void QRZT(const Matrix& X, Matrix& Y, Matrix& M)
61 {
62  REPORT
63  Tracer et("QRZT(2)");
64  int n = X.Ncols(); int s = X.Nrows(); int t = Y.Nrows();
65  if (Y.Ncols() != n)
66  { Throw(ProgramException("Unequal row lengths",X,Y)); }
67  M.ReSize(t,s);
68  Real* xi = X.Store(); int k;
69  for (int i=0; i<s; i++)
70  {
71  Real* xj0 = Y.Store(); Real* xi0 = xi;
72  for (int j=0; j<t; j++)
73  {
74  Real sum=0.0;
75  xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
76  xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
77  M.element(j,i) = sum;
78  }
79  }
80 }
81 
82 /*
83 void QRZ(Matrix& X, UpperTriangularMatrix& U)
84 {
85  Tracer et("QRZ(1)");
86  int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s);
87  Real* xi0 = X.Store(); int k;
88  for (int i=0; i<s; i++)
89  {
90  Real sum = 0.0;
91  Real* xi = xi0; k=n; while(k--) { sum += square(*xi); xi+=s; }
92  sum = std::sqrt(sum);
93  U.element(i,i) = sum;
94  if (sum==0.0) Throw(SingularException(U));
95  Real* xj0=xi0; k=n; while(k--) { *xj0 /= sum; xj0+=s; }
96  xj0 = xi0;
97  for (int j=i+1; j<s; j++)
98  {
99  sum=0.0;
100  xi=xi0; k=n; xj0++; Real* xj=xj0;
101  while(k--) { sum += *xi * *xj; xi+=s; xj+=s; }
102  xi=xi0; k=n; xj=xj0;
103  while(k--) { *xj -= sum * *xi; xj+=s; xi+=s; }
104  U.element(i,j) = sum;
105  }
106  xi0++;
107  }
108 }
109 */
110 
112 {
113  REPORT
114  Tracer et("QRZ(1)");
115  int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); U = 0.0;
116  Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
117  int j, k; int J = s; int i = s;
118  while (i--)
119  {
120  Real* xj0 = xi0; Real* xi = xi0; k = n;
121  if (k) for (;;)
122  {
123  u = u0; Real Xi = *xi; Real* xj = xj0;
124  j = J; while(j--) *u++ += Xi * *xj++;
125  if (!(--k)) break;
126  xi += s; xj0 += s;
127  }
128 
129  Real sum = std::sqrt(*u0); *u0 = sum; u = u0+1;
130  if (sum == 0.0)
131  {
132  REPORT
133  j = J - 1; while(j--) *u++ = 0.0;
134 
135  xj0 = xi0++; k = n;
136  if (k) for (;;)
137  {
138  *xj0 = 0.0;
139  if (!(--k)) break;
140  xj0 += s;
141  }
142  u0 += J--;
143  }
144  else
145  {
146  int J1 = J-1; j = J1; while(j--) *u++ /= sum;
147 
148  xj0 = xi0; xi = xi0++; k = n;
149  if (k) for (;;)
150  {
151  u = u0+1; Real Xi = *xi; Real* xj = xj0;
152  Xi /= sum; *xj++ = Xi;
153  j = J1; while(j--) *xj++ -= *u++ * Xi;
154  if (!(--k)) break;
155  xi += s; xj0 += s;
156  }
157  u0 += J--;
158  }
159  }
160 }
161 
162 void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
163 {
164  REPORT
165  Tracer et("QRZ(2)");
166  int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
167  if (Y.Nrows() != n)
168  { Throw(ProgramException("Unequal column lengths",X,Y)); }
169  M.ReSize(s,t); M = 0;Real* m0 = M.Store(); Real* m;
170  Real* xi0 = X.Store();
171  int j, k; int i = s;
172  while (i--)
173  {
174  Real* xj0 = Y.Store(); Real* xi = xi0; k = n;
175  if (k) for (;;)
176  {
177  m = m0; Real Xi = *xi; Real* xj = xj0;
178  j = t; while(j--) *m++ += Xi * *xj++;
179  if (!(--k)) break;
180  xi += s; xj0 += t;
181  }
182 
183  xj0 = Y.Store(); xi = xi0++; k = n;
184  if (k) for (;;)
185  {
186  m = m0; Real Xi = *xi; Real* xj = xj0;
187  j = t; while(j--) *xj++ -= *m++ * Xi;
188  if (!(--k)) break;
189  xi += s; xj0 += t;
190  }
191  m0 += t;
192  }
193 }
194 
195 /*
196 
197 void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
198 {
199  Tracer et("QRZ(2)");
200  int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
201  if (Y.Nrows() != n)
202  { Throw(ProgramException("Unequal column lengths",X,Y)); }
203  M.ReSize(s,t);
204  Real* xi0 = X.Store(); int k;
205  for (int i=0; i<s; i++)
206  {
207  Real* xj0 = Y.Store();
208  for (int j=0; j<t; j++)
209  {
210  Real sum=0.0;
211  Real* xi=xi0; Real* xj=xj0; k=n;
212  while(k--) { sum += *xi * *xj; xi+=s; xj+=t; }
213  xi=xi0; k=n; xj=xj0++;
214  while(k--) { *xj -= sum * *xi; xj+=t; xi+=s; }
215  M.element(i,j) = sum;
216  }
217  xi0++;
218  }
219 }
220 */
221 
223 {
224  REPORT
225  Tracer et("UpdateQRZT");
226  int n = X.Ncols(); int s = X.Nrows();
227  if (s != L.Nrows())
228  Throw(ProgramException("Incompatible dimensions",X,L));
229  Real* xi = X.Store(); int k;
230  for (int i=0; i<s; i++)
231  {
232  Real r = L.element(i,i);
233  Real sum = 0.0;
234  Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
235  sum = std::sqrt(sum + square(r));
236  if (sum == 0.0)
237  {
238  REPORT
239  k=n; while(k--) { *xi0++ = 0.0; }
240  for (int j=i; j<s; j++) L.element(j,i) = 0.0;
241  }
242  else
243  {
244  Real frs = std::fabs(r) + sum;
245  Real a0 = std::sqrt(frs / sum); Real alpha = a0 / frs;
246  if (r <= 0) { REPORT L.element(i,i) = sum; alpha = -alpha; }
247  else { REPORT L.element(i,i) = -sum; }
248  Real* xj0=xi0; k=n; while(k--) { *xj0++ *= alpha; }
249  for (int j=i+1; j<s; j++)
250  {
251  sum = 0.0;
252  xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
253  sum += a0 * L.element(j,i);
254  xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
255  L.element(j,i) -= sum * a0;
256  }
257  }
258  }
259 }
260 
262 {
263  REPORT
264  Tracer et("UpdateQRZ");
265  int n = X.Nrows(); int s = X.Ncols();
266  if (s != U.Ncols())
267  Throw(ProgramException("Incompatible dimensions",X,U));
268  Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
269  RowVector V(s); Real* v0 = V.Store(); Real* v; V = 0.0;
270  int j, k; int J = s; int i = s;
271  while (i--)
272  {
273  Real* xj0 = xi0; Real* xi = xi0; k = n;
274  if (k) for (;;)
275  {
276  v = v0; Real Xi = *xi; Real* xj = xj0;
277  j = J; while(j--) *v++ += Xi * *xj++;
278  if (!(--k)) break;
279  xi += s; xj0 += s;
280  }
281 
282  Real r = *u0;
283  Real sum = std::sqrt(*v0 + square(r));
284 
285  if (sum == 0.0)
286  {
287  REPORT
288  u = u0; v = v0;
289  j = J; while(j--) { *u++ = 0.0; *v++ = 0.0; }
290  xj0 = xi0++; k = n;
291  if (k) for (;;)
292  {
293  *xj0 = 0.0;
294  if (!(--k)) break;
295  xj0 += s;
296  }
297  u0 += J--;
298  }
299  else
300  {
301  Real frs = std::fabs(r) + sum;
302  Real a0 = std::sqrt(frs / sum); Real alpha = a0 / frs;
303  if (r <= 0) { REPORT alpha = -alpha; *u0 = sum; }
304  else { REPORT *u0 = -sum; }
305 
306  j = J - 1; v = v0 + 1; u = u0 + 1;
307  while (j--)
308  { *v = a0 * *u + alpha * *v; *u -= a0 * *v; ++v; ++u; }
309 
310  xj0 = xi0; xi = xi0++; k = n;
311  if (k) for (;;)
312  {
313  v = v0 + 1; Real Xi = *xi; Real* xj = xj0;
314  Xi *= alpha; *xj++ = Xi;
315  j = J - 1; while(j--) *xj++ -= *v++ * Xi;
316  if (!(--k)) break;
317  xi += s; xj0 += s;
318  }
319 
320  j = J; v = v0;
321  while (j--) *v++ = 0.0;
322 
323  u0 += J--;
324  }
325  }
326 }
327 
328 
329 #ifdef use_namespace
330 }
331 #endif
332 
ossim_uint32 x
double Real
Definition: include.h:57
void QRZT(Matrix &X, LowerTriangularMatrix &L)
Definition: hholder.cpp:28
Real & element(int, int)
Definition: newmat6.cpp:709
int Ncols() const
Definition: newmat.h:431
Real & element(int, int)
Definition: newmat6.cpp:659
virtual void ReSize(int, int)
Definition: newmat4.cpp:233
os2<< "> n<< " > nendobj n
Real square(Real x)
Definition: hholder.cpp:26
void UpdateQRZT(Matrix &X, LowerTriangularMatrix &L)
Definition: hholder.cpp:222
#define REPORT
Definition: hholder.cpp:20
Definition: newmat.h:543
void QRZ(Matrix &X, UpperTriangularMatrix &U)
Definition: hholder.cpp:111
int Nrows() const
Definition: newmat.h:430
Real * Store() const
Definition: newmat.h:433
void UpdateQRZ(Matrix &X, UpperTriangularMatrix &U)
Definition: hholder.cpp:261