#ifndef VECTOR_MATH_H #define VECTOR_MATH_H #include #include #include #include "vector.h" #define VECTOR_INIT_NUMERIC(name, type, unsigned_type, type_abs) \ __VECTOR_BASE(name, type) \ __VECTOR_DESTROY(name, type) \ \ static inline void type##_array_zero(type *array, size_t n) { \ memset(array, 0, n * sizeof(type)); \ } \ \ static inline void type##_array_set(type *array, size_t n, type value) { \ for (int i = 0; i < n; i++) { \ array[i] = value; \ } \ } \ \ static inline name *name##_new_value(size_t n, type value) { \ name *vector = name##_new_size(n); \ if (vector == NULL) return NULL; \ type##_array_set(vector->a, n, (type)value); \ vector->n = n; \ return vector; \ } \ \ static inline name *name##_new_ones(size_t n) { \ return name##_new_value(n, (type)1); \ } \ \ static inline name *name##_new_zeros(size_t n) { \ name *vector = name##_new_size(n); \ memset(vector->a, 0, n * sizeof(type)); \ vector->n = n; \ return vector; \ } \ \ static inline type type##_array_max(type *array, size_t n) { \ if (n < 1) return (type) 0; \ type val = array[0]; \ type max_val = val; \ for (int i = 1; i < n; i++) { \ val = array[i]; \ if (val > max_val) max_val = val; \ } \ return max_val; \ } \ \ static inline type type##_array_min(type *array, size_t n) { \ if (n < 1) return (type) 0; \ type val = array[0]; \ type min_val = val; \ for (int i = 1; i < n; i++) { \ val = array[i]; \ if (val < min_val) min_val = val; \ } \ return min_val; \ } \ \ static inline int64_t type##_array_argmax(type *array, size_t n) { \ if (n < 1) return -1; \ type val = array[0]; \ type max_val = val; \ int64_t argmax = 0; \ for (int i = 0; i < n; i++) { \ val = array[i]; \ if (val > max_val) { \ max_val = val; \ argmax = i; \ } \ } \ return argmax; \ } \ \ static inline int64_t type##_array_argmin(type *array, size_t n) { \ if (n < 1) return (type) -1; \ type val = array[0]; \ type min_val = val; \ int64_t argmin = 0; \ for (int i = 1; i < n; i++) { \ val = array[i]; \ if (val < min_val) { \ min_val = val; \ argmin = i; \ } \ } \ return argmin; \ } \ \ static inline void type##_array_add(type *array, type c, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] += c; \ } \ } \ \ static inline void type##_array_sub(type *array, type c, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] -= c; \ } \ } \ \ static inline void type##_array_mul(type *array, type c, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] *= c; \ } \ } \ \ static inline void type##_array_div(type *array, type c, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] /= c; \ } \ } \ \ static inline type type##_array_sum(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += array[i]; \ } \ return result; \ } \ \ static inline unsigned_type type##_array_l1_norm(type *array, size_t n) { \ unsigned_type result = 0; \ for (int i = 0; i < n; i++) { \ result += type_abs(array[i]); \ } \ return result; \ } \ \ static inline unsigned_type type##_array_l2_norm(type *array, size_t n) { \ unsigned_type result = 0; \ for (int i = 0; i < n; i++) { \ result += array[i] * array[i]; \ } \ return result; \ } \ \ static inline type type##_array_product(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result *= array[i]; \ } \ return result; \ } \ \ static inline void type##_array_add_array(type *a1, type *a2, size_t n) { \ for (int i = 0; i < n; i++) { \ a1[i] += a2[i]; \ } \ } \ \ static inline void type##_array_sub_array(type *a1, type *a2, size_t n) { \ for (int i = 0; i < n; i++) { \ a1[i] -= a2[i]; \ } \ } \ \ static inline void type##_array_mul_array(type *a1, type *a2, size_t n) { \ for (int i = 0; i < n; i++) { \ a1[i] *= a2[i]; \ } \ } \ \ static inline void type##_array_div_array(type *a1, type *a2, size_t n) { \ for (int i = 0; i < n; i++) { \ a1[i] /= a2[i]; \ } \ } \ \ static inline type type##_array_dot(type *a1, type *a2, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += a1[i] * a2[i]; \ } \ return result; \ } #define VECTOR_INIT_NUMERIC_FLOAT(name, type, type_abs) \ VECTOR_INIT_NUMERIC(name, type, type, type_abs) \ \ static inline void type##_array_log(type *array, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] = log(array[i]); \ } \ } \ \ static inline void type##_array_exp(type *array, size_t n) { \ for (int i = 0; i < n; i++) { \ array[i] = exp(array[i]); \ } \ } \ \ static inline type type##_array_log_sum(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += log(array[i]); \ } \ return result; \ } \ \ static inline type type##_array_log_sum_exp(type *array, size_t n) { \ type max = type##_array_max(array, n); \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += exp(array[i] - max); \ } \ return max + log(result); \ } #endif