From 1386f6dc5024937c8c9c741efed9274d4861b76f Mon Sep 17 00:00:00 2001 From: Jasper Date: Mon, 8 Sep 2025 10:35:14 +0200 Subject: Added vector struct It's completely based on the existing matrix struct and its functions. --- build.sh | 2 +- vector.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vector.h | 67 +++++++++++++++++++++++ 3 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 vector.c create mode 100644 vector.h diff --git a/build.sh b/build.sh index 6ec6b63..82d4c4c 100755 --- a/build.sh +++ b/build.sh @@ -2,4 +2,4 @@ if [ ! -d "bin" ]; then mkdir bin fi -gcc -Wall -Wextra -pedantic -lm -o bin/linalg_debug debug.c tests.c utils.c matrix.c +gcc -Wall -Wextra -pedantic -lm -o bin/linalg_debug debug.c tests.c utils.c matrix.c vector.c 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 +#include +#include +#include +#include + +#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; +} diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..c10a765 --- /dev/null +++ b/vector.h @@ -0,0 +1,67 @@ +#ifndef VECTOR_H +#define VECTOR_H + +#include + +#include "matrix.h" + +#define vector_at(v, i) ((v)->xs[(i)]) + +#define vector_loop(v, i) matrix_loop((v)->mat, i) + +#define vector_foreach(v, it) matrix_foreach((v)->mat, it) + +#define vector_foreach_idx(v, it, i) matrix_foreach_idx((v)->mat, it, i, _) + +#define VECTOR_DIM_MATCH(v1, v2) ((v1)->m == (v2)->m) + +typedef struct { + double *xs; + size_t m; + Matrix *mat; + bool is_colvec; +} Vector; + +Vector *vector_alloc(size_t m); +Vector *vector_alloc1(Matrix *mat); + +void vector_free(Vector *v); + +void vector_print(const Vector *v); + +Vector *vector_from_str(char *str); +Vector *vector_from_arr(double arr[], size_t m); + +Vector *vector_unit(size_t m, size_t i); + +Vector *vector_const(size_t m, double x); +void vector_const1(Vector *v, double x); + +Vector *vector_slice(const Vector *v, size_t i, size_t j); + +Vector *vector_copy(const Vector *v); +void vector_copy1(Vector *u, const Vector *v); + +Vector *vector_transpose(const Vector *v); +void vector_transpose1(Vector *v); + +Vector *vector_add(const Vector *u, const Vector *v); +void vector_add1(Vector *u, const Vector *v); + +Vector *vector_scale(const Vector *v, double x); +void vector_scale1(Vector *v, double x); + +double vector_norm_p(const Vector *x, size_t p); + +Vector *vector_sub(const Vector *u, const Vector *v); +void vector_sub1(Vector *u, const Vector *v); + +Vector *vector_rand(size_t m, int bound_l, int bound_u); +void vector_rand1(Vector *v, int bound_l, int bound_u); + +bool vector_eq(const Vector *u, const Vector *v, double tol); + +double vector_norm_p(const Vector *v, size_t p); +double vector_norm_max(const Vector *v); + +#endif -- cgit v1.2.3