[math] Adding vector sort and vector argsort to numeric vectors
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
#ifndef VECTOR_H
|
#ifndef VECTOR_H
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define DEFAULT_VECTOR_SIZE 8
|
#define DEFAULT_VECTOR_SIZE 8
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
|
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
|||||||
@@ -6,15 +6,17 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
|
#define ks_lt_index(a, b) ((a).value < (b).value)
|
||||||
|
|
||||||
#define VECTOR_INIT_NUMERIC(name, type, unsigned_type, type_abs) \
|
#define VECTOR_INIT_NUMERIC(name, type, unsigned_type, type_abs) \
|
||||||
__VECTOR_BASE(name, type) \
|
__VECTOR_BASE(name, type) \
|
||||||
__VECTOR_DESTROY(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)); \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] = value; \
|
array[i] = value; \
|
||||||
} \
|
} \
|
||||||
@@ -23,7 +25,7 @@
|
|||||||
static inline name *name##_new_value(size_t n, type value) { \
|
static inline name *name##_new_value(size_t n, type value) { \
|
||||||
name *vector = name##_new_size(n); \
|
name *vector = name##_new_size(n); \
|
||||||
if (vector == NULL) return NULL; \
|
if (vector == NULL) return NULL; \
|
||||||
type##_array_set(vector->a, n, (type)value); \
|
name##_set(vector->a, n, (type)value); \
|
||||||
vector->n = n; \
|
vector->n = n; \
|
||||||
return vector; \
|
return vector; \
|
||||||
} \
|
} \
|
||||||
@@ -34,12 +36,12 @@
|
|||||||
\
|
\
|
||||||
static inline name *name##_new_zeros(size_t n) { \
|
static inline name *name##_new_zeros(size_t n) { \
|
||||||
name *vector = name##_new_size(n); \
|
name *vector = name##_new_size(n); \
|
||||||
type##_array_zero(vector->a, n); \
|
name##_zero(vector->a, n); \
|
||||||
vector->n = n; \
|
vector->n = n; \
|
||||||
return vector; \
|
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; \
|
if (n < 1) return (type) 0; \
|
||||||
type val = array[0]; \
|
type val = array[0]; \
|
||||||
type max_val = val; \
|
type max_val = val; \
|
||||||
@@ -50,7 +52,7 @@
|
|||||||
return max_val; \
|
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; \
|
if (n < 1) return (type) 0; \
|
||||||
type val = array[0]; \
|
type val = array[0]; \
|
||||||
type min_val = val; \
|
type min_val = val; \
|
||||||
@@ -61,7 +63,7 @@
|
|||||||
return min_val; \
|
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; \
|
if (n < 1) return -1; \
|
||||||
type val = array[0]; \
|
type val = array[0]; \
|
||||||
type max_val = val; \
|
type max_val = val; \
|
||||||
@@ -76,7 +78,7 @@
|
|||||||
return argmax; \
|
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; \
|
if (n < 1) return (type) -1; \
|
||||||
type val = array[0]; \
|
type val = array[0]; \
|
||||||
type min_val = val; \
|
type min_val = val; \
|
||||||
@@ -91,31 +93,58 @@
|
|||||||
return argmin; \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] += c; \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] -= c; \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] *= c; \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] /= c; \
|
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; \
|
type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += array[i]; \
|
result += array[i]; \
|
||||||
@@ -123,7 +152,7 @@
|
|||||||
return result; \
|
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; \
|
unsigned_type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += type_abs(array[i]); \
|
result += type_abs(array[i]); \
|
||||||
@@ -131,7 +160,7 @@
|
|||||||
return result; \
|
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; \
|
unsigned_type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += array[i] * array[i]; \
|
result += array[i] * array[i]; \
|
||||||
@@ -139,7 +168,7 @@
|
|||||||
return result; \
|
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; \
|
type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result *= array[i]; \
|
result *= array[i]; \
|
||||||
@@ -147,31 +176,31 @@
|
|||||||
return result; \
|
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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
a1[i] += a2[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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
a1[i] -= a2[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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
a1[i] *= a2[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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
a1[i] /= a2[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; \
|
type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += a1[i] * a2[i]; \
|
result += a1[i] * a2[i]; \
|
||||||
@@ -184,19 +213,19 @@
|
|||||||
#define VECTOR_INIT_NUMERIC_FLOAT(name, type, type_abs) \
|
#define VECTOR_INIT_NUMERIC_FLOAT(name, type, type_abs) \
|
||||||
VECTOR_INIT_NUMERIC(name, type, 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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] = log(array[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++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
array[i] = exp(array[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; \
|
type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += log(array[i]); \
|
result += log(array[i]); \
|
||||||
@@ -204,8 +233,8 @@
|
|||||||
return result; \
|
return result; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline type type##_array_log_sum_exp(type *array, size_t n) { \
|
static inline type name##_log_sum_exp(type *array, size_t n) { \
|
||||||
type max = type##_array_max(array, n); \
|
type max = name##_max(array, n); \
|
||||||
type result = 0; \
|
type result = 0; \
|
||||||
for (int i = 0; i < n; i++) { \
|
for (int i = 0; i < n; i++) { \
|
||||||
result += exp(array[i] - max); \
|
result += exp(array[i] - max); \
|
||||||
|
|||||||
Reference in New Issue
Block a user