Rev 838 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
966 | MikeW | 1 | /* matmatrix.c |
2 | |||
3 | The following functions are based on the Numerical Recipes. |
||
4 | |||
5 | */ |
||
6 | |||
838 | MikeW | 7 | /***************************************************************************** |
8 | INCLUDES |
||
9 | **************************************************************************** */ |
||
10 | |||
966 | MikeW | 11 | #include <math.h> |
12 | #include <stdio.h> |
||
13 | #include <stdlib.h> |
||
838 | MikeW | 14 | #include <string.h> |
966 | MikeW | 15 | #include "matmatrix.h" |
838 | MikeW | 16 | |
17 | /***************************************************************************** |
||
18 | FUNCTIONS |
||
19 | *****************************************************************************/ |
||
20 | |||
966 | MikeW | 21 | /* **************************************************************************** |
22 | Functionname: matrix_sub */ /*! |
||
23 | Description: C = A - B |
||
838 | MikeW | 24 | |
966 | MikeW | 25 | @param[in] |
26 | |||
27 | @return void |
||
28 | @pre - |
||
29 | @post - |
||
30 | @author Michael Walter |
||
31 | **************************************************************************** */ |
||
32 | void matrix_sub( f32_t **a, f32_t **b, f32_t **c, int m, int n ) |
||
33 | { |
||
34 | int i,j; |
||
35 | f32_t *a_ptr, *b_ptr, *c_ptr; |
||
36 | |||
37 | for( j = 1; j <= m; j++) |
||
38 | { |
||
39 | a_ptr = &a[j][1]; |
||
40 | b_ptr = &b[j][1]; |
||
41 | c_ptr = &c[j][1]; |
||
42 | |||
43 | for( i = 1; i <= n; i++) |
||
44 | { |
||
45 | *c_ptr++ = *a_ptr++ - *b_ptr++; |
||
46 | } |
||
47 | } |
||
48 | } |
||
49 | |||
50 | /* **************************************************************************** |
||
51 | Functionname: matrix_add */ /*! |
||
52 | Description: C = A + B |
||
53 | |||
54 | @param[in] |
||
55 | |||
56 | @return void |
||
57 | @pre - |
||
58 | @post - |
||
59 | @author Michael Walter |
||
60 | **************************************************************************** */ |
||
61 | void matrix_add( f32_t **a, f32_t **b, f32_t **c, int m, int n ) |
||
62 | { |
||
63 | int i,j; |
||
64 | f32_t *a_ptr, *b_ptr, *c_ptr; |
||
65 | |||
66 | for( j = 1; j <= m; j++) |
||
67 | { |
||
68 | a_ptr = &a[j][1]; |
||
69 | b_ptr = &b[j][1]; |
||
70 | c_ptr = &c[j][1]; |
||
71 | |||
72 | for( i = 1; i <= n; i++) |
||
73 | { |
||
74 | *c_ptr++ = *a_ptr++ + *b_ptr++; |
||
75 | } |
||
76 | } |
||
77 | } |
||
78 | |||
79 | /* **************************************************************************** |
||
80 | Functionname: matrix_mult */ /*! |
||
81 | Description: C = A x B |
||
82 | |||
83 | @param[in] |
||
84 | |||
85 | @return void |
||
86 | @pre - |
||
87 | @post - |
||
88 | @author Michael Walter |
||
89 | **************************************************************************** */ |
||
90 | void matrix_mult( f32_t **a, f32_t **b, f32_t **c, |
||
91 | int a_rows, int a_cols, int b_cols ) |
||
92 | { |
||
93 | int i, j, k; |
||
94 | f32_t *a_ptr; |
||
95 | f32_t temp; |
||
96 | |||
97 | for( i = 1; i <= a_rows; i++) |
||
98 | { |
||
99 | a_ptr = &a[i][0]; |
||
100 | for( j = 1; j <= b_cols; j++ ) |
||
101 | { |
||
102 | temp = 0.0; |
||
103 | for( k = 1; k <= a_cols; k++ ) |
||
104 | { |
||
105 | temp = temp + (a_ptr[k] * b[k][j]); |
||
106 | } |
||
107 | c[i][j] = temp; |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | |||
112 | /* **************************************************************************** |
||
113 | Functionname: matrix_mult_transpose */ /*! |
||
114 | Description: C = A x B^T |
||
115 | |||
116 | @param[in] |
||
117 | |||
118 | @return void |
||
119 | @pre - |
||
120 | @post - |
||
121 | @author Michael Walter |
||
122 | **************************************************************************** */ |
||
123 | void matrix_mult_transpose( f32_t **a, f32_t **b, f32_t **c, |
||
124 | int a_rows, int a_cols, int b_cols ) |
||
125 | { |
||
126 | int i, j, k; |
||
127 | f32_t *a_ptr, *b_ptr; |
||
128 | f32_t temp; |
||
129 | |||
130 | for( i = 1; i <= a_rows; i++) |
||
131 | { |
||
132 | a_ptr = &a[i][0]; |
||
133 | for( j = 1; j <= b_cols; j++ ) |
||
134 | { |
||
135 | b_ptr = &b[j][1]; |
||
136 | |||
137 | temp = (f32_t)0; |
||
138 | |||
139 | for( k = 1; k <= a_cols; k++ ) |
||
140 | { |
||
141 | temp += a_ptr[ k ] * *b_ptr++; |
||
142 | } |
||
143 | c[i][j] = temp; |
||
144 | } |
||
145 | } |
||
146 | } |
||
147 | |||
148 | /* **************************************************************************** |
||
149 | Functionname: matrix_mult_transpose */ /*! |
||
150 | Description: C = A^T x B |
||
151 | |||
152 | @param[in] |
||
153 | |||
154 | @return void |
||
155 | @pre - |
||
156 | @post - |
||
157 | @author Michael Walter |
||
158 | **************************************************************************** */ |
||
159 | void matrix_transpose_mult( f32_t **A, f32_t **B, f32_t **C, |
||
160 | int a_rows, int a_cols, int b_cols ) |
||
161 | { |
||
162 | int i, j, k; |
||
163 | f32_t temp; |
||
164 | |||
165 | for( i = 1; i <= a_rows; i++) |
||
166 | { |
||
167 | for( j = 1; j <= b_cols; j++ ) |
||
168 | { |
||
169 | temp = 0.0; |
||
170 | |||
171 | for( k = 1; k <= a_cols; k++ ) |
||
172 | { |
||
173 | temp += A[ k ][ i ] * B[ k ][ j ]; |
||
174 | } |
||
175 | C[ i ][ j ] = temp; |
||
176 | } |
||
177 | } |
||
178 | } |
||
179 | |||
180 | |||
181 | |||
182 | /* **************************************************************************** |
||
183 | Functionname: matrix_copy */ /*! |
||
184 | Description: B = A |
||
185 | |||
186 | @param[in] |
||
187 | |||
188 | @return void |
||
189 | @pre - |
||
190 | @post - |
||
191 | @author Michael Walter |
||
192 | **************************************************************************** */ |
||
193 | void matrix_copy( f32_t **src, f32_t **dst, int num_rows, int num_cols ) |
||
194 | { |
||
195 | int i, j; |
||
196 | |||
197 | for( i = 1; i <= num_rows; i++ ) |
||
198 | { |
||
199 | for( j = 1; j <= num_cols; j++ ) |
||
200 | { |
||
201 | dst[ i ][ j ] = src[ i ][ j ]; |
||
202 | } |
||
203 | } |
||
204 | } |
||
205 | |||
206 | /* **************************************************************************** |
||
207 | Functionname: matrix_alloc */ /*! |
||
208 | Description: B = A |
||
209 | |||
210 | @param[in] |
||
211 | |||
212 | @return void |
||
213 | @pre - |
||
214 | @post - |
||
215 | @author Michael Walter |
||
216 | **************************************************************************** */ |
||
217 | f32_t **matrix(long row_low, long row_high, long col_low, long col_high) |
||
218 | { |
||
219 | long i, NumOfRows=row_high-row_low+1,NumOfCols=col_high-col_low+1; |
||
220 | f32_t **m; |
||
221 | |||
222 | /* allocate pointers to rows */ |
||
223 | m=(f32_t **)malloc((size_t)((NumOfRows+1) |
||
224 | *sizeof(f32_t *))); |
||
225 | m += 1; |
||
226 | m -= row_low; |
||
227 | |||
228 | /* allocate rows and set pointers to them */ |
||
229 | m[row_low]=(f32_t *)malloc((size_t)((NumOfRows*NumOfCols+1) |
||
230 | *sizeof(f32_t))); |
||
231 | m[row_low] += 1; |
||
232 | m[row_low] -= col_low; |
||
233 | |||
234 | for(i=row_low+1;i<=row_high;i++) m[i]=m[i-1]+NumOfCols; |
||
235 | |||
236 | { /* init values with 0.0F */ |
||
237 | int x, y; |
||
238 | for(y = 1; y <= NumOfRows; y++) |
||
239 | { |
||
240 | for(x = 1; x <= NumOfCols; x++) |
||
241 | { |
||
242 | m[y][x] = 0.F; |
||
243 | } |
||
244 | } |
||
245 | } |
||
246 | /* return pointer to array of pointers to rows */ |
||
247 | return m; |
||
248 | } |
||
249 | |||
250 | /* **************************************************************************** |
||
251 | Functionname: free_matrix */ /*! |
||
252 | Description: |
||
253 | |||
254 | @param[in] |
||
255 | |||
256 | @return void |
||
257 | @pre - |
||
258 | @post - |
||
259 | @author Michael Walter |
||
260 | **************************************************************************** */ |
||
261 | void free_matrix(f32_t **m, long row_low, long row_high, long col_low, long col_high) |
||
262 | /* free a matrix allocated by matrix() */ |
||
263 | { |
||
264 | free((char*) (m[row_low]+col_low-1)); |
||
265 | free((char*) (m+row_low-1)); |
||
266 | } |
||
267 | |||
268 | |||
269 | /* **************************************************************************** |
||
270 | Functionname: take_inverse */ /*! |
||
271 | Description: B = A^-1 |
||
272 | |||
273 | @param[in] |
||
274 | |||
275 | @return void |
||
276 | @pre - |
||
277 | @post - |
||
278 | @author Michael Walter |
||
279 | **************************************************************************** */ |
||
280 | void take_inverse( f32_t **A, f32_t **B, int size) |
||
281 | { |
||
282 | gaussj( A, size, B); |
||
283 | matrix_copy( A, B, size, size); |
||
284 | } |
||
285 | |||
286 | |||
287 | /* gaussj() |
||
288 | This function performs gauss-jordan elimination to solve a set |
||
289 | of linear equations, at the same time generating the inverse of |
||
290 | the A matrix. |
||
291 | |||
292 | (C) Copr. 1986-92 Numerical Recipes Software `2$m.1.9-153. |
||
293 | */ |
||
294 | |||
295 | #define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;} |
||
296 | |||
297 | void gaussj(f32_t **a, int n, f32_t **b) |
||
298 | { |
||
299 | int i,icol,irow,j,k,l,ll; |
||
300 | f32_t big,dum,pivinv,temp; |
||
301 | |||
302 | int indxc[5]; |
||
303 | int indxr[5]; |
||
304 | int ipiv[5]; |
||
305 | |||
306 | irow = 0; |
||
307 | icol = 0; |
||
308 | |||
309 | for (j=1;j<=n;j++) |
||
310 | { |
||
311 | ipiv[j]=0; |
||
312 | } |
||
313 | |||
314 | for (i=1;i<=n;i++) |
||
315 | { |
||
316 | big=0.0; |
||
317 | for (j=1;j<=n;j++) |
||
318 | { |
||
319 | if (ipiv[j] != 1) |
||
320 | { |
||
321 | for (k=1;k<=n;k++) |
||
322 | { |
||
323 | if (ipiv[k] == 0) |
||
324 | { |
||
325 | if (fabs(a[j][k]) >= big) |
||
326 | { |
||
327 | big=fabs(a[j][k]); |
||
328 | irow=j; |
||
329 | icol=k; |
||
330 | } |
||
331 | } |
||
332 | } |
||
333 | } |
||
334 | } |
||
335 | ++(ipiv[icol]); |
||
336 | if (irow != icol) |
||
337 | { |
||
338 | for (l=1;l<=n;l++) |
||
339 | { |
||
340 | SWAP(a[irow][l],a[icol][l]) |
||
341 | } |
||
342 | } |
||
343 | indxr[i]=irow; |
||
344 | indxc[i]=icol; |
||
345 | |||
346 | pivinv=1.0/a[icol][icol]; |
||
347 | a[icol][icol]=1.0; |
||
348 | for (l=1;l<=n;l++) |
||
349 | { |
||
350 | a[icol][l] *= pivinv; |
||
351 | } |
||
352 | for (ll=1;ll<=n;ll++) |
||
353 | { |
||
354 | if (ll != icol) |
||
355 | { |
||
356 | dum=a[ll][icol]; |
||
357 | a[ll][icol]=0.0; |
||
358 | for (l=1;l<=n;l++) |
||
359 | { |
||
360 | a[ll][l] -= a[icol][l]*dum; |
||
361 | } |
||
362 | } |
||
363 | } |
||
364 | } |
||
365 | for (l=n;l>=1;l--) |
||
366 | { |
||
367 | if (indxr[l] != indxc[l]) |
||
368 | { |
||
369 | for (k=1;k<=n;k++) |
||
370 | { |
||
371 | SWAP(a[k][indxr[l]],a[k][indxc[l]]); |
||
372 | } |
||
373 | } |
||
374 | } |
||
375 | } |
||
376 | #undef SWAP |
||
377 | |||
378 |