diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-10-11 10:04:04 -0600 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-10-11 10:04:04 -0600 |
commit | 43f06890e2689af2ef54c4480fe5790692a24f65 (patch) | |
tree | b933f3e05aad81d780c0c94646676efa1bbad22d /src/vector.c | |
parent | a74a732b27fb610133190e89a91b2d42d0cf78b3 (diff) | |
download | cmath-43f06890e2689af2ef54c4480fe5790692a24f65.tar.gz cmath-43f06890e2689af2ef54c4480fe5790692a24f65.zip |
deprecate common lisp solutions and write c; it's too much effort to keep up with the requirements for an archive.
Diffstat (limited to 'src/vector.c')
-rw-r--r-- | src/vector.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/vector.c b/src/vector.c new file mode 100644 index 0000000..61692e1 --- /dev/null +++ b/src/vector.c @@ -0,0 +1,90 @@ +#include "lizfcm.h" +#include <assert.h> +#include <float.h> +#include <math.h> +#include <stdio.h> + +double l2_norm(Array_double *v) { + double norm = 0; + for (size_t i = 0; i < v->size; ++i) + norm += v->data[i] * v->data[i]; + return sqrt(norm); +} + +double l1_norm(Array_double *v) { + double sum = 0; + for (size_t i = 0; i < v->size; ++i) + sum += fabs(v->data[i]); + return sum; +} + +double linf_norm(Array_double *v) { + double max = -DBL_MAX; + for (size_t i = 0; i < v->size; ++i) + max = c_max(v->data[i], max); + return max; +} + +Array_double *minus_v(Array_double *v1, Array_double *v2) { + assert(v1->size == v2->size); + + Array_double *sub = InitArrayWithSize(double, v1->size, 0); + for (size_t i = 0; i < v1->size; i++) + sub->data[i] = v1->data[i] - v2->data[i]; + return sub; +} + +double sum_v(Array_double *v) { + double sum = 0; + for (size_t i = 0; i < v->size; i++) + sum += v->data[i]; + return sum; +} + +Array_double *add_v(Array_double *v1, Array_double *v2) { + assert(v1->size == v2->size); + + Array_double *sum = InitArrayWithSize(double, v1->size, 0); + for (size_t i = 0; i < v1->size; i++) + sum->data[i] = v1->data[i] + v2->data[i]; + return sum; +} + +double dot_v(Array_double *v1, Array_double *v2) { + assert(v1->size == v2->size); + + double dot = 0; + for (size_t i = 0; i < v1->size; i++) + dot += v1->data[i] * v2->data[i]; + return dot; +} + +double l2_distance(Array_double *v1, Array_double *v2) { + Array_double *minus = minus_v(v1, v2); + double dist = l2_norm(minus); + free(minus); + return dist; +} + +double l1_distance(Array_double *v1, Array_double *v2) { + Array_double *minus = minus_v(v1, v2); + double dist = l1_norm(minus); + free(minus); + return dist; +} + +double linf_distance(Array_double *v1, Array_double *v2) { + Array_double *minus = minus_v(v1, v2); + double dist = linf_norm(minus); + free(minus); + return dist; +} + +void format_vector_into(Array_double *v, char *s) { + sprintf(s, ""); + if (v->size == 0) + sprintf(s, "empty"); + + for (size_t i = 0; i < v->size; ++i) + sprintf(s, "%s %f,", s, v->data[i]); +} |