A Survey of Gaussian Convolution Algorithms
invert_matrix.c
Go to the documentation of this file.
1 
20 #include "invert_matrix.h"
21 #include <assert.h>
22 #include <math.h>
23 #include <stdlib.h>
24 
37 int invert_matrix(double *inv_A, double *A, int N)
38 {
39  double *c = NULL, *d = NULL, *col_j, *col_k, *inv_col_k;
40  double temp, scale, sum;
41  int i, j, k, success = 0;
42 
43  assert(inv_A && A && N > 0);
44 
45  if (!(c = (double *)malloc(sizeof(double) * N))
46  || !(d = (double *)malloc(sizeof(double) * N)))
47  goto fail;
48 
49  for (k = 0, col_k = A; k < N - 1; ++k, col_k += N)
50  {
51  scale = 0.0;
52 
53  for (i = k; i < N; ++i)
54  if ((temp = fabs(col_k[i])) > scale)
55  scale = temp;
56 
57  if (scale == 0.0)
58  goto fail; /* Singular matrix */
59 
60  for (i = k; i < N; ++i)
61  col_k[i] /= scale;
62 
63  for (sum = 0.0, i = k; i < N; ++i)
64  sum += col_k[i]*col_k[i];
65 
66  temp = (col_k[k] >= 0.0) ? sqrt(sum) : -sqrt(sum);
67  col_k[k] += temp;
68  c[k] = temp * col_k[k];
69  d[k] = -scale * temp;
70 
71  for (j = k + 1, col_j = col_k + N; j < N; ++j, col_j += N)
72  {
73  for (scale = 0.0, i = k; i < N; ++i)
74  scale += col_k[i] * col_j[i];
75 
76  scale /= c[k];
77 
78  for (i = k; i < N; ++i)
79  col_j[i] -= scale * col_k[i];
80  }
81  }
82 
83  d[N-1] = col_k[k];
84 
85  if (d[N - 1] == 0.0)
86  goto fail; /* Singular matrix */
87 
88  for (k = 0, inv_col_k = inv_A; k < N; ++k, inv_col_k += N)
89  {
90  for (i = 0; i < N; ++i)
91  inv_col_k[i] = -A[k] * A[i] / c[0];
92 
93  inv_col_k[k] += 1.0;
94 
95  for (j = 1, col_j = A + N; j < N-1; ++j, col_j += N)
96  {
97  for (scale = 0.0, i = j; i < N; ++i)
98  scale += col_j[i] * inv_col_k[i];
99 
100  scale /= c[j];
101 
102  for (i = j; i < N; ++i)
103  inv_col_k[i] -= scale * col_j[i];
104  }
105 
106  inv_col_k[j] /= d[N-1];
107 
108  for (i = N - 2; i >= 0; --i)
109  {
110  for (sum = 0.0, j = i + 1, col_j = A + N*(i + 1);
111  j < N; ++j, col_j += N)
112  sum += col_j[i] * inv_col_k[j];
113 
114  inv_col_k[i] = (inv_col_k[i] - sum) / d[i];
115  }
116  }
117 
118  success = 1; /* Finished successfully */
119 fail: /* Clean up */
120  free(d);
121  free(c);
122  return success;
123 }