diff --git a/src/vector.h b/src/vector.h index e2952f52..6877fe63 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,8 +1,6 @@ #ifndef VECTOR_H #define VECTOR_H -#include - #define DEFAULT_VECTOR_SIZE 8 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) diff --git a/src/vector_math.h b/src/vector_math.h index 729f7d10..23ae17fb 100644 --- a/src/vector_math.h +++ b/src/vector_math.h @@ -6,15 +6,17 @@ #include #include "vector.h" +#define ks_lt_index(a, b) ((a).value < (b).value) + #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) { \ + static inline void name##_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) { \ + static inline void name##_set(type *array, size_t n, type value) { \ for (int i = 0; i < n; i++) { \ array[i] = value; \ } \ @@ -23,7 +25,7 @@ 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); \ + name##_set(vector->a, n, (type)value); \ vector->n = n; \ return vector; \ } \ @@ -34,12 +36,12 @@ \ static inline name *name##_new_zeros(size_t n) { \ name *vector = name##_new_size(n); \ - type##_array_zero(vector->a, n); \ + name##_zero(vector->a, n); \ vector->n = n; \ return vector; \ } \ \ - static inline type type##_array_max(type *array, size_t n) { \ + static inline type name##_max(type *array, size_t n) { \ if (n < 1) return (type) 0; \ type val = array[0]; \ type max_val = val; \ @@ -50,7 +52,7 @@ return max_val; \ } \ \ - static inline type type##_array_min(type *array, size_t n) { \ + static inline type name##_min(type *array, size_t n) { \ if (n < 1) return (type) 0; \ type val = array[0]; \ type min_val = val; \ @@ -61,7 +63,7 @@ return min_val; \ } \ \ - static inline int64_t type##_array_argmax(type *array, size_t n) { \ + static inline int64_t name##_argmax(type *array, size_t n) { \ if (n < 1) return -1; \ type val = array[0]; \ type max_val = val; \ @@ -76,7 +78,7 @@ return argmax; \ } \ \ - static inline int64_t type##_array_argmin(type *array, size_t n) { \ + static inline int64_t name##_argmin(type *array, size_t n) { \ if (n < 1) return (type) -1; \ type val = array[0]; \ type min_val = val; \ @@ -91,31 +93,58 @@ return argmin; \ } \ \ - static inline void type##_array_add(type *array, type c, size_t n) { \ + typedef struct type##_index { \ + size_t index; \ + type value; \ + } type##_index_t; \ + \ + KSORT_INIT_GENERIC(type) \ + KSORT_INIT(type##_indices, type##_index_t, ks_lt_index) \ + \ + static inline void name##_sort(type *array, size_t n) { \ + ks_introsort(type, n, array); \ + } \ + \ + static inline size_t *name##_argsort(type *array, size_t n) { \ + type##_index_t *type_indices = malloc(sizeof(type##_index_t) * n); \ + size_t i; \ + for (i = 0; i < n; i++) { \ + type_indices[i] = (type##_index_t){i, array[i]}; \ + } \ + ks_introsort(type##_indices, n, type_indices); \ + size_t *indices = malloc(sizeof(size_t) * n); \ + for (i = 0; i < n; i++) { \ + indices[i] = type_indices[i].index; \ + } \ + free(type_indices); \ + return indices; \ + } \ + \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline type name##_sum(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += array[i]; \ @@ -123,7 +152,7 @@ return result; \ } \ \ - static inline unsigned_type type##_array_l1_norm(type *array, size_t n) { \ + static inline unsigned_type name##_l1_norm(type *array, size_t n) { \ unsigned_type result = 0; \ for (int i = 0; i < n; i++) { \ result += type_abs(array[i]); \ @@ -131,7 +160,7 @@ return result; \ } \ \ - static inline unsigned_type type##_array_l2_norm(type *array, size_t n) { \ + static inline unsigned_type name##_l2_norm(type *array, size_t n) { \ unsigned_type result = 0; \ for (int i = 0; i < n; i++) { \ result += array[i] * array[i]; \ @@ -139,7 +168,7 @@ return result; \ } \ \ - static inline type type##_array_product(type *array, size_t n) { \ + static inline type name##_product(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result *= array[i]; \ @@ -147,31 +176,31 @@ return result; \ } \ \ - static inline void type##_array_add_array(type *a1, type *a2, size_t n) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline type name##_dot(type *a1, type *a2, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += a1[i] * a2[i]; \ @@ -184,19 +213,19 @@ #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) { \ + static inline void name##_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) { \ + static inline void name##_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) { \ + static inline type name##_log_sum(type *array, size_t n) { \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += log(array[i]); \ @@ -204,8 +233,8 @@ return result; \ } \ \ - static inline type type##_array_log_sum_exp(type *array, size_t n) { \ - type max = type##_array_max(array, n); \ + static inline type name##_log_sum_exp(type *array, size_t n) { \ + type max = name##_max(array, n); \ type result = 0; \ for (int i = 0; i < n; i++) { \ result += exp(array[i] - max); \