small_linalg.h
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
33 #ifndef __small_linalg_h__
34 #define __small_linalg_h__
35 
36 // convenience functions for small linear algebra operations
37 
38 #include <stdio.h>
39 #include <math.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 static inline double
46 matrix_determinant_3x3d (const double m[9])
47 {
48  return m[0]*(m[4]*m[8] - m[5]*m[7])
49  - m[1]*(m[3]*m[8] - m[5]*m[6])
50  + m[2]*(m[3]*m[7] - m[4]*m[6]);
51 }
52 
53 int matrix_inverse_4x4d (const double m[16], double inv[16]);
54 
55 // returns 0 on success, -1 if matrix is singular
56 static inline int
57 matrix_inverse_3x3d (const double m[9], double inverse[9])
58 {
59  double det = matrix_determinant_3x3d (m);
60  if (det == 0) return -1;
61  double det_inv = 1.0 / det;
62  inverse[0] = det_inv * (m[4]*m[8] - m[5]*m[7]);
63  inverse[1] = det_inv * (m[2]*m[7] - m[1]*m[8]);
64  inverse[2] = det_inv * (m[1]*m[5] - m[2]*m[4]);
65  inverse[3] = det_inv * (m[5]*m[6] - m[3]*m[8]);
66  inverse[4] = det_inv * (m[0]*m[8] - m[2]*m[6]);
67  inverse[5] = det_inv * (m[2]*m[3] - m[0]*m[5]);
68  inverse[6] = det_inv * (m[3]*m[7] - m[4]*m[6]);
69  inverse[7] = det_inv * (m[1]*m[6] - m[0]*m[7]);
70  inverse[8] = det_inv * (m[0]*m[4] - m[1]*m[3]);
71 
72  return 0;
73 }
74 
75 static inline int
76 matrix_inverse_2x2d(const double m[4], double inverse[4])
77 {
78  double det = m[0]*m[3] - m[1]*m[2];
79  if (det == 0) return -1;
80 
81  inverse[0] = m[3] / det;
82  inverse[1] = -m[1] / det;
83  inverse[2] = -m[2] / det;
84  inverse[3] = m[0] / det;
85  return 0;
86 }
87 
88 static inline void
89 matrix_vector_multiply_2x2_2d (const double m[4], const double v[2],
90  double result[2])
91 {
92  result[0] = m[0]*v[0] + m[1]*v[1];
93  result[1] = m[2]*v[0] + m[3]*v[1];
94 }
95 
96 static inline void
97 matrix_vector_multiply_3x3_3d (const double m[9], const double v[3],
98  double result[3])
99 {
100  result[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2];
101  result[1] = m[3]*v[0] + m[4]*v[1] + m[5]*v[2];
102  result[2] = m[6]*v[0] + m[7]*v[1] + m[8]*v[2];
103 }
104 
105 static inline void
106 matrix_vector_multiply_4x4_4d (const double m[16], const double v[4],
107  double result[4])
108 {
109  result[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2] + m[3]*v[3];
110  result[1] = m[4]*v[0] + m[5]*v[1] + m[6]*v[2] + m[7]*v[3];
111  result[2] = m[8]*v[0] + m[9]*v[1] + m[10]*v[2] + m[11]*v[3];
112  result[3] = m[12]*v[0] + m[13]*v[1] + m[14]*v[2] + m[15]*v[3];
113 }
114 
115 static inline void
116 vector_add_3d (const double v1[3], const double v2[3], double result[3])
117 {
118  result[0] = v1[0] + v2[0];
119  result[1] = v1[1] + v2[1];
120  result[2] = v1[2] + v2[2];
121 }
122 
123 static inline void
124 vector_add_nd (const double * v1, const double * v2, int N, double * result)
125 {
126  int i;
127  for (i = 0; i < N; i++)
128  result[i] = v1[i] + v2[i];
129 }
130 
131 static inline void
132 vector_sub_nd (const double * v1, const double * v2, int N, double * result)
133 {
134  int i;
135  for (i = 0; i < N; i++)
136  result[i] = v1[i] - v2[i];
137 }
138 
144 static inline void
145 vector_subtract_3d (const double v1[3], const double v2[3], double result[3])
146 {
147  result[0] = v1[0] - v2[0];
148  result[1] = v1[1] - v2[1];
149  result[2] = v1[2] - v2[2];
150 }
151 
152 static inline double
153 vector_dot_2d (const double v1[2], const double v2[2])
154 {
155  return v1[0]*v2[0] + v1[1]*v2[1];
156 }
157 
158 static inline double
159 vector_dot_3d (const double v1[3], const double v2[3])
160 {
161  return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
162 }
163 
164 static inline void
165 vector_cross_3d (const double v1[3], const double v2[3], double result[3])
166 {
167  result[0] = v1[1]*v2[2] - v1[2]*v2[1];
168  result[1] = v1[2]*v2[0] - v1[0]*v2[2];
169  result[2] = v1[0]*v2[1] - v1[1]*v2[0];
170 }
171 
172 static inline double
173 vector_magnitude_squared_2d (const double v[2])
174 {
175  return v[0]*v[0] + v[1]*v[1];
176 }
177 
178 static inline double
179 vector_magnitude_2d (const double v[2])
180 {
181  return sqrt(v[0]*v[0] + v[1]*v[1]);
182 }
183 
184 static inline double
185 vector_magnitude_3d (const double v[3])
186 {
187  return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
188 }
189 
190 static inline double
191 vector_magnitude_squared_3d (const double v[3])
192 {
193  return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
194 }
195 
196 static inline double
197 vector_dist_3d (const double v1[3], const double v2[3])
198 {
199  double v[3];
200  vector_subtract_3d (v1, v2, v);
201  return vector_magnitude_3d (v);
202 }
203 
204 static inline double
205 vector_dist_squared_3d (const double v1[3], const double v2[3])
206 {
207  double v[3];
208  vector_subtract_3d (v1, v2, v);
209  return vector_magnitude_squared_3d (v);
210 }
211 
212 static inline double
213 vector_dist_2d (const double v1[2], const double v2[2])
214 {
215  double v[2];
216  vector_sub_nd (v1, v2, 2, v);
217  return vector_magnitude_2d (v);
218 }
219 
220 static inline void
221 vector_normalize_2d (double v[2])
222 {
223  double mag = vector_magnitude_2d (v);
224  v[0] /= mag;
225  v[1] /= mag;
226 }
227 
228 static inline void
229 vector_normalize_3d (double v[3])
230 {
231  double mag = vector_magnitude_3d (v);
232  v[0] /= mag;
233  v[1] /= mag;
234  v[2] /= mag;
235 }
236 
237 static inline void
238 vector_scale_2d (double v[2], double s)
239 {
240  v[0] *= s;
241  v[1] *= s;
242 }
243 
244 static inline void
245 vector_scale_3d (double v[2], double s)
246 {
247  v[0] *= s;
248  v[1] *= s;
249  v[2] *= s;
250 }
251 
252 // z = a * x + y
253 static inline void
254 vector_saxpy_3d (double a, const double x[3], const double y[3], double z[3])
255 {
256  double t[3] = { a * x[0] + y[0], a * x[1] + y[1], a * x[2] + y[2] };
257  z[0] = t[0]; z[1] = t[1]; z[2] = t[2];
258 }
259 
260 static inline double
261 vector_angle_2d (const double v1[2], const double v2[2])
262 {
263  double mag1 = vector_magnitude_2d (v1);
264  double mag2 = vector_magnitude_2d (v2);
265  double dot = vector_dot_2d (v1, v2);
266 
267  double costheta = dot / ( mag1 * mag2);
268  if (costheta > 1) return 0;
269  double theta = acos (costheta);
270 
271  if ( (v1[0]*v2[1] - v1[1]*v2[0]) < 0) {
272  return -theta;
273  }
274 
275  return theta;
276 }
277 
278 static inline double
279 vector_angle_3d (const double v1[3], const double v2[3])
280 {
281  double mag1 = vector_magnitude_3d (v1);
282  double mag2 = vector_magnitude_3d (v2);
283  double dot = vector_dot_3d (v1, v2);
284  double costheta = dot / (mag1*mag2);
285  if (costheta > 1) return 0;
286  return acos (costheta);
287 }
288 
289 static inline void
290 matrix_transpose_3x3d (const double m[9], double result[9])
291 {
292  result[0] = m[0];
293  result[1] = m[3];
294  result[2] = m[6];
295  result[3] = m[1];
296  result[4] = m[4];
297  result[5] = m[7];
298  result[6] = m[2];
299  result[7] = m[5];
300  result[8] = m[8];
301 }
302 
303 static inline void
304 matrix_transpose_4x4d (const double m[16], double result[16])
305 {
306  result[0] = m[0];
307  result[1] = m[4];
308  result[2] = m[8];
309  result[3] = m[12];
310  result[4] = m[1];
311  result[5] = m[5];
312  result[6] = m[9];
313  result[7] = m[13];
314  result[8] = m[2];
315  result[9] = m[6];
316  result[10] = m[10];
317  result[11] = m[14];
318  result[12] = m[3];
319  result[13] = m[7];
320  result[14] = m[11];
321  result[15] = m[15];
322 }
323 
324 static inline void
325 matrix_multiply_4x4_4x4 (const double a[16], const double b[16], double r[16])
326 {
327  int i, j;
328  for (i = 0; i < 4; i++) {
329  for (j = 0; j < 4; j++) {
330  double acc = 0;
331  int k;
332  for (k = 0; k < 4; k++)
333  acc += a[4*i + k] * b[j + 4*k];
334  r[i*4+j] = acc;
335  }
336  }
337 }
338 
339 static inline void
340 matrix_multiply_3x3_3x3 (const double a[9], const double b[9], double r[9])
341 {
342  int i, j;
343  for (i = 0; i < 3; i++) {
344  for (j = 0; j < 3; j++) {
345  double acc = 0;
346  int k;
347  for (k = 0; k < 3; k++)
348  acc += a[3*i + k] * b[j + 3*k];
349  r[i*3+j] = acc;
350  }
351  }
352 }
353 
354 static inline void
355 matrix_multiply (const double *a, int a_nrows, int a_ncols,
356  const double *b, int b_nrows, int b_ncols,
357  double *result)
358 {
359  int i, j;
360  for (i=0; i<a_nrows; i++) {
361  for (j=0; j<b_ncols; j++) {
362  double acc = 0;
363  int r;
364  for (r=0; r<a_ncols; r++) {
365  acc += a[i*a_ncols + r] * b[r*b_ncols + j];
366  }
367  result[i*b_ncols + j] = acc;
368  }
369  }
370 }
371 
372 static inline int
373 matrix_rigid_body_transform_inverse_4x4d (const double m[16], double inv[16])
374 {
375  // TODO handle case where m[15] != 1
376 
377  double rot_inv_1[3] = { m[0], m[4], m[8] };
378  double rot_inv_2[3] = { m[1], m[5], m[9] };
379  double rot_inv_3[3] = { m[2], m[6], m[10] };
380  double t_inv[3] = { -m[3], -m[7], -m[11] };
381 
382  inv[0] = m[0];
383  inv[1] = m[4];
384  inv[2] = m[8];
385  inv[3] = vector_dot_3d (rot_inv_1, t_inv);
386  inv[4] = m[1];
387  inv[5] = m[5];
388  inv[6] = m[9];
389  inv[7] = vector_dot_3d (rot_inv_2, t_inv);
390  inv[8] = m[2];
391  inv[9] = m[6];
392  inv[10] = m[10];
393  inv[11] = vector_dot_3d (rot_inv_3, t_inv);
394  inv[12] = inv[13] = inv[14] = 0;
395  inv[15] = m[15];
396  return 0;
397 }
398 
399 static inline void
401  double rot[16])
402 {
403  rot[0] = m[0]; rot[1] = m[1]; rot[2] = m[2]; rot[3] = 0;
404  rot[4] = m[4]; rot[5] = m[5]; rot[6] = m[6]; rot[7] = 0;
405  rot[8] = m[8]; rot[9] = m[9]; rot[10] = m[10]; rot[11] = 0;
406  rot[12] = rot[13] = rot[14] = 0; rot[15] = 1;
407 }
408 
409 static inline void
411  double t[16])
412 {
413  t[0] = 1; t[1] = 0; t[2] = 0; t[3] = m[3];
414  t[4] = 0; t[5] = 1; t[6] = 0; t[7] = m[7];
415  t[8] = 0; t[9] = 0; t[10] = 1; t[11] = m[11];
416  t[12] = t[13] = t[14] = 0; t[15] = 1;
417 }
418 
419 static inline void
420 matrix_print(const double *a, int rows, int cols)
421 {
422  int r, c;
423  for (r = 0; r < rows; r++) {
424  for (c = 0; c < cols; c++) {
425  printf("%10f ", a[r*cols + c]);
426  }
427  printf("\n");
428  }
429 }
430 
431 static inline void
432 vector_print_3d(const double a[3])
433 {
434  int i;
435  for (i = 0; i < 3; i++)
436  printf("%15f\n", a[i]);
437  printf("\n");
438 }
439 
440 static inline void
441 vector_vector_outer_product_3d (const double v1[3], const double v2[3],
442  double result[9])
443 {
444  result[0] = v1[0] * v2[0];
445  result[1] = v1[1] * v2[0];
446  result[2] = v1[2] * v2[0];
447  result[3] = result[1];
448  result[4] = v1[1] * v2[1];
449  result[5] = v1[2] * v2[1];
450  result[6] = result[2];
451  result[7] = result[5];
452  result[8] = v1[2] * v2[2];
453 }
454 
455 #ifdef __cplusplus
456 }
457 #endif
458 
459 #endif
460 
static int matrix_rigid_body_transform_inverse_4x4d(const double m[16], double inv[16])
Definition: small_linalg.h:373
static void matrix_rigid_body_transform_get_rotation_matrix_4x4d(const double m[16], double rot[16])
Definition: small_linalg.h:400
static void matrix_rigid_body_transform_get_translation_matrix_4x4d(const double m[16], double t[16])
Definition: small_linalg.h:410
static void vector_saxpy_3d(double a, const double x[3], const double y[3], double z[3])
Definition: small_linalg.h:254
static double vector_angle_3d(const double v1[3], const double v2[3])
Definition: small_linalg.h:279
static int matrix_inverse_3x3d(const double m[9], double inverse[9])
Definition: small_linalg.h:57
static double vector_magnitude_squared_2d(const double v[2])
Definition: small_linalg.h:173
static double vector_magnitude_3d(const double v[3])
Definition: small_linalg.h:185
static void vector_normalize_2d(double v[2])
Definition: small_linalg.h:221
static double vector_dist_squared_3d(const double v1[3], const double v2[3])
Definition: small_linalg.h:205
static int matrix_inverse_2x2d(const double m[4], double inverse[4])
Definition: small_linalg.h:76
static void vector_sub_nd(const double *v1, const double *v2, int N, double *result)
Definition: small_linalg.h:132
static void matrix_transpose_4x4d(const double m[16], double result[16])
Definition: small_linalg.h:304
static void matrix_vector_multiply_2x2_2d(const double m[4], const double v[2], double result[2])
Definition: small_linalg.h:89
static void matrix_multiply(const double *a, int a_nrows, int a_ncols, const double *b, int b_nrows, int b_ncols, double *result)
Definition: small_linalg.h:355
static void matrix_print(const double *a, int rows, int cols)
Definition: small_linalg.h:420
static void matrix_vector_multiply_4x4_4d(const double m[16], const double v[4], double result[4])
Definition: small_linalg.h:106
static void vector_vector_outer_product_3d(const double v1[3], const double v2[3], double result[9])
Definition: small_linalg.h:441
static void vector_scale_2d(double v[2], double s)
Definition: small_linalg.h:238
static void vector_add_3d(const double v1[3], const double v2[3], double result[3])
Definition: small_linalg.h:116
static void matrix_transpose_3x3d(const double m[9], double result[9])
Definition: small_linalg.h:290
static double vector_dist_2d(const double v1[2], const double v2[2])
Definition: small_linalg.h:213
int matrix_inverse_4x4d(const double m[16], double inv[16])
static void matrix_multiply_3x3_3x3(const double a[9], const double b[9], double r[9])
Definition: small_linalg.h:340
static double vector_angle_2d(const double v1[2], const double v2[2])
Definition: small_linalg.h:261
static void vector_print_3d(const double a[3])
Definition: small_linalg.h:432
static void vector_add_nd(const double *v1, const double *v2, int N, double *result)
Definition: small_linalg.h:124
static void vector_normalize_3d(double v[3])
Definition: small_linalg.h:229
static void vector_cross_3d(const double v1[3], const double v2[3], double result[3])
Definition: small_linalg.h:165
static void vector_subtract_3d(const double v1[3], const double v2[3], double result[3])
Definition: small_linalg.h:145
static double matrix_determinant_3x3d(const double m[9])
Definition: small_linalg.h:46
static double vector_dot_3d(const double v1[3], const double v2[3])
Definition: small_linalg.h:159
static double vector_magnitude_squared_3d(const double v[3])
Definition: small_linalg.h:191
static double vector_dist_3d(const double v1[3], const double v2[3])
Definition: small_linalg.h:197
static void matrix_multiply_4x4_4x4(const double a[16], const double b[16], double r[16])
Definition: small_linalg.h:325
static double vector_magnitude_2d(const double v[2])
Definition: small_linalg.h:179
static double vector_dot_2d(const double v1[2], const double v2[2])
Definition: small_linalg.h:153
static void vector_scale_3d(double v[2], double s)
Definition: small_linalg.h:245
static void matrix_vector_multiply_3x3_3d(const double m[9], const double v[3], double result[3])
Definition: small_linalg.h:97


mit_darpa_logs_player
Author(s): Miguel Oliveira
autogenerated on Mon Mar 2 2015 01:32:15