diff --git a/mlpp/activation/activation.cpp b/mlpp/activation/activation.cpp index 8d4e490..10fa0f5 100644 --- a/mlpp/activation/activation.cpp +++ b/mlpp/activation/activation.cpp @@ -35,33 +35,21 @@ Ref MLPPActivation::run_activation_deriv_matrix(const ActivationFunc return Ref(); } -Ref MLPPActivation::activation(const Ref &z, real_t (*function)(real_t), const bool deriv) { - return Ref(); -} -Ref MLPPActivation::activation_norm(const Ref &z, real_t (*function)(real_t)) { - return Ref(); -} -Ref MLPPActivation::activation_deriv(const Ref &z, real_t (*function)(real_t)) { - return Ref(); -} +Ref MLPPActivation::activation(const Ref &z, real_t (*function)(real_t)) { + Ref a; + a.instance(); -/* + int size = z->size(); -// TO DO: Implement this template activation -std::vector MLPPActivation::activation(std::vector z, bool deriv, real_t (*function)(real_t, bool)) { - if (deriv) { - std::vector deriv; - deriv.resize(z.size()); - for (int i = 0; i < z.size(); i++) { - deriv[i] = function(z[i], true); - } - return deriv; - } - std::vector a; - a.resize(z.size()); - for (int i = 0; i < z.size(); i++) { - a[i] = function(z[i], deriv); + a->resize(size); + + const real_t *z_ptr = z->ptr(); + real_t *a_ptr = a->ptrw(); + + for (int i = 0; i < size; ++i) { + a_ptr[i] = function(z_ptr[i]); } + return a; } @@ -83,11 +71,11 @@ real_t MLPPActivation::linear_deriv(real_t z) { } Ref MLPPActivation::linear_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.onevec(z.size()); + return alg.onevecv(z->size()); } Ref MLPPActivation::linear_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.onemat(z.size(), z[0].size()); + return alg.onematm(z->size().x, z->size().y); } //SIGMOID @@ -96,15 +84,14 @@ real_t MLPPActivation::sigmoid_norm(real_t z) { } Ref MLPPActivation::sigmoid_norm(const Ref &z) { MLPPLinAlg alg; - - return alg.elementWiseDivision(alg.onevec(z.size()), alg.addition(alg.onevec(z.size()), alg.exp(alg.scalarMultiply(-1, z)))); + return alg.element_wise_division(alg.onevecv(z->size()), alg.additionm(alg.onevecv(z->size()), alg.expv(alg.scalar_multiplynv(-1, z)))); } Ref MLPPActivation::sigmoid_norm(const Ref &z) { MLPPLinAlg alg; - - return alg.elementWiseDivision(alg.onemat(z.size(), z[0].size()), alg.addition(alg.onemat(z.size(), z[0].size()), alg.exp(alg.scalarMultiply(-1, 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)); } @@ -1257,9 +1244,7 @@ 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/activation/activation.h b/mlpp/activation/activation.h index d648194..405e0fd 100644 --- a/mlpp/activation/activation.h +++ b/mlpp/activation/activation.h @@ -66,9 +66,7 @@ public: Ref run_activation_deriv_vector(const ActivationFunction func, const Ref &z); Ref run_activation_deriv_matrix(const ActivationFunction func, const Ref &z); - Ref activation(const Ref &z, real_t (*function)(real_t), const bool deriv = false); - Ref activation_norm(const Ref &z, real_t (*function)(real_t)); - Ref activation_deriv(const Ref &z, real_t (*function)(real_t)); + Ref activation(const Ref &z, real_t (*function)(real_t)); //ACTIVATION FUNCTIONS diff --git a/mlpp/lin_alg/lin_alg.cpp b/mlpp/lin_alg/lin_alg.cpp index d4132fa..2feb86a 100644 --- a/mlpp/lin_alg/lin_alg.cpp +++ b/mlpp/lin_alg/lin_alg.cpp @@ -88,6 +88,77 @@ std::vector> MLPPLinAlg::matmult(std::vector MLPPLinAlg::additionm(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(); + + int data_size = A->data_size(); + + for (int i = 0; i < data_size; ++i) { + c_ptr[i] = a_ptr[i] + b_ptr[i]; + } + + return C; +} +Ref MLPPLinAlg::subtractionm(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(); + + int data_size = A->data_size(); + + for (int i = 0; i < data_size; ++i) { + c_ptr[i] = a_ptr[i] - b_ptr[i]; + } + + return C; +} +Ref MLPPLinAlg::matmultm(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 k = 0; k < a_size.y; k++) { + int ind_i_k = A->calculate_index(i, k); + + for (int j = 0; j < a_size.x; j++) { + int ind_i_j = A->calculate_index(i, j); + int ind_k_j = A->calculate_index(k, j); + + c_ptr[ind_i_j] += a_ptr[ind_i_k] * b_ptr[ind_k_j]; + } + } + } + + return C; +} + std::vector> MLPPLinAlg::hadamard_product(std::vector> A, std::vector> B) { std::vector> C; C.resize(A.size()); @@ -402,6 +473,34 @@ std::vector> MLPPLinAlg::onemat(int n, int m) { return full(n, m, 1); } +Ref MLPPLinAlg::zeromatm(int n, int m) { + Ref mat; + mat.instance(); + + mat->resize(Size2i(n, m)); + mat->fill(0); + + return mat; +} +Ref MLPPLinAlg::onematm(int n, int m) { + Ref mat; + mat.instance(); + + mat->resize(Size2i(n, m)); + mat->fill(1); + + return mat; +} +Ref MLPPLinAlg::fullm(int n, int m, int k) { + Ref mat; + mat.instance(); + + mat->resize(Size2i(n, m)); + mat->fill(k); + + return mat; +} + std::vector> MLPPLinAlg::full(int n, int m, int k) { std::vector> full; full.resize(n); @@ -995,6 +1094,29 @@ std::vector MLPPLinAlg::elementWiseDivision(std::vector a, std:: return c; } +Ref MLPPLinAlg::element_wise_division(const Ref &a, const Ref &b) { + ERR_FAIL_COND_V(!a.is_valid() || !b.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + + ERR_FAIL_COND_V(size != b->size(), Ref()); + + out->resize(size); + + const real_t *a_ptr = a->ptr(); + const real_t *b_ptr = b->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = a_ptr[i] / b_ptr[i]; + } + + return out; +} + std::vector MLPPLinAlg::scalarMultiply(real_t scalar, std::vector a) { for (int i = 0; i < a.size(); i++) { a[i] *= scalar; @@ -1210,6 +1332,118 @@ std::vector MLPPLinAlg::cbrt(std::vector a) { return exponentiate(a, real_t(1) / real_t(3)); } +Ref logv(const Ref &a) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = Math::log(a_ptr[i]); + } + + return out; +} +Ref log10v(const Ref &a) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = std::log10(a_ptr[i]); + } + + return out; +} +Ref expv(const Ref &a) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = Math::exp(a_ptr[i]); + } + + return out; +} +Ref erfv(const Ref &a) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = std::erf(a_ptr[i]); + } + + return out; +} +Ref exponentiatev(const Ref &a, real_t p) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = Math::pow(a_ptr[i], p); + } + + return out; +} +Ref sqrtv(const Ref &a) { + ERR_FAIL_COND_V(!a.is_valid(), Ref()); + + Ref out; + out.instance(); + + int size = a->size(); + out->resize(size); + + const real_t *a_ptr = a->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < size; ++i) { + out_ptr[i] = Math::sqrt(a_ptr[i]); + } + + return out; +} +Ref cbrtv(const Ref &a) { + return exponentiatev(a, static_cast(1) / static_cast(3)); +} + real_t MLPPLinAlg::dot(std::vector a, std::vector b) { real_t c = 0; for (int i = 0; i < a.size(); i++) { @@ -1265,6 +1499,34 @@ std::vector MLPPLinAlg::full(int n, int k) { return full; } +Ref MLPPLinAlg::zerovecv(int n) { + Ref vec; + vec.instance(); + + vec->resize(n); + vec->fill(0); + + return vec; +} +Ref MLPPLinAlg::onevecv(int n) { + Ref vec; + vec.instance(); + + vec->resize(n); + vec->fill(1); + + return vec; +} +Ref MLPPLinAlg::fullv(int n, int k) { + Ref vec; + vec.instance(); + + vec->resize(n); + vec->fill(k); + + return vec; +} + std::vector MLPPLinAlg::sin(std::vector a) { std::vector b; b.resize(a.size()); diff --git a/mlpp/lin_alg/lin_alg.h b/mlpp/lin_alg/lin_alg.h index f73e105..a8696d9 100644 --- a/mlpp/lin_alg/lin_alg.h +++ b/mlpp/lin_alg/lin_alg.h @@ -27,35 +27,27 @@ public: std::vector> gaussianNoise(int n, int m); std::vector> addition(std::vector> A, std::vector> B); - std::vector> subtraction(std::vector> A, std::vector> B); - std::vector> matmult(std::vector> A, std::vector> B); + Ref additionm(const Ref &A, const Ref &B); + Ref subtractionm(const Ref &A, const Ref &B); + Ref matmultm(const Ref &A, const Ref &B); + std::vector> hadamard_product(std::vector> A, std::vector> B); - std::vector> kronecker_product(std::vector> A, std::vector> B); - std::vector> elementWiseDivision(std::vector> A, std::vector> 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); std::vector> log(std::vector> A); - std::vector> log10(std::vector> A); - std::vector> exp(std::vector> A); - std::vector> erf(std::vector> A); - std::vector> exponentiate(std::vector> A, real_t p); - std::vector> sqrt(std::vector> A); - std::vector> cbrt(std::vector> A); std::vector> matrixPower(std::vector> A, int n); @@ -75,13 +67,14 @@ public: std::vector> pinverse(std::vector> A); std::vector> zeromat(int n, int m); - std::vector> onemat(int n, int m); - std::vector> full(int n, int m, int k); - std::vector> sin(std::vector> A); + Ref zeromatm(int n, int m); + Ref onematm(int n, int m); + Ref fullm(int n, int m, int k); + std::vector> sin(std::vector> A); std::vector> cos(std::vector> A); std::vector> rotate(std::vector> A, real_t theta, int axis = -1); @@ -162,6 +155,7 @@ public: std::vector hadamard_product(std::vector a, std::vector b); std::vector elementWiseDivision(std::vector a, std::vector b); + Ref element_wise_division(const Ref &a, const Ref &b); std::vector scalarMultiply(real_t scalar, std::vector a); Ref scalar_multiplynv(real_t scalar, const Ref &a); @@ -181,19 +175,21 @@ public: std::vector subtractMatrixRows(std::vector a, std::vector> B); std::vector log(std::vector a); - std::vector log10(std::vector a); - std::vector exp(std::vector a); - std::vector erf(std::vector a); - std::vector exponentiate(std::vector a, real_t p); - std::vector sqrt(std::vector a); - std::vector cbrt(std::vector a); + Ref logv(const Ref &a); + Ref log10v(const Ref &a); + Ref expv(const Ref &a); + Ref erfv(const Ref &a); + Ref exponentiatev(const Ref &a, real_t p); + Ref sqrtv(const Ref &a); + Ref cbrtv(const Ref &a); + real_t dot(std::vector a, std::vector b); std::vector cross(std::vector a, std::vector b); @@ -201,13 +197,15 @@ public: std::vector abs(std::vector a); std::vector zerovec(int n); - std::vector onevec(int n); + std::vector full(int n, int k); + + Ref zerovecv(int n); + Ref onevecv(int n); + Ref fullv(int n, int k); std::vector> diag(std::vector a); - std::vector full(int n, int k); - std::vector sin(std::vector a); std::vector cos(std::vector a);