From 818f9ec1af64b58a57e280de5df96a9770e20824 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 24 Apr 2023 09:22:53 +0200 Subject: [PATCH] Also added vector/matrix methods to MLPPVector and MLPPMatrix from LinAlg. --- mlpp/lin_alg/mlpp_matrix.cpp | 75 ++++++++++++++++++++++++++++++++++++ mlpp/lin_alg/mlpp_matrix.h | 7 ++++ mlpp/lin_alg/mlpp_vector.cpp | 60 +++++++++++++++++++++++++++++ mlpp/lin_alg/mlpp_vector.h | 8 ++++ 4 files changed, 150 insertions(+) diff --git a/mlpp/lin_alg/mlpp_matrix.cpp b/mlpp/lin_alg/mlpp_matrix.cpp index d43cfd2..cde8a1f 100644 --- a/mlpp/lin_alg/mlpp_matrix.cpp +++ b/mlpp/lin_alg/mlpp_matrix.cpp @@ -1066,6 +1066,81 @@ bool MLPPMatrix::zeroEigenvalue(std::vector> A) { } */ +Ref MLPPMatrix::mat_vec_multnv(const Ref &A, const Ref &b) { + ERR_FAIL_COND_V(!A.is_valid() || !b.is_valid(), Ref()); + + Size2i a_size = A->size(); + int b_size = b->size(); + + ERR_FAIL_COND_V(a_size.x < b->size(), Ref()); + + Ref c; + c.instance(); + c->resize(a_size.y); + c->fill(0); + + const real_t *a_ptr = A->ptr(); + const real_t *b_ptr = b->ptr(); + real_t *c_ptr = c->ptrw(); + + for (int i = 0; i < a_size.y; ++i) { + for (int k = 0; k < b_size; ++k) { + int mat_index = A->calculate_index(i, k); + + c_ptr[i] += a_ptr[mat_index] * b_ptr[k]; + } + } + + return c; +} + + +Ref MLPPMatrix::mat_vec_addnm(const Ref &A, const Ref &b) { + ERR_FAIL_COND_V(!A.is_valid() || !b.is_valid(), Ref()); + + Size2i a_size = A->size(); + + ERR_FAIL_COND_V(a_size.x != b->size(), Ref()); + + Ref ret; + ret.instance(); + ret->resize(a_size); + + const real_t *a_ptr = A->ptr(); + const real_t *b_ptr = b->ptr(); + real_t *ret_ptr = ret->ptrw(); + + for (int i = 0; i < a_size.y; ++i) { + for (int j = 0; j < a_size.x; ++j) { + int mat_index = A->calculate_index(i, j); + + ret_ptr[mat_index] = a_ptr[mat_index] + b_ptr[j]; + } + } + + return ret; +} + +Ref MLPPMatrix::diagnm(const Ref &a) { + int a_size = a->size(); + + Ref B; + B.instance(); + + B->resize(Size2i(a_size, a_size)); + B->fill(0); + + const real_t *a_ptr = a->ptr(); + real_t *b_ptr = B->ptrw(); + + for (int i = 0; i < a_size; ++i) { + b_ptr[B->calculate_index(i, i)] = a_ptr[i]; + } + + return B; +} + + String MLPPMatrix::to_string() { String str; diff --git a/mlpp/lin_alg/mlpp_matrix.h b/mlpp/lin_alg/mlpp_matrix.h index 56acfb6..1f18986 100644 --- a/mlpp/lin_alg/mlpp_matrix.h +++ b/mlpp/lin_alg/mlpp_matrix.h @@ -698,6 +698,13 @@ public: bool zeroEigenvalue(std::vector> A); */ + Ref mat_vec_multnv(const Ref &A, const Ref &b); + Ref mat_vec_addnm(const Ref &A, const Ref &b); + + // set_diagonal (just sets diagonal), set_as_diagonal (zeros, then sets diagonal to vec) + // Also a variant that copies + Ref diagnm(const Ref &a); + _FORCE_INLINE_ bool is_equal_approx(const Ref &p_with, real_t tolerance = static_cast(CMP_EPSILON)) const { ERR_FAIL_COND_V(!p_with.is_valid(), false); diff --git a/mlpp/lin_alg/mlpp_vector.cpp b/mlpp/lin_alg/mlpp_vector.cpp index ba824c9..aad1c33 100644 --- a/mlpp/lin_alg/mlpp_vector.cpp +++ b/mlpp/lin_alg/mlpp_vector.cpp @@ -1,6 +1,8 @@ #include "mlpp_vector.h" +#include "mlpp_matrix.h" + Ref MLPPVector::flattenmnv(const Vector> &A) { Ref a; a.instance(); @@ -644,6 +646,64 @@ real_t MLPPVector::cosineSimilarity(std::vector a, std::vector b } */ +Ref MLPPVector::subtract_matrix_rowsnv(const Ref &a, const Ref &B) { + Ref c = a->duplicate(); + + Size2i b_size = B->size(); + + ERR_FAIL_COND_V(b_size.x != c->size(), c); + + const real_t *b_ptr = B->ptr(); + real_t *c_ptr = c->ptrw(); + + for (int i = 0; i < b_size.y; ++i) { + for (int j = 0; j < b_size.x; ++j) { + c_ptr[j] -= b_ptr[B->calculate_index(i, j)]; + } + } + + return c; +} + +Ref MLPPVector::outer_product(const Ref &a, const Ref &b) { + Ref C; + C.instance(); + Size2i size = Size2i(b->size(), a->size()); + C->resize(size); + + const real_t *a_ptr = a->ptr(); + const real_t *b_ptr = b->ptr(); + + for (int i = 0; i < size.y; ++i) { + real_t curr_a = a_ptr[i]; + + for (int j = 0; j < size.x; ++j) { + C->set_element(i, j, curr_a * b_ptr[j]); + } + } + + return C; +} + +Ref MLPPVector::diagnm(const Ref &a) { + int a_size = a->size(); + + Ref B; + B.instance(); + + B->resize(Size2i(a_size, a_size)); + B->fill(0); + + const real_t *a_ptr = a->ptr(); + real_t *b_ptr = B->ptrw(); + + for (int i = 0; i < a_size; ++i) { + b_ptr[B->calculate_index(i, i)] = a_ptr[i]; + } + + return B; +} + String MLPPVector::to_string() { String str; diff --git a/mlpp/lin_alg/mlpp_vector.h b/mlpp/lin_alg/mlpp_vector.h index 4c7b3ae..9268471 100644 --- a/mlpp/lin_alg/mlpp_vector.h +++ b/mlpp/lin_alg/mlpp_vector.h @@ -15,6 +15,8 @@ //REMOVE #include +class MLPPMatrix; + class MLPPVector : public Reference { GDCLASS(MLPPVector, Reference); @@ -392,6 +394,12 @@ public: //real_t cosineSimilarity(std::vector a, std::vector b); + Ref subtract_matrix_rowsnv(const Ref &a, const Ref &B); + Ref outer_product(const Ref &a, const Ref &b); // This multiplies a, bT + + // as_diagonal_matrix / to_diagonal_matrix + Ref diagnm(const Ref &a); + String to_string(); _FORCE_INLINE_ MLPPVector() {