1 /* 2 * Copyright (c) 2019-2020 Kevin Townsend (KTOWN) 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @defgroup VECTORS Vectors 9 * 10 * @brief Vectors functions 11 * 12 * TODO: Expand with examples, better high-level documentation, etc. 13 */ 14 15 /** 16 * @file 17 * @brief API header file for vectors in zscilib. 18 * 19 * This file contains the zscilib vector APIs 20 */ 21 22 #ifndef ZEPHYR_INCLUDE_ZSL_VECTORS_H_ 23 #define ZEPHYR_INCLUDE_ZSL_VECTORS_H_ 24 25 #include <zsl/zsl.h> 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 /** 32 * @addtogroup VEC_STRUCTS Structs, Enums and Macros 33 * 34 * @brief Various struct, enums and macros related to vectors. 35 * 36 * @ingroup VECTORS 37 * @{ */ 38 39 /** @brief Represents a vector. */ 40 struct zsl_vec { 41 /** The number of elements in the vector. */ 42 size_t sz; 43 /** The array of real number values assigned to the vector. */ 44 zsl_real_t *data; 45 }; 46 47 /** Macro to declare a vector of size `n`. 48 * 49 * Be sure to also call 'zsl_vec_init' on the vector after this macro, since 50 * matrices declared on the stack may have non-zero values by default! 51 */ 52 #define ZSL_VECTOR_DEF(name, n) \ 53 zsl_real_t name ## _vec[n]; \ 54 struct zsl_vec name = { \ 55 .sz = n, \ 56 .data = name ## _vec \ 57 } 58 59 /** @} */ /* End of VEC_STRUCTS group */ 60 61 /** 62 * @addtogroup VEC_INIT Initialisation 63 * 64 * @brief Vector initisialisation. 65 * 66 * @ingroup VECTORS 67 * @{ */ 68 69 /** 70 * Initialises vector 'v' with 0.0 values. 71 * 72 * @param v Pointer to the zsl_vec to initialise/clear. 73 * 74 * @return 0 on success, and non-zero error code on failure 75 */ 76 int zsl_vec_init(struct zsl_vec *v); 77 78 /** 79 * @brief Converts an array of values into a vector. The number of elements in 80 * array 'a' must match the number of elements in vector 'v'. 81 * As such, 'v' should be previously initialised with an appropriate 82 * value assigned to v.sz. 83 * 84 * @param v The vector that the contents of array 'a' should be assigned to. 85 * The v.sz value must match the number of elements in 'a', meaning 86 * that the vector should be initialised before being passed in to 87 * this function. 88 * @param a Pointer to the array containing the values to assign to 'v'. 89 * The array will be read v.sz elements deep. 90 * 91 * @return 0 on success, and non-zero error code on failure 92 */ 93 int zsl_vec_from_arr(struct zsl_vec *v, zsl_real_t *a); 94 95 /** 96 * @brief Copies the contents of vector 'vsrc' into vector 'vdest'. 97 * 98 * @param vdest Pointer to the destination vector data will be copied to. 99 * @param vsrc Pointer to the source vector data will be copied from. 100 * 101 * @return 0 on success, and non-zero error code on failure 102 */ 103 int zsl_vec_copy(struct zsl_vec *vdest, struct zsl_vec *vsrc); 104 105 /** @} */ /* End of VEC_INIT group */ 106 107 /** 108 * @addtogroup VEC_SELECTION Data Selection 109 * 110 * @brief Functions used to access subsets of the vector. 111 * 112 * @ingroup VECTORS 113 * @{ */ 114 115 /** 116 * @brief Returns a subset of source vector 'v' in 'vsub'.. 117 * 118 * @param v The parent vector to read a subset of. 119 * @param offset The starting index (zero-based) foor the data subset. 120 * @param len The number of values to read, starting at offset. 121 * @param vsub The subset vector, which must have a buffer of at least 122 * size 'len'. If the data buffer isn't sufficiently large, 123 * this function will return -EINVAL. 124 * 125 * @return 0 on success, -EINVAL on a size of index error. 126 */ 127 int zsl_vec_get_subset(struct zsl_vec *v, size_t offset, size_t len, 128 struct zsl_vec *vsub); 129 130 /** @} */ /* End of VEC_SELECTION group */ 131 132 /** 133 * @addtogroup VEC_BASICMATH Basic Math 134 * 135 * @brief Basic mathematical operations (add, sum, norm, etc.). 136 * 137 * @ingroup VECTORS 138 * @{ */ 139 140 /** 141 * @brief Adds corresponding vector elements in 'v' and 'w', saving to 'x'. 142 * 143 * @param v The first vector. 144 * @param w The second vector. 145 * @param x The output vector. 146 * 147 * @return 0 on success, -EINVAL if v and w are not equal length. 148 */ 149 int zsl_vec_add(struct zsl_vec *v, struct zsl_vec *w, struct zsl_vec *x); 150 151 /** 152 * @brief Subtracts corresponding vector elements in 'v' and 'w', saving to 'x'. 153 * 154 * @param v The first vector. 155 * @param w The second vector. 156 * @param x The output vector. 157 * 158 * @return 0 on success, -EINVAL if v and w are not equal length. 159 */ 160 int zsl_vec_sub(struct zsl_vec *v, struct zsl_vec *w, struct zsl_vec *x); 161 162 /** 163 * @brief Negates the elements in vector 'v'. 164 * 165 * @param v The vector to negate. 166 * 167 * @return 0 on success, and non-zero error code on failure 168 */ 169 int zsl_vec_neg(struct zsl_vec *v); 170 171 /** 172 * @brief Component-wise sum of a set of equal-length vectors. 173 * 174 * @param v Pointer to the array of vectors. 175 * @param n The number of vectors in 'v'. 176 * @param w Pointer to the output vector containing the component-wise sum. 177 * 178 * @return 0 on success, -EINVAL if vectors in 'v' are no equal length, or 179 * -EINVAL if 'n' = 0. 180 */ 181 int zsl_vec_sum(struct zsl_vec **v, size_t n, struct zsl_vec *w); 182 183 /** 184 * @brief Adds a scalar to each element in a vector. 185 * 186 * @param v The vector to scale. 187 * @param s The scalar to add to each element. 188 * 189 * @return 0 on success, and non-zero error code on failure 190 */ 191 int zsl_vec_scalar_add(struct zsl_vec *v, zsl_real_t s); 192 193 /** 194 * @brief Multiply a vector by a scalar. 195 * 196 * @param v The vector to scale. 197 * @param s The scalar to multiply by. 198 * 199 * @return 0 on success, and non-zero error code on failure 200 */ 201 int zsl_vec_scalar_mult(struct zsl_vec *v, zsl_real_t s); 202 203 /** 204 * @brief Divide a vector by a scalar. 205 * 206 * @param v The vector to scale. 207 * @param s The scalar to divide all elements by. 208 * 209 * @return 0 on success, and non-zero error code on failure 210 */ 211 int zsl_vec_scalar_div(struct zsl_vec *v, zsl_real_t s); 212 213 /** 214 * @brief Calculates the distance between two vectors, which is equal to the 215 * norm of vector v - vector w. 216 * 217 * @param v The first vector. 218 * @param w The second vector. 219 * 220 * @return The norm of vector v - vector w, or NAN is there was a 221 * size mismatch between vectors v and w. 222 */ 223 zsl_real_t zsl_vec_dist(struct zsl_vec *v, struct zsl_vec *w); 224 225 /** 226 * @brief Computes the dot (aka scalar) product of two equal-length vectors 227 * (the sum of their component-wise products). The dot product is an 228 * indicator of the "agreement" between two vectors, or can be used 229 * to determine how far vector w deviates from vector v. 230 * 231 * @param v The first vector. 232 * @param w The second vector. 233 * @param d The dot product. 234 * 235 * @return 0 on success, or -EINVAL if vectors v and w aren't equal-length. 236 */ 237 int zsl_vec_dot(struct zsl_vec *v, struct zsl_vec *w, zsl_real_t *d); 238 239 /** 240 * @brief Calculates the norm or absolute value of vector 'v' (the 241 * square root of the vector's dot product). 242 * 243 * @param v The vector to calculate the norm of. 244 * 245 * @return The norm of vector 'v'. 246 */ 247 zsl_real_t zsl_vec_norm(struct zsl_vec *v); 248 249 /** 250 * @brief Calculates the projection of vector 'u' over vector 'v', placing 251 * the results in vector 'w'. 252 * 253 * @param u Pointer to the first input vector. 254 * @param v Pointer to the second input vector. 255 * @param w Pointer to the output vector where the proj. results are stored. 256 * 257 * @return 0 if everything executed correctly, otherwise an appropriate 258 * error code. 259 */ 260 int zsl_vec_project(struct zsl_vec *u, struct zsl_vec *v, struct zsl_vec *w); 261 262 /** 263 * @brief Converts (normalises) vector 'v' to a unit vector (a vector of 264 * magnitude or length 1). This is accomploished by dividing each 265 * element by the it's norm. 266 * 267 * @note Unit vectors are important since they have the ability to provide 268 * 'directional' information, without requiring a specific magnitude. 269 * 270 * @param v The vector to convert to a unit vector. 271 * 272 * @return 0 on success, and non-zero error code on failure 273 */ 274 int zsl_vec_to_unit(struct zsl_vec *v); 275 276 /** 277 * @brief Computes the cross (or vector) product of two 3-vectors. 278 * 279 * @param v The first 3-vector. 280 * @param w The second 3-vector. 281 * @param c The cross product 3-vector output. 282 * 283 * @return 0 on success, or -EINVAL if a non 3-vector is provided. 284 * 285 * Given two linearly independent 3-vectors (v and w), the cross product, 286 * (v X w), is a vector that is perpendicular to both v and w and thus 'normal' 287 * to the plane containing them. 288 * 289 * If two vectors have the same direction (or have the exact opposite direction 290 * from one another, i.e. are not linearly independent) or if either one has 291 * zero length, then their cross product is zero. 292 * 293 * The norm of the cross product equals the area of a parallelogram 294 * with vectors v and w for sides. 295 * 296 * For a discusson of geometric and algebraic applications, see: 297 * https://en.wikipedia.org/wiki/Cross_product 298 */ 299 int zsl_vec_cross(struct zsl_vec *v, struct zsl_vec *w, struct zsl_vec *c); 300 301 /** 302 * @brief Computes the vector's sum of squares. 303 * 304 * @param v The vector to use. 305 * 306 * @return The sum of the squares of vector 'v'. 307 */ 308 zsl_real_t zsl_vec_sum_of_sqrs(struct zsl_vec *v); 309 310 /** 311 * @brief Computes the component-wise mean of a set of identically-sized 312 * vectors. 313 * 314 * @param v Pointer to the array of vectors. 315 * @param n The number of vectors in 'v'. 316 * @param m Pointer to the output vector whose i'th element is the mean of 317 * the i'th elements of the input vectors. 318 * 319 * @return 0 on success, and -EINVAL if all vectors aren't identically sized. 320 */ 321 int zsl_vec_mean(struct zsl_vec **v, size_t n, struct zsl_vec *m); 322 323 /** 324 * @brief Computes the arithmetic mean of a vector. 325 * 326 * @param v The vector to use. 327 * @param m The arithmetic mean of vector v. 328 * 329 * @return 0 on success, otherwise an appropriate error code. 330 */ 331 int zsl_vec_ar_mean(struct zsl_vec *v, zsl_real_t *m); 332 333 /** 334 * @brief Reverses the order of the entries in vector 'v'. 335 * 336 * @param v The vector to use. 337 * 338 * @return 0 on success, otherwise an appropriate error code. 339 */ 340 int zsl_vec_rev(struct zsl_vec *v); 341 342 /** 343 * @brief Rearranges the input vector to place any zero-values at the end. 344 * 345 * @param v The input vector to rearrange. 346 * 347 * @warning This function is destructive to 'v'! 348 * 349 * @return 0 if everything executed correctly, otherwise an appropriate 350 * error code. 351 */ 352 int zsl_vec_zte(struct zsl_vec *v); 353 354 /** @} */ /* End of VEC_BASICMATH group */ 355 356 /** 357 * @addtogroup VEC_COMPARE Comparison 358 * 359 * @brief Functions used to compare or verify vectors. 360 * 361 * @ingroup VECTORS 362 * @{ */ 363 364 /** 365 * @brief Checks if two vectors are identical in size and content. 366 * 367 * @param v The first vector. 368 * @param w The second vector. 369 * @param eps The margin for floating-point equality (ex. '1E-5'). 370 * 371 * @return true if the two vectors have the same size and the same values, 372 * otherwise false. 373 */ 374 bool zsl_vec_is_equal(struct zsl_vec *v, struct zsl_vec *w, zsl_real_t eps); 375 376 /** 377 * @brief Checks if all elements in vector v are >= zero. 378 * 379 * @param v The vector to check. 380 * 381 * @return true if all elements in 'v' are zero or positive, otherwise false. 382 */ 383 bool zsl_vec_is_nonneg(struct zsl_vec *v); 384 385 /** 386 * @brief Checks if vector v contains val, returning the number of occurences. 387 * 388 * @param v The vector to check. 389 * @param val The value to check all coefficients for. 390 * @param eps The margin for floating-point equality (ex. '1E-5'). 391 * 392 * @return The number of occurences of val withing range eps, 0 if no 393 * matching occurences were found, or a negative error code. 394 */ 395 int zsl_vec_contains(struct zsl_vec *v, zsl_real_t val, zsl_real_t eps); 396 397 /** 398 * @brief Sorts the values in vector v from smallest to largest using quicksort, 399 * and assigns the sorted output to vector w. 400 * 401 * @param v The unsorted, input vector. 402 * @param w The sorted, output vector. 403 * 404 * @return 0 if everything executed properly, otherwise a negative error code. 405 */ 406 int zsl_vec_sort(struct zsl_vec *v, struct zsl_vec *w); 407 408 /** @} */ /* End of VEC_COMPARE group */ 409 410 /** 411 * @addtogroup VEC_DISPLAY Display 412 * 413 * @brief Functions used to present vectors in a user-friendly format. 414 * 415 * @ingroup VECTORS 416 * @{ */ 417 418 /** 419 * @brief Print the supplied vector using printf in a human-readable manner. 420 * 421 * @param v Pointer to the vector to print. 422 * 423 * @return 0 if everything executed correctly, otherwise an appropriate 424 * error code. 425 */ 426 int zsl_vec_print(struct zsl_vec *v); 427 428 // int zsl_vec_fprint(FILE *stream, zsl_vec *v); 429 430 /** @} */ /* End of VEC_DISPLAY group */ 431 432 #ifdef __cplusplus 433 } 434 #endif 435 436 #endif /* ZEPHYR_INCLUDE_ZSL_VECTORS_H_ */ 437 438 /** @} */ /* End of vectors group */ 439