From d26daf4c1a03add01e62e78a277728b47d2fc5a6 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 31 Jan 2023 03:20:20 +0100 Subject: [PATCH] More cleanups. --- mlpp/activation/activation.cpp | 17 +++- mlpp/lin_alg/lin_alg.cpp | 169 +++++++++++++++++++++++++++++++++ mlpp/lin_alg/lin_alg.h | 9 ++ 3 files changed, 191 insertions(+), 4 deletions(-) diff --git a/mlpp/activation/activation.cpp b/mlpp/activation/activation.cpp index 10fa0f5..6437e3d 100644 --- a/mlpp/activation/activation.cpp +++ b/mlpp/activation/activation.cpp @@ -91,19 +91,26 @@ Ref MLPPActivation::sigmoid_norm(const Ref &z) { return alg.element_wise_division(alg.onematm(z->size().x, z->size().y), alg.additionm(alg.onematm(z->size().x, z->size().y), alg.expv(alg.scalar_multiplynv(-1, z)))); } -/* real_t MLPPActivation::sigmoid_deriv(real_t z) { - return sigmoid_norm(z) * (1 - sigmoid_norm(z)); + real_t sig_norm = sigmoid_norm(z); + + return sig_norm * (1 - sig_norm); } + +/* Ref MLPPActivation::sigmoid_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.subtraction(sigmoid(z), alg.hadamard_product(sigmoid(z), sigmoid(z))); + real_t sig_norm = sigmoid_norm(z); + + return alg.subtractionv(sig_norm, alg.hadamard_productm(sig_norm, sig_norm)); } Ref MLPPActivation::sigmoid_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.subtraction(sigmoid(z), alg.hadamard_product(sigmoid(z), sigmoid(z))); + real_t sig_norm = sigmoid_norm(z); + + return alg.subtractionv(sig_norm, alg.hadamard_productm(sig_norm, sig_norm)); } //SOFTMAX @@ -1244,7 +1251,9 @@ Ref MLPPActivation::arcoth_deriv(const Ref &z) { return alg.elementWiseDivision(alg.onemat(z.size(), z[0].size()), alg.subtraction(alg.onemat(z.size(), z[0].size()), alg.hadamard_product(z, z))); } + */ + //======================== OLD ============================= real_t MLPPActivation::linear(real_t z, bool deriv) { diff --git a/mlpp/lin_alg/lin_alg.cpp b/mlpp/lin_alg/lin_alg.cpp index 2feb86a..258f1dd 100644 --- a/mlpp/lin_alg/lin_alg.cpp +++ b/mlpp/lin_alg/lin_alg.cpp @@ -138,6 +138,7 @@ Ref MLPPLinAlg::matmultm(const Ref &A, const Ref C; C.instance(); C->resize(a_size); + C->fill(0); const real_t *a_ptr = A->ptr(); const real_t *b_ptr = B->ptr(); @@ -217,6 +218,99 @@ std::vector> MLPPLinAlg::elementWiseDivision(std::vector MLPPLinAlg::hadamard_productm(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 != B->size(), Ref()); + + Ref C; + C.instance(); + C->resize(a_size); + + 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 j = 0; j < a_size.x; j++) { + int ind_i_j = A->calculate_index(i, j); + c_ptr[ind_i_j] = a_ptr[ind_i_j] * b_ptr[ind_i_j]; + } + } + + return C; +} +Ref MLPPLinAlg::kronecker_productm(const Ref &A, const Ref &B) { + // [1,1,1,1] [1,2,3,4,5] + // [1,1,1,1] [1,2,3,4,5] + // [1,2,3,4,5] + + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + // [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] + + // Resulting matrix: A.size() * B.size() + // A[0].size() * B[0].size() + + ERR_FAIL_COND_V(!A.is_valid() || !B.is_valid(), Ref()); + Size2i a_size = A->size(); + Size2i b_size = B->size(); + + Ref C; + C.instance(); + C->resize(Size2i(b_size.x * a_size.x, b_size.y * a_size.y)); + + const real_t *a_ptr = A->ptr(); + const real_t *b_ptr = B->ptr(); + real_t *c_ptr = C->ptrw(); + + Ref row_tmp; + row_tmp.instance(); + row_tmp->resize(b_size.x); + + for (int i = 0; i < a_size.y; ++i) { + for (int j = 0; j < b_size.y; ++j) { + B->get_row_into_mlpp_vector(j, row_tmp); + + Vector> row; + for (int k = 0; k < a_size.x; ++k) { + row.push_back(scalar_multiplynv(a_ptr[A->calculate_index(i, k)], row_tmp)); + } + + Ref flattened_row = flattenv(row); + + C->set_row_mlpp_vector(i * b_size.y + j, flattened_row); + } + } + + return C; +} +Ref MLPPLinAlg::elementWise_divisionm(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 != B->size(), Ref()); + + Ref C; + C.instance(); + C->resize(a_size); + + 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 j = 0; j < a_size.x; j++) { + int ind_i_j = A->calculate_index(i, j); + c_ptr[ind_i_j] = a_ptr[ind_i_j] / b_ptr[ind_i_j]; + } + } + + return C; +} + std::vector> MLPPLinAlg::transpose(std::vector> A) { std::vector> AT; AT.resize(A[0].size()); @@ -250,6 +344,52 @@ std::vector> MLPPLinAlg::scalarAdd(real_t scalar, std::vecto return A; } +Ref MLPPLinAlg::transposem(const Ref &A) { + Size2i a_size = A->size(); + + Ref AT; + AT.instance(); + AT->resize(Size2i(a_size.y, a_size.x)); + + const real_t *a_ptr = A->ptr(); + real_t *at_ptr = AT->ptrw(); + + for (int i = 0; i < a_size.x; ++i) { + for (int j = 0; j < a_size.y; ++j) { + at_ptr[AT->calculate_index(i, j)] = a_ptr[AT->calculate_index(j, i)]; + } + } + + return AT; +} +Ref MLPPLinAlg::scalar_multiplym(real_t scalar, const Ref &A) { + Ref AN = A->duplicate(); + Size2i a_size = AN->size(); + real_t *an_ptr = AN->ptrw(); + + for (int i = 0; i < a_size.y; ++i) { + for (int j = 0; j < a_size.x; ++j) { + an_ptr[AN->calculate_index(i, j)] *= scalar; + } + } + + return AN; +} + +Ref MLPPLinAlg::scalar_addm(real_t scalar, const Ref &A) { + Ref AN = A->duplicate(); + Size2i a_size = AN->size(); + real_t *an_ptr = AN->ptrw(); + + for (int i = 0; i < a_size.y; ++i) { + for (int j = 0; j < a_size.x; ++j) { + an_ptr[AN->calculate_index(i, j)] += scalar; + } + } + + return AN; +} + std::vector> MLPPLinAlg::log(std::vector> A) { std::vector> B; B.resize(A.size()); @@ -1009,6 +1149,35 @@ std::vector MLPPLinAlg::flatten(std::vector> A) { return a; } +Ref MLPPLinAlg::flattenv(const Vector> &A) { + Ref a; + a.instance(); + + int vsize = 0; + for (int i = 0; i < A.size(); ++i) { + vsize += A[i]->size(); + } + + a->resize(vsize); + + int a_index = 0; + real_t *a_ptr = a->ptrw(); + + for (int i = 0; i < A.size(); ++i) { + const Ref &r = A[i]; + + int r_size = r->size(); + const real_t *r_ptr = r->ptr(); + + for (int j = 0; j < r_size; ++j) { + a_ptr[a_index] = r_ptr[j]; + ++a_index; + } + } + + return a; +} + std::vector MLPPLinAlg::solve(std::vector> A, std::vector b) { return mat_vec_mult(inverse(A), b); } diff --git a/mlpp/lin_alg/lin_alg.h b/mlpp/lin_alg/lin_alg.h index a8696d9..9f57367 100644 --- a/mlpp/lin_alg/lin_alg.h +++ b/mlpp/lin_alg/lin_alg.h @@ -38,10 +38,18 @@ public: std::vector> kronecker_product(std::vector> A, std::vector> B); std::vector> elementWiseDivision(std::vector> A, std::vector> B); + Ref hadamard_productm(const Ref &A, const Ref &B); + Ref kronecker_productm(const Ref &A, const Ref &B); + Ref elementWise_divisionm(const Ref &A, const Ref &B); + std::vector> transpose(std::vector> A); std::vector> scalarMultiply(real_t scalar, std::vector> A); std::vector> scalarAdd(real_t scalar, std::vector> A); + Ref transposem(const Ref &A); + Ref scalar_multiplym(real_t scalar, const Ref &A); + Ref scalar_addm(real_t scalar, const Ref &A); + std::vector> log(std::vector> A); std::vector> log10(std::vector> A); std::vector> exp(std::vector> A); @@ -137,6 +145,7 @@ public: real_t sum_elements(std::vector> A); std::vector flatten(std::vector> A); + Ref flattenv(const Vector> &A); std::vector solve(std::vector> A, std::vector b);