diff options
Diffstat (limited to 'vector.c')
-rw-r--r-- | vector.c | 186 |
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; +} |