QwAnalysis
matrix.cc File Reference
#include "matrix.h"
+ Include dependency graph for matrix.cc:

Go to the source code of this file.

Macros

#define DBL_EPSILON   2.22045e-16
 

Functions

double * V_Zero (double *v, const int n)
 
double * V_Unit (double *v, const int n, const int k)
 
void V_Print (const double *v, const int n)
 
void V_Print (const double *v, const double *w, const int n)
 
double UNorm (const double *A, int n, const int m)
 Calculates the least upper bound norm. More...
 
double * M_Cholesky (double *B, double *q, const int n)
 Calculates the Cholesky decomposition of the positive-definite matrix B. More...
 
void RowMult (const double a, double *A, const double b, const double *B, const int n)
 Calculates a*A + b*B, where both A and B are rows of length n, returns as A. More...
 
void M_Print (const double *A, const int n)
 Print matrix A of dimension [n,n] to cout. More...
 
void M_Print (const double *A, const double *B, const int n)
 Print matrices A and B of dimension [n,n] to cout. More...
 
double * M_Unit (double *A, const int n)
 Creates unit matrix A. More...
 
double * M_Zero (double *A, const int n)
 Creates zero matrix A. More...
 
double * M_Invert (double *Ap, double *Bp, const int n)
 Matrix inversion of Ap will be stored in Bp. More...
 
double * M_InvertPos (double *B, const int n)
 Calculates a*A + b*B, where both A and B are rows of length n. More...
 
double * M_A_times_b (double *y, const double *A, const int n, const int m, const double *b)
 Calculates y[n] = A[n,m] * b[m], with dimensions indicated. More...
 

Macro Definition Documentation

#define DBL_EPSILON   2.22045e-16

Definition at line 3 of file matrix.cc.

Referenced by M_Cholesky().

Function Documentation

double* M_A_times_b ( double *  y,
const double *  A,
const int  n,
const int  m,
const double *  b 
)

Calculates y[n] = A[n,m] * b[m], with dimensions indicated.

Definition at line 443 of file matrix.cc.

References Qw::m.

Referenced by QwTrackingTreeCombine::r2_PartialTrackFit().

444 {
445  for (int i = 0; i < n; i++) {
446  y[i] = 0;
447  for (int j = 0; j < m; j++) {
448  y[i] += A[i*n+j] * b[j];
449  }
450  }
451  return y;
452 }
static const double m
Definition: QwUnits.h:63

+ Here is the caller graph for this function:

double* M_Cholesky ( double *  B,
double *  q,
const int  n 
)

Calculates the Cholesky decomposition of the positive-definite matrix B.

Definition at line 76 of file matrix.cc.

References DBL_EPSILON, Qw::min, and UNorm().

Referenced by M_InvertPos().

77 {
78  int i, j, k;
79  double sum, min;
80  double *C = B;
81  double A[n][n];
82  double p[n],*pp;
83 
84  for(i=0;i<n;i++){
85  for(j=0;j<n;j++){
86  A[i][j]=*C;
87  C++;
88  }
89  }
90 
91  min = UNorm (B, n, n) * n * DBL_EPSILON;
92  for( i = 0; i < n; i++ ) {
93  for( j = i; j < n; j++ ) {
94  sum = A[i][j];
95  for( k = i-1; k >= 0; k-- )
96  sum -= A[i][k] * A[j][k];
97  if( i == j ) {
98  if( sum < min ) {
99  return 0;
100  }
101  p[i] = sqrt(sum);
102  } else
103  A[j][i] = sum/p[i];
104  }
105  }
106  C = B;
107  pp=q;
108  for(i=0;i<n;i++){
109  *p = p[i];
110  pp++;
111  for(j=0;j<n;j++){
112  *C = A[i][j];
113  C++;
114  }
115  }
116  C = B;
117  pp = q;
118  return B;
119 }
#define DBL_EPSILON
Definition: matrix.cc:3
double UNorm(const double *A, int n, const int m)
Calculates the least upper bound norm.
Definition: matrix.cc:51
static const double min
Definition: QwUnits.h:76

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double* M_Invert ( double *  Ap,
double *  Bp,
const int  n 
)

Matrix inversion of Ap will be stored in Bp.

Definition at line 240 of file matrix.cc.

References M_Unit(), and RowMult().

Referenced by QwTrackingTreeCombine::r2_PartialTrackFit().

