From bd9c03f1f2b52b00a9ab9f9af604a938ebfe098c Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 24 Apr 2023 18:11:22 +0200 Subject: [PATCH] MLPPVector math api rework pt4. --- mlpp/lin_alg/mlpp_matrix.cpp | 20 ++++++++ mlpp/lin_alg/mlpp_matrix.h | 2 + mlpp/lin_alg/mlpp_vector.cpp | 97 +++++++++++++++++++++--------------- mlpp/lin_alg/mlpp_vector.h | 18 ++++--- 4 files changed, 91 insertions(+), 46 deletions(-) diff --git a/mlpp/lin_alg/mlpp_matrix.cpp b/mlpp/lin_alg/mlpp_matrix.cpp index cde8a1f..639eeb6 100644 --- a/mlpp/lin_alg/mlpp_matrix.cpp +++ b/mlpp/lin_alg/mlpp_matrix.cpp @@ -1121,6 +1121,26 @@ Ref MLPPMatrix::mat_vec_addnm(const Ref &A, const Ref MLPPMatrix::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 MLPPMatrix::diagnm(const Ref &a) { int a_size = a->size(); diff --git a/mlpp/lin_alg/mlpp_matrix.h b/mlpp/lin_alg/mlpp_matrix.h index 1f18986..5e1bb39 100644 --- a/mlpp/lin_alg/mlpp_matrix.h +++ b/mlpp/lin_alg/mlpp_matrix.h @@ -701,6 +701,8 @@ public: Ref mat_vec_multnv(const Ref &A, const Ref &b); Ref mat_vec_addnm(const Ref &A, const Ref &b); + Ref outer_product(const Ref &a, const Ref &b); // This multiplies a, bT + // set_diagonal (just sets diagonal), set_as_diagonal (zeros, then sets diagonal to vec) // Also a variant that copies Ref diagnm(const Ref &a); diff --git a/mlpp/lin_alg/mlpp_vector.cpp b/mlpp/lin_alg/mlpp_vector.cpp index 3ae9c8e..3782bcd 100644 --- a/mlpp/lin_alg/mlpp_vector.cpp +++ b/mlpp/lin_alg/mlpp_vector.cpp @@ -838,37 +838,33 @@ std::vector> MLPPVector::round(std::vector &a, const Ref &b) { - ERR_FAIL_COND_V(!a.is_valid() || !b.is_valid(), 0); +real_t MLPPVector::euclidean_distance(const Ref &b) { + ERR_FAIL_COND_V(!b.is_valid(), 0); - int a_size = a->size(); + ERR_FAIL_COND_V(_size != b->size(), 0); - ERR_FAIL_COND_V(a_size != b->size(), 0); - - const real_t *aa = a->ptr(); + const real_t *aa = ptr(); const real_t *ba = b->ptr(); real_t dist = 0; - for (int i = 0; i < a_size; i++) { + for (int i = 0; i < _size; i++) { dist += (aa[i] - ba[i]) * (aa[i] - ba[i]); } return Math::sqrt(dist); } -real_t MLPPVector::euclidean_distance_squared(const Ref &a, const Ref &b) { - ERR_FAIL_COND_V(!a.is_valid() || !b.is_valid(), 0); +real_t MLPPVector::euclidean_distance_squared(const Ref &b) { + ERR_FAIL_COND_V(!b.is_valid(), 0); - int a_size = a->size(); + ERR_FAIL_COND_V(_size != b->size(), 0); - ERR_FAIL_COND_V(a_size != b->size(), 0); - - const real_t *aa = a->ptr(); + const real_t *aa = ptr(); const real_t *ba = b->ptr(); real_t dist = 0; - for (int i = 0; i < a_size; i++) { + for (int i = 0; i < _size; i++) { dist += (aa[i] - ba[i]) * (aa[i] - ba[i]); } @@ -887,26 +883,21 @@ real_t MLPPVector::norm_2(std::vector> A) { } */ -real_t MLPPVector::norm_sqv(const Ref &a) { - ERR_FAIL_COND_V(!a.is_valid(), 0); - - int size = a->size(); - const real_t *a_ptr = a->ptr(); +real_t MLPPVector::norm_sq() { + const real_t *a_ptr = ptr(); real_t n_sq = 0; - for (int i = 0; i < size; ++i) { + for (int i = 0; i < _size; ++i) { n_sq += a_ptr[i] * a_ptr[i]; } return n_sq; } -real_t MLPPVector::sum_elementsv(const Ref &a) { - int a_size = a->size(); - - const real_t *a_ptr = a->ptr(); +real_t MLPPVector::sum_elements() { + const real_t *a_ptr = ptr(); real_t sum = 0; - for (int i = 0; i < a_size; ++i) { + for (int i = 0; i < _size; ++i) { sum += a_ptr[i]; } return sum; @@ -918,8 +909,22 @@ 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(); +void MLPPVector::subtract_matrix_rows(const Ref &B) { + Size2i b_size = B->size(); + + ERR_FAIL_COND(b_size.x != size()); + + const real_t *b_ptr = B->ptr(); + real_t *c_ptr = 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)]; + } + } +} +Ref MLPPVector::subtract_matrix_rowsn(const Ref &B) { + Ref c = duplicate(); Size2i b_size = B->size(); @@ -936,20 +941,36 @@ Ref MLPPVector::subtract_matrix_rowsnv(const Ref &a, con return c; } +void MLPPVector::subtract_matrix_rowsb(const Ref &a, const Ref &B) { + Size2i b_size = B->size(); -Ref MLPPVector::outer_product(const Ref &a, const Ref &b) { + ERR_FAIL_COND(b_size.x != a->size()); + + set_from_mlpp_vector(a); + + const real_t *b_ptr = B->ptr(); + real_t *c_ptr = 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)]; + } + } +} + +Ref MLPPVector::outer_product(const Ref &b) { Ref C; C.instance(); - Size2i size = Size2i(b->size(), a->size()); - C->resize(size); + Size2i sm = Size2i(b->size(), size()); + C->resize(sm); - const real_t *a_ptr = a->ptr(); + const real_t *a_ptr = ptr(); const real_t *b_ptr = b->ptr(); - for (int i = 0; i < size.y; ++i) { + for (int i = 0; i < sm.y; ++i) { real_t curr_a = a_ptr[i]; - for (int j = 0; j < size.x; ++j) { + for (int j = 0; j < sm.x; ++j) { C->set_element(i, j, curr_a * b_ptr[j]); } } @@ -957,19 +978,17 @@ Ref MLPPVector::outer_product(const Ref &a, const Ref MLPPVector::diagnm(const Ref &a) { - int a_size = a->size(); - +Ref MLPPVector::diagnm() { Ref B; B.instance(); - B->resize(Size2i(a_size, a_size)); + B->resize(Size2i(_size, _size)); B->fill(0); - const real_t *a_ptr = a->ptr(); + const real_t *a_ptr = ptr(); real_t *b_ptr = B->ptrw(); - for (int i = 0; i < a_size; ++i) { + for (int i = 0; i < _size; ++i) { b_ptr[B->calculate_index(i, i)] = a_ptr[i]; } diff --git a/mlpp/lin_alg/mlpp_vector.h b/mlpp/lin_alg/mlpp_vector.h index 3309d8f..a833f3c 100644 --- a/mlpp/lin_alg/mlpp_vector.h +++ b/mlpp/lin_alg/mlpp_vector.h @@ -423,24 +423,28 @@ public: //std::vector round(std::vector a); - real_t euclidean_distance(const Ref &a, const Ref &b); - real_t euclidean_distance_squared(const Ref &a, const Ref &b); + real_t euclidean_distance(const Ref &b); + real_t euclidean_distance_squared(const Ref &b); /* real_t norm_2(std::vector a); */ - real_t norm_sqv(const Ref &a); + real_t norm_sq(); - real_t sum_elementsv(const Ref &a); + real_t sum_elements(); //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 + void subtract_matrix_rows(const Ref &B); + Ref subtract_matrix_rowsn(const Ref &B); + void subtract_matrix_rowsb(const Ref &a, const Ref &B); + + // This multiplies a, bT + Ref outer_product(const Ref &b); // as_diagonal_matrix / to_diagonal_matrix - Ref diagnm(const Ref &a); + Ref diagnm(); String to_string();