Robot Control Library
vector.h
Go to the documentation of this file.
1 /**
2  * <rc/math/vector.h>
3  *
4  * @brief Functions for vector manipulation.
5  *
6  * The small rc_vector_t struct contains information about the vector's size and
7  * a pointer to where dynamically allocated memory exists that stores the actual
8  * data for the vector. Use rc_vector_alloc to dynamically allocate memory for
9  * each new vector. Then use rc_vector_free() and to free the memory when you
10  * are done using it. See the remaining vector, matrix, and linear algebra
11  * functions for more details.
12  *
13  * @author James Strawson
14  * @date 2016
15  *
16  * @addtogroup Vector
17  * @ingroup Math
18  * @{
19  */
20 
21 
22 #ifndef RC_VECTOR_H
23 #define RC_VECTOR_H
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 extern double zero_tolerance;
30 
31 /**
32  * @brief Struct containing the state of a vector and a pointer to
33  * dynamically allocated memory to hold its contents.
34  *
35  * Set and read values directly with this code:
36  * @code{.c}
37  * vec.d[position]=new_value; // set value in the vector
38  * value = v.d[pos]; // get value from vector
39  * @endcode
40  */
41 typedef struct rc_vector_t{
42  int len; ///< number of elements in the vector
43  double* d; ///< pointer to dynamically allocated data
44  int initialized;///< initialization flag
45 } rc_vector_t;
46 
47 
48 #define RC_VECTOR_INITIALIZER {\
49  .len = 0,\
50  .d = NULL,\
51  .initialized = 0}
52 
53 
54 /**
55  * @brief Returns an rc_vector_t with no allocated memory and the
56  * initialized flag set to 0.
57  *
58  * This is essential for initializing vectors when they are declared since
59  * local variables declared in a function without global variable scope in C are
60  * not guaranteed to be zeroed out which can lead to bad memory pointers and
61  * segfaults if not handled carefully. We recommend initializing all vectors
62  * with this function before using rc_vector_alloc or any other function.
63  *
64  * @return rc_vector_t with no allocated memory and the initialized flag set
65  * to 0.
66  */
68 
69 /**
70  * @brief Allocates memory for vector v to have specified length.
71  *
72  * If v is initially the right length then nothing is done and the data in v is
73  * preserved. If v is uninitialized or of the wrong length then any existing
74  * memory is freed and new memory is allocated, helping to prevent accidental
75  * memory leaks.
76  *
77  * The contents of the new vector is not guaranteed to be anything in particular
78  * as it is allocated with malloc. Use rc_vector_zeros or rc_vector_ones if you
79  * require known starting values.
80  *
81  * Returns 0 if successful, otherwise returns -1. Will only be unsuccessful if
82  * length is invalid or there is insufficient memory available.
83  *
84  * @param v Pointer to user's rc_vector_t struct
85  * @param[in] length Length of vector to allocate memory for
86  *
87  * @return Returns 0 if successful, otherwise returns -1.
88  */
89 int rc_vector_alloc(rc_vector_t* v, int length);
90 
91 /**
92  * @brief Frees the memory allocated for vector v.
93  *
94  * Also sets the length and initialized flag of the rc_vector_t struct to 0 to
95  * indicate to other functions that v no longer points to allocated memory and
96  * cannot be used until more memory is allocated such as with rc_vector_alloc or
97  * rc_vector_zeros. Returns 0 on success. Will only fail and return -1 if it is
98  * passed a NULL pointer.
99  *
100  * @param v Pointer to user's rc_vector_t struct
101  *
102  * @return Returns 0 if successful, otherwise returns -1.
103  */
105 
106 /**
107  * @brief Resizes vector v and fills with zeros.
108  *
109  * uses calloc to allocate new memory. Any existing memory allocated for v is
110  * freed if necessary to avoid memory leaks. It is not necessary to call
111  * rc_alloc_vector before this.
112  *
113  * @param v Pointer to user's rc_vector_t struct
114  * @param[in] length Length of vector to allocate memory for
115  *
116  * @return Returns 0 if successful, otherwise returns -1.
117  */
118 int rc_vector_zeros(rc_vector_t* v, int length);
119 
120 /**
121  * @brief Resizes vector v and fills with ones.
122  *
123  * Any existing memory allocated for v is freed if necessary to avoid memory
124  * leaks. It is not necessary to call rc_alloc_vector before this.
125  *
126  * @param v Pointer to user's rc_vector_t struct
127  * @param[in] length Length of vector to allocate memory for
128  *
129  * @return Returns 0 if successful, otherwise returns -1.
130  */
131 int rc_vector_ones(rc_vector_t* v, int length);
132 
133 /**
134  * @brief Resizes vector v and fills with random numbers between -1.0 and
135  * 1.0
136  *
137  * Any existing memory allocated for v is freed if necessary to avoid memory
138  * leaks. It is not necessary to call rc_alloc_vector before this.
139  *
140  * @param v Pointer to user's rc_vector_t struct
141  * @param[in] length Length of vector to allocate memory for
142  *
143  * @return Returns 0 if successful, otherwise returns -1.
144  */
145 int rc_vector_random(rc_vector_t* v, int length);
146 
147 /**
148  * @brief Resizes vector v and fills with Fibonnaci sequence
149  *
150  * Any existing memory allocated for v is freed if necessary to avoid memory
151  * leaks. It is not necessary to call rc_alloc_vector before this.
152  *
153  * @param v Pointer to user's rc_vector_t struct
154  * @param[in] length Length of vector to allocate memory for
155  *
156  * @return Returns 0 if successful, otherwise returns -1.
157  */
158 int rc_vector_fibonnaci(rc_vector_t* v, int length);
159 
160 /**
161  * @brief Resizes vector v and populates with values from specified array
162  * ptr.
163  *
164  * Any existing memory allocated for v is freed if necessary to avoid memory
165  * leaks. It is not necessary to call rc_alloc_vector before this. This is
166  * generally used when the user has an existing array of data and wants to use
167  * it with other math functions.
168  *
169  * @param v Pointer to user's rc_vector_t struct
170  * @param[in] ptr pointer to array to read values from
171  * @param[in] length Length of vector to allocate memory for
172  *
173  * @return Returns 0 if successful, otherwise returns -1.
174  */
175 int rc_vector_from_array(rc_vector_t* v, double* ptr, int length);
176 
177 /**
178  * @brief Duplicates the contents of vector a and into a new vector b.
179  *
180  * Simply making a copy of an rc_vector_t struct is not sufficient as the
181  * rc_vector_t struct simply contains a pointer to the memory allocated to
182  * contain the contents of the vector. rc_vector_duplicate sets b to be a new
183  * rc_vector_t with a pointer to freshly-allocated memory.
184  *
185  * @param[in] a Vector to be duplicated
186  * @param b pointer to new vector to be allocated and written
187  *
188  * @return Returns 0 if successful, otherwise returns -1.
189  */
191 
192 /**
193  * @brief Prints to stdout the contents of vector v in one line.
194  *
195  * This is not advisable for extremely long vectors but serves for quickly
196  * debugging or printing results. It prints 4 decimal places with padding for a
197  * sign. We recommend rc_vector_print_sci() for very small or very large numbers
198  * where scientific notation would be more appropriate.
199  *
200  * @param[in] v Pointer to user's rc_vector_t struct
201  *
202  * @return Returns 0 on success or -1 on failure.
203  */
205 
206 /**
207  * @brief Prints to stdout the contents of vector v in one line.
208  *
209  * Like rc_vector_print but prints with scientific notation. This is not
210  * advisable for extremely long vectors but serves for quickly debugging or
211  * printing.
212  *
213  * @param[in] v Pointer to user's rc_vector_t struct
214  *
215  * @return Returns 0 on success or -1 on failure.
216  */
218 
219 /**
220  * @brief Sets all values of an already-allocated vector to 0
221  *
222  * @param v pointer to vector to be zero'd out
223  *
224  * @return 0 on success, -1 on failure.
225  */
227 
228 /**
229  * @brief Multiplies every entry in vector v by scalar s.
230  *
231  * It is not strictly necessary for v to be provided as a pointer since a copy
232  * of the struct v would also contain the correct pointer to the original
233  * vector's allocated memory. However, in this library we use the convention of
234  * passing an rc_vector_t struct or rc_matrix_struct as a pointer when its data
235  * is to be modified by the function, and as a normal argument when it is only
236  * to be read by the function.
237  *
238  * @param v Pointer to user's rc_vector_t struct
239  * @param[in] s scalar multiplier
240  *
241  * @return Returns 0 on success or -1 on failure.
242  */
243 int rc_vector_times_scalar(rc_vector_t* v, double s);
244 
245 /**
246  * @brief Returns the vector norm defined by sum(abs(v)^p)^(1/p), where p
247  * is any positive real value.
248  *
249  * Just like the matlab norm(v,p) function.
250  *
251  * Most common norms are the 1 norm which gives the sum of absolute values of
252  * the vector and the 2-norm which is the square root of sum of squares. for
253  * infinity and -infinity norms see rc_vector_max and rc_vector_min
254  *
255  * @param[in] v User's vector struct
256  * @param[in] p Which norm to use. Positive real values only.
257  *
258  * @return vector norm. Prints error message and returns -1.0f on error.
259  */
260 double rc_vector_norm(rc_vector_t v, double p);
261 
262 /**
263  * @brief Returns the index of the maximum value in v.
264  *
265  * The value contained in the returned index is the equivalent to the infinity
266  * norm. If the max value occurs multiple times then the index of the first
267  * instance is returned.
268  *
269  * @param[in] v User's vector struct
270  *
271  * @return Returns the index of the maximum value in v or -1 on error.
272  */
274 
275 /**
276  * @brief Returns the index of the minimum value in v.
277  *
278  * The value contained in the returned index is the equivalent to the -infinity
279  * norm. If the minimum value occurs multiple times then the index of the first
280  * instance is returned.
281  *
282  * @param[in] v User's vector struct
283  *
284  * @return Returns the index of the minimum value in v or -1 on error.
285  */
287 
288 /**
289  * @brief Returns the standard deviation of the values in a vector.
290  *
291  * @param[in] v User's vector struct
292  *
293  * @return Returns the standard deviation or prints and error message and
294  * return -1.0f on error.
295  */
297 
298 /**
299  * @brief Returns the mean (average) of all values in vector v or -1.0f on
300  * error.
301  *
302  * @param[in] v User's vector struct
303  *
304  * @return Returns the mean (average) of all values in vector v or -1.0f on
305  * error.
306  */
307 double rc_vector_mean(rc_vector_t v);
308 
309 /**
310  * @brief Populates vector p with the projection of vector v onto e.
311  *
312  * p is resized appropriately and any exising memory is freed to avoid memory
313  * leaks.
314  *
315  * @param[in] v User's vector struct
316  * @param[in] e User's vector struct
317  * @param[out] p output
318  *
319  * @return Returns 0 on success, otherwise -1.
320  */
322 
323 /**
324  * @brief Calculates the dot product of two equal-length vectors.
325  *
326  * @param[in] v1 User's vector struct
327  * @param[in] v2 User's vector struct
328  *
329  * @return Returns the dot product, or prints and error message and returns
330  * -1.0f on error.
331  */
333 
334 /**
335  * @brief Computes the cross-product of two vectors, each of length 3.
336  *
337  * The result is placed in vector p and and any existing memory used by p is
338  * freed to avoid memory leaks.
339  *
340  * @param[in] v1 User's vector struct
341  * @param[in] v2 User's vector struct
342  * @param[out] p resulting cross product
343  *
344  * @return Returns 0 on success, otherwise -1.
345  */
347 
348 /**
349  * @brief Populates vector s with the sum of vectors v1 and v2.
350  *
351  * v1 and v2 must be of the same length. Any existing memory allocated for s is
352  * freed and lost, new memory is allocated if necessary.
353  *
354  * @param[in] v1 User's vector struct
355  * @param[in] v2 User's vector struct
356  * @param[out] s output sum
357  *
358  * @return Returns 0 on success, otherwise -1.
359  */
361 
362 /**
363  * @brief Adds vector v2 to v1 and leaves the result in v1.
364  *
365  * The original contents of v1 are lost and v2 is left untouched. v1 and v2 must
366  * be of the same length.
367  *
368  * @param v1 User's vector struct, holds the result
369  * @param[in] v2 User's vector struct
370  *
371  * @return Returns 0 on success, otherwise -1.
372  */
374 
375 /**
376  * @brief Populates vector s with the difference v1 - v2.
377  *
378  * v1 and v2 must be of the same length. Any existing memory allocated for s is
379  * freed and lost, new memory is allocated if necessary.
380  *
381  * @param[in] v1 User's vector struct
382  * @param[in] v2 User's vector struct
383  * @param[out] s output difference v1-v2
384  *
385  * @return Returns 0 on success, otherwise -1.
386  */
388 
389 
390 #ifdef __cplusplus
391 }
392 #endif
393 
394 #endif // RC_VECTOR_H
395 
396 /** @} end group math*/
int rc_vector_free(rc_vector_t *v)
Frees the memory allocated for vector v.
int rc_vector_ones(rc_vector_t *v, int length)
Resizes vector v and fills with ones.
int rc_vector_projection(rc_vector_t v, rc_vector_t e, rc_vector_t *p)
Populates vector p with the projection of vector v onto e.
int rc_vector_sum(rc_vector_t v1, rc_vector_t v2, rc_vector_t *s)
Populates vector s with the sum of vectors v1 and v2.
int rc_vector_print_sci(rc_vector_t v)
Prints to stdout the contents of vector v in one line.
double rc_vector_std_dev(rc_vector_t v)
Returns the standard deviation of the values in a vector.
int rc_vector_zero_out(rc_vector_t *v)
Sets all values of an already-allocated vector to 0.
int rc_vector_alloc(rc_vector_t *v, int length)
Allocates memory for vector v to have specified length.
int initialized
initialization flag
Definition: vector.h:44
int rc_vector_zeros(rc_vector_t *v, int length)
Resizes vector v and fills with zeros.
double rc_vector_norm(rc_vector_t v, double p)
Returns the vector norm defined by sum(abs(v)^p)^(1/p), where p is any positive real value...
int rc_vector_min(rc_vector_t v)
Returns the index of the minimum value in v.
struct rc_vector_t rc_vector_t
Struct containing the state of a vector and a pointer to dynamically allocated memory to hold its con...
double * d
pointer to dynamically allocated data
Definition: vector.h:43
int rc_vector_random(rc_vector_t *v, int length)
Resizes vector v and fills with random numbers between -1.0 and 1.0.
int rc_vector_fibonnaci(rc_vector_t *v, int length)
Resizes vector v and fills with Fibonnaci sequence.
int rc_vector_cross_product(rc_vector_t v1, rc_vector_t v2, rc_vector_t *p)
Computes the cross-product of two vectors, each of length 3.
int rc_vector_max(rc_vector_t v)
Returns the index of the maximum value in v.
Struct containing the state of a vector and a pointer to dynamically allocated memory to hold its con...
Definition: vector.h:41
int rc_vector_duplicate(rc_vector_t a, rc_vector_t *b)
Duplicates the contents of vector a and into a new vector b.
double rc_vector_mean(rc_vector_t v)
Returns the mean (average) of all values in vector v or -1.0f on error.
int rc_vector_print(rc_vector_t v)
Prints to stdout the contents of vector v in one line.
int rc_vector_from_array(rc_vector_t *v, double *ptr, int length)
Resizes vector v and populates with values from specified array ptr.
int len
number of elements in the vector
Definition: vector.h:42
rc_vector_t rc_vector_empty(void)
Returns an rc_vector_t with no allocated memory and the initialized flag set to 0.
int rc_vector_sum_inplace(rc_vector_t *v1, rc_vector_t v2)
Adds vector v2 to v1 and leaves the result in v1.
double zero_tolerance
int rc_vector_subtract(rc_vector_t v1, rc_vector_t v2, rc_vector_t *s)
Populates vector s with the difference v1 - v2.
double rc_vector_dot_product(rc_vector_t v1, rc_vector_t v2)
Calculates the dot product of two equal-length vectors.
int rc_vector_times_scalar(rc_vector_t *v, double s)
Multiplies every entry in vector v by scalar s.