241 {
242  double *row1, *row2;
243  double a, b;
244 
245  // Initialize B to unit matrix (wdc: assumed n = 4 here)
246  M_Unit (Bp, n);
247 
248  // Print matrices Ap and Bp
249  //M_Print (Ap, Bp, n);
250 
251  // This will not be generalized for nxn matrices.
252  // (wdc: TODO faster algs could be useful later)
253  if (n == 2) {
254  double det = (Ap[0] * Ap[3]) - (Ap[1] * Ap[2]);
255  Bp[0] = Ap[0] / det;
256  Bp[1] = -Ap[1] / det;
257  Bp[2] = -Ap[2] / det;
258  Bp[3] = Ap[3] / det;
259  }
260 
261  if (n == 4) {
262  // Calculate inverse matrix using row-reduce method.
263  // (No safety for singular matrices!)
264 
265  // get A10 to An0 to be zero.
266  for (int i = 1; i < n; i++) {
267  a = -(Ap[0]);
268  b = Ap[i*n];
269  row1 = &(Ap[i*n]);
270  row2 = &(Ap[0]);
271  RowMult(a, row1, b, row2, 4);
272  row1 = &(Bp[i*n]);
273  row2 = &(Bp[0]);
274  RowMult(a, row1, b, row2, 4);
275  }
276 
277  // get A21 and A31 to be zero
278  for (int i = 2; i < n; i++) {
279  a = -(Ap[5]);
280  b = Ap[i*n+1];
281  row1 = &(Ap[i*n]);
282  row2 = &(Ap[4]);
283  RowMult(a, row1, b, row2, 4);
284  row1 = &(Bp[i*n]);
285  row2 = &(Bp[4]);
286  RowMult(a, row1, b, row2, 4);
287  }
288 
289  // get A32 to be zero
290  a = -(Ap[10]);
291  b = Ap[14];
292  row1 = &(Ap[12]);
293  row2 = &(Ap[8]);
294  RowMult(a, row1, b, row2, 4);
295  row1 = &(Bp[12]);
296  row2 = &(Bp[8]);
297  RowMult(a, row1, b, row2, 4);
298 
299  // Now the matrix is upper right triangular.
300 
301  // row reduce the 4th row
302  a = 1/(Ap[15]);
303  row1 = &(Ap[12]);
304  RowMult(a, row1, 0, row2, 4);
305  row1 = &(Bp[12]);
306  RowMult(a, row1, 0, row2, 4);
307 
308  // get A03 to A23 to be zero
309  for (int i = 0; i < n-1; i++) {
310  a = -(Ap[15]);
311  b = Ap[i*n+3];
312  row1 = &(Ap[i*n]);
313  row2 = &(Ap[12]);
314  RowMult(a, row1, b, row2, 4);
315  row1 = &(Bp[i*n]);
316  row2 = &(Bp[12]);
317  RowMult(a, row1, b, row2, 4);
318  }
319 
320  // row reduce the 3rd row
321  a = 1/(Ap[10]);
322  row1 = &(Ap[8]);
323  RowMult(a, row1, 0, row2, 4);
324  row1 = &(Bp[8]);
325  RowMult(a, row1, 0, row2, 4);
326 
327  // get A02 and A12 to be zero
328  for (int i = 0; i < 2; i++) {
329  a = -(Ap[10]);
330  b = Ap[i*n+2];
331  row1 = &(Ap[i*n]);
332  row2 = &(Ap[8]);
333  RowMult(a, row1, b, row2, 4);
334  row1 = &(Bp[i*n]);
335  row2 = &(Bp[8]);
336  RowMult(a, row1, b, row2, 4);
337  }
338 
339  // row reduce the 2nd row
340  a = 1/(Ap[5]);
341  row1 = &(Ap[4]);
342  RowMult(a, row1, 0, row2, n);
343  row1 = &(Bp[4]);
344  RowMult(a, row1, 0, row2, n);
345 
346  // get A01 to be zero
347  a = -(Ap[5]);
348  b = Ap[1];
349  row1 = &(Ap[0]);
350  row2 = &(Ap[4]);
351  RowMult(a, row1, b, row2, n);
352  row1 = &(Bp[0]);
353  row2 = &(Bp[4]);
354  RowMult(a, row1, b, row2, n);
355 
356  // row reduce 1st row
357  a = 1/(Ap[0]);
358  row1 = &(Ap[0]);
359  RowMult(a, row1, 0, row2, n);
360  row1 = &(Bp[0]);
361  RowMult(a, row1, 0, row2, n);
362  }
363 
364  return Bp;
365 }
void RowMult(const double a, double *A, const double b, const double *B, const int n)
Calculates a*A + b*B, where both A and B are rows of length n, returns as A.
Definition: matrix.cc:130
double * M_Unit(double *A, const int n)
Creates unit matrix A.
Definition: matrix.cc:199

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double* M_InvertPos ( double *  B,
const int  n 
)

Calculates a*A + b*B, where both A and B are rows of length n.

Definition at line 376 of file matrix.cc.

References M_Cholesky().

