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
17extern "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 */
32typedef 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
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 */
76int 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 */
103int 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 */
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 */
134int 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 */
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*/
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 rc_matrix_free(rc_matrix_t *A)
Frees the memory allocated for a matrix A.
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_diagonal(rc_matrix_t *A, rc_vector_t v)
Generates a diagonal matrix with the elements of specified vector v.
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_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_identity(rc_matrix_t *A, int dim)
Resizes A to be a square identity matrix with dimensions dim-by-dim.
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_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_multiply(rc_matrix_t A, rc_matrix_t B, rc_matrix_t *C)
Multiplies A*B=C.
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_add_inplace(rc_matrix_t *A, rc_matrix_t B)
Adds matrix A to B and places the result back in A.
int rc_matrix_symmetrize(rc_matrix_t *P)
Symmetrizes a square matrix.
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 rc_matrix_times_scalar(rc_matrix_t *A, double s)
Multiplies every entry in A by scalar value s.
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.
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_transpose(rc_matrix_t A, rc_matrix_t *T)
Transposes the contents of A and places the result in T.
int rc_matrix_transpose_inplace(rc_matrix_t *A)
Transposes matrix A in place.
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_zero_out(rc_matrix_t *A)
Sets all values of an already-allocated matrix to 0.
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_random(rc_matrix_t *A, int rows, int cols)
Generates a matrix populated with random numbers between -1 and 1.
int rc_matrix_print_sci(rc_matrix_t A)
Prints the contents of matrix A to stdout in scientific notation.
double rc_matrix_determinant(rc_matrix_t A)
Calculates the determinant of square matrix A.
Struct containing the state of a matrix and a pointer to dynamically allocated memory to hold its con...
Definition: matrix.h:32
int rows
number of rows in the matrix
Definition: matrix.h:33
int cols
number of columns in the matrix
Definition: matrix.h:34
int initialized
set to 1 once memory has been allocated
Definition: matrix.h:36
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