summaryrefslogtreecommitdiff
path: root/vector.c
diff options
context:
space:
mode:
authorJasper2025-09-08 10:35:14 +0200
committerJasper2025-09-08 10:35:14 +0200
commit1386f6dc5024937c8c9c741efed9274d4861b76f (patch)
tree50c27e867e3551a820e90ac2bd0d43ca087625ef /vector.c
parentbd39c6ab8b87a90944afe271ce847ed0ce090c92 (diff)
Added vector struct
It's completely based on the existing matrix struct and its functions.
Diffstat (limited to 'vector.c')
-rw-r--r--vector.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/vector.c b/vector.c
new file mode 100644
index 0000000..e5bf717
--- /dev/null
+++ b/vector.c
@@ -0,0 +1,186 @@
+#include <math.h>
+#include <stddef.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "utils.h"
+#include "vector.h"
+
+Vector *vector_alloc(size_t m)
+{
+ Vector *v = malloc(sizeof(Vector));
+ assert(v != NULL && "Allocation of vector failed");
+ v->mat = matrix_alloc(m, 1);
+ v->xs = v->mat->xs;
+ v->m = v->mat->m;
+ v->is_colvec = true;
+ return v;
+}
+
+Vector *vector_alloc1(Matrix *mat)
+{
+ assert(matrix_is_colvec(mat) && "Matrix as column vector expected");
+ Vector *v = malloc(sizeof(Vector));
+ v->mat = mat;
+ v->m = mat->m;
+ v->xs = mat->xs;
+ v->is_colvec = true;
+ return v;
+}
+
+void vector_free(Vector *v)
+{
+ matrix_free(v->mat);
+ free(v);
+}
+
+void vector_print(const Vector *v)
+{
+ if (v->is_colvec) matrix_print(v->mat);
+ else matrix_print(matrix_transpose(v->mat));
+}
+
+Vector *vector_from_str(char *str)
+{
+ return vector_alloc1(matrix_from_str(str));
+}
+
+Vector *vector_from_arr(double arr[], size_t m)
+{
+ return vector_alloc1(matrix_from_arr(arr, m, 1));
+}
+
+Vector *vector_unit(size_t m, size_t i)
+{
+ Vector *v = vector_alloc(m);
+
+ vector_foreach_idx(v, it, idx)
+ {
+ if (i != idx) *it = 0;
+ else *it = 1;
+ }
+
+ return v;
+}
+
+Vector *vector_const(size_t m, double x)
+{
+ return vector_alloc1(matrix_const(m, 1, x));
+}
+
+void vector_const1(Vector *v, double x)
+{
+ matrix_const1(v->mat, x);
+}
+
+Vector *vector_slice(const Vector *v, size_t i, size_t j)
+{
+ assert(j < v->m && i < j && "Valid start and end positions expected");
+
+ Vector *w = vector_alloc(j - i);
+
+ vector_foreach_idx(w, it, idx)
+ *it = vector_at(v, i + idx);
+
+ return w;
+}
+
+Vector *vector_copy(const Vector *v)
+{
+ return vector_alloc1(matrix_copy(v->mat));
+}
+
+void vector_copy1(Vector *u, const Vector *v)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ matrix_copy1(u->mat, v->mat);
+}
+
+Vector *vector_transpose(const Vector *v)
+{
+ Vector *w = vector_copy(v);
+ w->is_colvec = false;
+
+ return w;
+}
+
+void vector_transpose1(Vector *v)
+{
+ v->is_colvec = false;
+}
+
+Vector *vector_add(const Vector *u, const Vector *v)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ return vector_alloc1(matrix_add(u->mat, v->mat));
+}
+
+void vector_add1(Vector *u, const Vector *v)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ matrix_add1(u->mat, v->mat);
+}
+
+Vector *vector_scale(const Vector *v, double x)
+{
+ return vector_alloc1(matrix_scale(v->mat, x));
+}
+
+void vector_scale1(Vector *v, double x)
+{
+ matrix_scale1(v->mat, x);
+}
+
+Vector *vector_sub(const Vector *u, const Vector *v)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ return vector_alloc1(matrix_sub(u->mat, v->mat));
+}
+
+void vector_sub1(Vector *u, const Vector *v)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ matrix_sub1(u->mat, v->mat);
+}
+
+Vector *vector_rand(size_t m, int bound_l, int bound_u)
+{
+ return vector_alloc1(matrix_rand(m, 1, bound_l, bound_u, MATRIX_NONE));
+}
+
+void vector_rand1(Vector *v, int bound_l, int bound_u)
+{
+ matrix_rand1(v->mat, bound_l, bound_u, MATRIX_NONE);
+}
+
+bool vector_eq(const Vector *u, const Vector *v, double tol)
+{
+ assert(VECTOR_DIM_MATCH(u, v) && "Dimension mismatch");
+
+ return matrix_eq(u->mat, v->mat, tol);
+}
+
+double vector_norm_p(const Vector *v, size_t p)
+{
+ assert(p >= 1 && "Nonzero p expected");
+
+ double tmp = 0;
+ vector_foreach(v, it)
+ tmp += pow(ABS(*it), p);
+ return pow(tmp, 1.0/p);
+}
+
+double vector_norm_max(const Vector *v)
+{
+ double tmp = ABS(v->xs[0]);
+ vector_foreach(v, it)
+ if (ABS(*it) > tmp) tmp = ABS(*it);
+
+ return tmp;
+}