Robot Control Library
matrix.h
Go to the documentation of this file.
1 /**
2  * <rc/math/matrix.h>
3  *
4  * @brief functions for masic matrix manipulation
5  *
6  *
7  * @addtogroup Matrix
8  * @ingroup Math
9  * @{
10  */
11 
12 
13 #ifndef RC_MATRIX_H
14 #define RC_MATRIX_H
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #include <rc/math/vector.h>
21 
22 /**
23  * @brief Struct containing the state of a matrix and a pointer to
24  * dynamically allocated memory to hold its contents.
25  *
26  * Set and read values directly with this code:
27  * @code{.c}
28  * matrix.d[row][col] = new_value; // set value in the matrix
29  * value = matrix.d[row][col]; // get value from the matrix
30  * @endcode
31  */
32 typedef struct rc_matrix_t{
33  int rows; ///< number of rows in the matrix
34  int cols; ///< number of columns in the matrix
35  double** d; ///< pointer to allocated 2d array
36  int initialized;///< set to 1 once memory has been allocated
37 } rc_matrix_t;
38 
39 #define RC_MATRIX_INITIALIZER {\
40  .rows = 0,\
41  .cols = 0,\
42  .d = NULL,\
43  .initialized = 0}
44 
45 /**
46  * @brief Returns an rc_matrix_t with no allocated memory and the
47  * initialized flag set to 0.
48  *
49  * This is essential for initializing rc_matrix_t structs when they are declared
50  * since local variables declared in a function without global variable scope in
51  * C are not guaranteed to be zeroed out which can lead to bad memory pointers
52  * and segfaults if not handled carefully. We recommend initializing all
53  * matrices with this before using rc_matrix_alloc or any other function.
54  *
55  * @return Returns an empty rc_matrix_t
56  */
58 
59 /**
60  * @brief Allocates memory for matrix A to have size rows&cols.
61  *
62  * If A is initially the right size, nothing is done and the data in A is
63  * preserved. If A is uninitialized or of the wrong size then any existing
64  * memory is freed and new memory is allocated, helping to prevent accidental
65  * memory leaks. The contents of the new matrix is not guaranteed to be anything
66  * in particular as the memory is allocated with malloc. Will only be
67  * unsuccessful if rows&cols are invalid or there is insufficient memory
68  * available.
69  *
70  * @param A Pointer to user's matrix struct
71  * @param[in] rows number of rows
72  * @param[in] cols number of columns
73  *
74  * @return 0 on success, -1 on failure.
75  */
76 int rc_matrix_alloc(rc_matrix_t* A, int rows, int cols);
77 
78 /**
79  * @brief Frees the memory allocated for a matrix A
80  *
81  * Also sets the dimensions and initialized flag to 0 to indicate to other
82  * functions that A no longer points to allocated memory and cannot be used
83  * until more memory is allocated such as with rc_matrix_alloc or
84  * rc_matrix_zeros. Will only fail and return -1 if it is passed a NULL pointer.
85  *
86  * @param A Pointer to user's matrix struct
87  *
88  * @return 0 on success, -1 on failure.
89  */
91 
92 /**
93  * @brief Resizes matrix A and allocates memory for a matrix with specified rows &
94 * columns. The new memory is pre-filled with zeros using calloc. Any existing memory
95 * allocated for A is freed if necessary to avoid memory leaks.
96  *
97  * @param A Pointer to user's matrix struct
98  * @param[in] rows number of rows
99  * @param[in] cols number of columns
100  *
101  * @return 0 on success, -1 on failure.
102  */
103 int rc_matrix_zeros(rc_matrix_t* A, int rows, int cols);
104 
105 /**
106  * @brief Resizes A to be a square identity matrix with dimensions
107  * dim-by-dim.
108  *
109  * Any existing memory allocated for A is freed if necessary to avoid memory
110  * leaks before new memory is allocated for the specified dimension.
111  *
112  * @param A Pointer to user's matrix struct
113  * @param[in] dim The dimension of one side of square matrix
114  *
115  * @return 0 on success, -1 on failure.
116  */
117 int rc_matrix_identity(rc_matrix_t* A, int dim);
118 
119 /**
120  * @brief Generates a matrix populated with random numbers between -1 and
121  * 1.
122  *
123  * Resizes A to be a matrix with the specified number of rows and columns and
124  * populates the new memory with random numbers evenly distributed between -1.0
125  * and 1.0. Any existing memory allocated for A is freed if necessary to avoid
126  * memory leaks.
127  *
128  * @param A Pointer to user's matrix struct
129  * @param[in] rows number of rows
130  * @param[in] cols number of columns
131  *
132  * @return 0 on success, -1 on failure.
133  */
134 int rc_matrix_random(rc_matrix_t* A, int rows, int cols);
135 
136 /**
137  * @brief Generates a diagonal matrix with the elements of specified vector
138  * v.
139  *
140  * Resizes A to be a square matrix with the same number of rows and columns as
141  * vector v's length. The diagonal entries of A are then populated with the
142  * contents of v and the off-diagonal entries are set to 0. The original
143  * contents of A are freed to avoid memory leaks.
144  *
145  * @param A Pointer to user's matrix struct
146  * @param[in] v vector of diagonal entries
147  *
148  * @return 0 on success, -1 on failure.
149  */
151 
152 /**
153  * @brief Duplicates the contents of matrix A and into matrix B.
154  *
155  * If B is already the right size then its contents are overwritten. If B is
156  * unallocated or is of the wrong size then the memory is freed and new memory
157  * is allocated to hold the duplicate of A.
158  *
159  * @param[in] A Matrix to be duplicated
160  * @param[out] B new matrix
161  *
162  * @return 0 on success, -1 on failure.
163  */
165 
166 /**
167  * @brief Prints the contents of matrix A to stdout in decimal notation
168  * with 4 decimal places.
169  *
170  * Not recommended for very large matrices as rows will typically linewrap if
171  * the terminal window is not wide enough.
172  *
173  * @param[in] A Matrix to print
174  *
175  * @return 0 on success, -1 on failure.
176  */
178 
179 /**
180  * @brief Prints the contents of matrix A to stdout in scientific notation.
181  *
182  * Prints 4 significant figures. Not recommended for very large matrices as rows
183  * will typically linewrap if the terminal window is not wide enough.
184  *
185  * @param[in] A Matrix to print
186  *
187  * @return 0 on success, -1 on failure.
188  */
190 
191 /**
192  * @brief Sets all values of an already-allocated matrix to 0
193  *
194  * @param A pointer to matrix to be zero'd out
195  *
196  * @return 0 on success, -1 on failure.
197  */
199 
200 /**
201  * @brief Multiplies every entry in A by scalar value s.
202  *
203  * It is not strictly necessary for A to be provided as a pointer since a copy
204  * of the struct A would also contain the correct pointer to the original
205  * matrix's allocated memory. However, in this library we use the convention of
206  * passing an rc_vector_t struct or rc_matrix_t struct as a pointer when its
207  * data is to be modified by the function, and as a normal argument when it is
208  * only to be read by the function.
209  *
210  * @param A Matrix to be modified
211  * @param[in] s scalar to multiply by
212  *
213  * @return Returns 0 on success or -1 on failure.
214  */
215 int rc_matrix_times_scalar(rc_matrix_t* A, double s);
216 
217 /**
218  * @brief Multiplies A*B=C.
219  *
220  * C is resized and its original contents are freed if necessary to avoid memory
221  * leaks.
222  *
223  * @param[in] A first input
224  * @param[in] B second input
225  * @param[out] C result
226  *
227  * @return Returns 0 on success or -1 on failure.
228  */
230 
231 /**
232  * @brief Multiplies A*B and puts the result back in the place of B.
233  *
234  * B is resized and its original contents are freed if necessary to avoid memory
235  * leaks.
236  *
237  * @param[in] A left matrix in the multiplication
238  * @param B right matrix in the multiplication and holder of the
239  * result.
240  *
241  * @return Returns 0 on success or -1 on failure.
242  */
244 
245 /**
246  * @brief Multiplies A*B and puts the result back in the place of A.
247  *
248  * A is resized and its original contents are freed if necessary to avoid memory
249  * leaks.
250  *
251  * @param A left matrix in the multiplication and holder of result
252  * @param[in] B right matrix in the multiplication
253  *
254  * @return Returns 0 on success or -1 on failure.
255  */
257 
258 /**
259  * @brief Adds matrices A+B and places the result in C.
260  *
261  * The original contents of C are safely freed if necessary to avoid memory
262  * leaks. Use rc_matrix_add_inplace if you do not need to keep the contents of
263  * one of these matrices after addition.
264  *
265  * @param[in] A First matrix
266  * @param[in] B second matrix
267  * @param[out] C result
268  *
269  * @return Returns 0 on success or -1 on failure.
270  */
272 
273 /**
274  * @brief Adds matrix A to B and places the result back in A.
275  *
276  * The original contents of A are lost. Use rc_matrix_add if you wish to keep
277  * the contents of both matrix A and B after addition.
278  *
279  * @param A First matrix for addition and holder of the result
280  * @param[in] B Second matrix for addition
281  *
282  * @return Returns 0 on success or -1 on failure.
283  */
285 
286 /**
287  * @brief Subtracts matrix B from A and leaves the result in A
288  *
289  * The original contents of A are lost.
290  *
291  * @param A First matrix for subtraction and holder of the result
292  * @param[in] B Second matrix for subtraction
293  *
294  * @return Returns 0 on success or -1 on failure.
295  */
297 
298 /**
299  * @brief Transposes the contents of A and places the result in T.
300  *
301  * Resizes matrix T to hold the transposed contents of A and leaves A untouched.
302  * Original contents of T are safely freed and lost. If the original contents of
303  * A are not needed after transposing then use rc_matrix_transpose_inplace
304  * instead.
305  *
306  * @param[in] A input matrix struct
307  * @param[out] T resulting transpose
308  *
309  * @return Returns 0 on success or -1 on failure.
310  */
312 
313 /**
314  * @brief Transposes matrix A in place.
315  *
316  * Use as an alternative to rc_matrix_transpose if you no longer have need for
317  * the original contents of matrix A.
318  *
319  * @param A Pointer to matrix to be transposed
320  *
321  * @return Returns 0 on success or -1 on failure.
322  */
324 
325 
326 /**
327  * @brief Multiplies matrix A times column vector v and places the result
328  * in column vector c.
329  *
330  * Any existing data in c is freed if necessary and c is resized appropriately.
331  * Vectors v and c are interpreted as column vectors, but nowhere in their
332  * definitions are they actually specified as one or the other.
333  *
334  * @param[in] A input matrix
335  * @param[in] v input vector
336  * @param[out] c output vector
337  *
338  * @return Returns 0 on success or -1 on failure.
339  */
341 
342 /**
343  * @brief Multiplies row vector v times matrix A and places the result in
344  * row vector c.
345  *
346  * Any existing data in c is freed if necessary and c is resized appropriately.
347  * Vectors v and c are interpreted as row vectors, but nowhere in their
348  * definitions are they actually specified as one or the other.
349  *
350  * @param[in] v input vector
351  * @param[in] A input matrix
352  * @param[out] c output vector
353  *
354  * @return Returns 0 on success or -1 on failure.
355  */
357 
358 /**
359  * @brief Computes v1 times v2 where v1 is a column vector and v2 is a row
360  * vector.
361  *
362  * @param[in] v1 Column vector v1
363  * @param[in] v2 Row vector v2
364  * @param A Output matrix
365  *
366  * @return Returns 0 on success or -1 on failure.
367  */
369 
370 
371 /**
372  * @brief Calculates the determinant of square matrix A
373  *
374  * @param[in] A input matrix
375  *
376  * @return Returns the determinant or prints error message and returns -1.0f
377  * of error.
378  */
380 
381 /**
382  * @brief Symmetrizes a square matrix
383  *
384  * P_sym = (P+P^T)/2
385  *
386  * @param P pointer to matrix to symmetrize
387  *
388  * @return 0 on success, -1 on failure
389  */
391 
392 
393 #ifdef __cplusplus
394 }
395 #endif
396 
397 #endif // RC_MATRIX_H
398 
399 /** @} end group math*/
rc_matrix_t rc_matrix_empty(void)
Returns an rc_matrix_t with no allocated memory and the initialized flag set to 0.
int rc_matrix_transpose(rc_matrix_t A, rc_matrix_t *T)
Transposes the contents of A and places the result in T.
int rc_matrix_free(rc_matrix_t *A)
Frees the memory allocated for a matrix A.
int rc_matrix_outer_product(rc_vector_t v1, rc_vector_t v2, rc_matrix_t *A)
Computes v1 times v2 where v1 is a column vector and v2 is a row vector.
int rc_matrix_diagonal(rc_matrix_t *A, rc_vector_t v)
Generates a diagonal matrix with the elements of specified vector v.
int rc_matrix_add(rc_matrix_t A, rc_matrix_t B, rc_matrix_t *C)
Adds matrices A+B and places the result in C.
int rc_matrix_symmetrize(rc_matrix_t *P)
Symmetrizes a square matrix.
int rc_matrix_multiply(rc_matrix_t A, rc_matrix_t B, rc_matrix_t *C)
Multiplies A*B=C.
int rc_matrix_subtract_inplace(rc_matrix_t *A, rc_matrix_t B)
Subtracts matrix B from A and leaves the result in A.
int rc_matrix_print_sci(rc_matrix_t A)
Prints the contents of matrix A to stdout in scientific notation.
int rc_matrix_times_scalar(rc_matrix_t *A, double s)
Multiplies every entry in A by scalar value s.
double ** d
pointer to allocated 2d array
Definition: matrix.h:35
Struct containing the state of a vector and a pointer to dynamically allocated memory to hold its con...
Definition: vector.h:41
double rc_matrix_determinant(rc_matrix_t A)
Calculates the determinant of square matrix A.
int rc_matrix_transpose_inplace(rc_matrix_t *A)
Transposes matrix A in place.
int rows
number of rows in the matrix
Definition: matrix.h:33
int rc_matrix_identity(rc_matrix_t *A, int dim)
Resizes A to be a square identity matrix with dimensions dim-by-dim.
struct rc_matrix_t rc_matrix_t
Struct containing the state of a matrix and a pointer to dynamically allocated memory to hold its con...
int initialized
set to 1 once memory has been allocated
Definition: matrix.h:36
int rc_matrix_zero_out(rc_matrix_t *A)
Sets all values of an already-allocated matrix to 0.
int rc_matrix_alloc(rc_matrix_t *A, int rows, int cols)
Allocates memory for matrix A to have size rows&cols.
int rc_matrix_left_multiply_inplace(rc_matrix_t A, rc_matrix_t *B)
Multiplies A*B and puts the result back in the place of B.
int rc_matrix_times_col_vec(rc_matrix_t A, rc_vector_t v, rc_vector_t *c)
Multiplies matrix A times column vector v and places the result in column vector c.
int rc_matrix_zeros(rc_matrix_t *A, int rows, int cols)
Resizes matrix A and allocates memory for a matrix with specified rows & columns. The new memory is p...
int cols
number of columns in the matrix
Definition: matrix.h:34
int rc_matrix_random(rc_matrix_t *A, int rows, int cols)
Generates a matrix populated with random numbers between -1 and 1.
int rc_matrix_print(rc_matrix_t A)
Prints the contents of matrix A to stdout in decimal notation with 4 decimal places.
int rc_matrix_right_multiply_inplace(rc_matrix_t *A, rc_matrix_t B)
Multiplies A*B and puts the result back in the place of A.
int rc_matrix_add_inplace(rc_matrix_t *A, rc_matrix_t B)
Adds matrix A to B and places the result back in A.
Struct containing the state of a matrix and a pointer to dynamically allocated memory to hold its con...
Definition: matrix.h:32
int rc_matrix_row_vec_times_matrix(rc_vector_t v, rc_matrix_t A, rc_vector_t *c)
Multiplies row vector v times matrix A and places the result in row vector c.
int rc_matrix_duplicate(rc_matrix_t A, rc_matrix_t *B)
Duplicates the contents of matrix A and into matrix B.