377 {
378  double sum;
379  double p[n];
380  double q[n];
381  double inv[n][n];
382  double *pp = NULL;
383  double A[n][n],*C;
384 
385  // First we find the cholesky decomposition of B
386  if (M_Cholesky(B, pp, n)) {
387 
388  C = B;
389  for (int i = 0; i < n; i++) {
390  p[i] = *q;
391  for (int j = 0; j < n; j++ ) {
392  A[i][j] = *C;
393  C++;
394  }
395  }
396 
397  for (int i = 0; i < n; i++) {
398  A[i][i] = 1.0 / p[i];
399  for (int j = i+1; j < n; j++) {
400  sum = 0;
401  for (int k = i; k < j; k++)
402  sum -= A[j][k] * A[k][i];
403  A[j][i] = sum / p[j];
404  }
405  }
406 
407  for (int i = 0; i < n; i++) {
408  for (int j = i; j < n; j++) {
409  sum = 0;
410  for (int k = j; k < n; k++)
411  sum += A[k][i] * A[k][j];
412  inv[i][j] = inv[j][i] = sum;
413  }
414  }
415 
416  C = B;
417  for (int i = 0; i < n; i++) {
418  for (int j = 0; j < n; j++) {
419  *C = inv[i][j];
420  C++;
421  }
422  }
423 
424  } else {
425  B = 0;
426  std::cout << "Cholesky decomposition failed!" << std::endl;
427  }
428 
429  C = B;
430 
431  return B;
432 }
double * M_Cholesky(double *B, double *q, const int n)
Calculates the Cholesky decomposition of the positive-definite matrix B.
Definition: matrix.cc:76

+ Here is the call graph for this function:

void M_Print ( const double *  A,
const int  n 
)

Print matrix A of dimension [n,n] to cout.

Definition at line 147 of file matrix.cc.

148 {
149  // Print matrix A
150  for (int i = 0; i < n; i++) {
151  std::cout << "[";
152  for (int j = 0; j < n; j++) {
153  std::cout << A[i*n+j] << ' ';
154  }
155  std::cout << ']' << std::endl;
156  }
157  std::cout << std::endl;
158 
159  return;
160 }
void M_Print ( const double *  A,
const double *  B,
const int  n 
)

Print matrices A and B of dimension [n,n] to cout.

Definition at line 171 of file matrix.cc.

172 {
173  // Print matrices A and B
174  for (int i = 0; i < n; i++) {
175  std::cout << "[";
176  for (int j = 0; j < n; j++) {
177  std::cout << A[i*n+j] << ' ';
178  }
179  std::cout << '|' ;
180  for (int j = 0; j < n; j++) {
181  std::cout << B[i*n+j] << ' ';
182  }
183  std::cout << ']' << std::endl;
184  }
185  std::cout << std::endl;
186 
187  return;
188 }
double* M_Unit ( double *  A,
const int  n 
)

Creates unit matrix A.

Definition at line 199 of file matrix.cc.

Referenced by M_Invert().

200 {
201  for (int i = 0; i < n; i++) {
202  for (int j = 0; j < n; j++) {
203  A[i*n+j] = 0;
204  }
205  A[i*n+i] = 1;
206  }
207 
208  return A;
209 }

+ Here is the caller graph for this function:

double* M_Zero ( double *  A,
const int  n 
)

Creates zero matrix A.

Definition at line 220 of file matrix.cc.

221 {
222  for (int i = 0; i < n; i++) {
223  for (int j = 0; j < n; j++) {
224  A[i*n+j] = 0;
225  }
226  }
227 
228  return A;
229 }
void RowMult ( const double  a,
double *  A,
const double  b,
const double *  B,
const int  n 
)

Calculates a*A + b*B, where both A and B are rows of length n, returns as A.

Definition at line 130 of file matrix.cc.

Referenced by M_Invert().

131 {
132  for (int i = 0; i < n; i++)
133  A[i] = a*A[i] + b*B[i];
134 
135  return;
136 }

+ Here is the caller graph for this function:

double UNorm ( const double *  A,
int  n,
const int  m 
)

Calculates the least upper bound norm.

Definition at line 51 of file matrix.cc.

References Qw::m.

Referenced by M_Cholesky().

52 {
53  int counter;
54  double help, Max = 0.0;
55  const double *B = A;
56  while (n--) {
57  counter = m;
58  while (counter--) {
59  B = A + n + counter;
60  if (Max < (help = fabs (*(B))))
61  Max = help;
62  }
63  }
64  return Max;
65 }
static const double m
Definition: QwUnits.h:63

+ Here is the caller graph for this function:

void V_Print ( const double *  v,
const int  n 
)

Definition at line 22 of file matrix.cc.

23 {
24  // Print vector v
25  for (int i = 0; i < n; i++) {
26  std::cout << v[i];
27  }
28  std::cout << std::endl;
29  return;
30 }
void V_Print ( const double *  v,
const double *  w,
const int  n 
)

Definition at line 32 of file matrix.cc.

33 {
34  // Print vector v and w
35  for (int i = 0; i < n; i++) {
36  std::cout << v[i] << " | " << w[i];
37  }
38  std::cout << std::endl;
39  return;
40 }
double* V_Unit ( double *  v,
const int  n,
const int  k 
)

Definition at line 13 of file matrix.cc.

14 {
15  for (int i = 0; i < n; i++) {
16  v[i] = 0.0;
17  }
18  v[k] = 1.0;
19  return v;
20 }
double* V_Zero ( double *  v,
const int  n 
)

Definition at line 5 of file matrix.cc.

6 {
7  for (int i = 0; i < n; i++) {
8  v[i] = 0.0;
9  }
10  return v;
11 }