diff --git a/mlpp/activation/activation.cpp b/mlpp/activation/activation.cpp index 6437e3d..c255f0c 100644 --- a/mlpp/activation/activation.cpp +++ b/mlpp/activation/activation.cpp @@ -97,47 +97,66 @@ real_t MLPPActivation::sigmoid_deriv(real_t z) { return sig_norm * (1 - sig_norm); } -/* Ref MLPPActivation::sigmoid_deriv(const Ref &z) { MLPPLinAlg alg; - real_t sig_norm = sigmoid_norm(z); + Ref sig_norm = sigmoid_norm(z); - return alg.subtractionv(sig_norm, alg.hadamard_productm(sig_norm, sig_norm)); + return alg.subtractionnv(sig_norm, alg.hadamard_productnv(sig_norm, sig_norm)); } Ref MLPPActivation::sigmoid_deriv(const Ref &z) { MLPPLinAlg alg; - real_t sig_norm = sigmoid_norm(z); + Ref sig_norm = sigmoid_norm(z); - return alg.subtractionv(sig_norm, alg.hadamard_productm(sig_norm, sig_norm)); + return alg.subtractionnv(sig_norm, alg.hadamard_productnv(sig_norm, sig_norm)); } //SOFTMAX Ref MLPPActivation::softmax_norm(const Ref &z) { MLPPLinAlg alg; - std::vector a; - a.resize(z.size()); - std::vector expZ = alg.exp(z); + + int z_size = z->size(); + + Ref a; + a.instance(); + a->resize(z_size); + + Ref exp_z = alg.expv(z); real_t sum = 0; - for (int i = 0; i < z.size(); i++) { - sum += expZ[i]; + const real_t *exp_z_ptr = exp_z->ptr(); + real_t *a_ptr = a->ptrw(); + + for (int i = 0; i < z_size; ++i) { + sum += exp_z_ptr[i]; } - for (int i = 0; i < z.size(); i++) { - a[i] = expZ[i] / sum; + for (int i = 0; i < z_size; ++i) { + a_ptr[i] = exp_z_ptr[i] / sum; } return a; } Ref MLPPActivation::softmax_norm(const Ref &z) { MLPPLinAlg alg; - std::vector> a; - a.resize(z.size()); - for (int i = 0; i < z.size(); i++) { - a[i] = softmax(z[i]); + Size2i z_size = z->size(); + + Ref a; + a.instance(); + a->resize(z_size); + + Ref row_tmp; + row_tmp.instance(); + row_tmp->resize(z_size.x); + + for (int i = 0; i < z_size.y; ++i) { + z->get_row_into_mlpp_vector(i, row_tmp); + + Ref sfn = softmax_norm(z); + + a->set_row_mlpp_vector(i, sfn); } return a; @@ -145,28 +164,48 @@ Ref MLPPActivation::softmax_norm(const Ref &z) { Ref MLPPActivation::softmax_deriv(const Ref &z) { MLPPLinAlg alg; - std::vector a; - a.resize(z.size()); - std::vector expZ = alg.exp(z); + + int z_size = z->size(); + + Ref a; + a.instance(); + a->resize(z_size); + + Ref exp_z = alg.expv(z); real_t sum = 0; - for (int i = 0; i < z.size(); i++) { - sum += expZ[i]; + const real_t *exp_z_ptr = exp_z->ptr(); + real_t *a_ptr = a->ptrw(); + + for (int i = 0; i < z_size; ++i) { + sum += exp_z_ptr[i]; } - for (int i = 0; i < z.size(); i++) { - a[i] = expZ[i] / sum; + for (int i = 0; i < z_size; ++i) { + a_ptr[i] = exp_z_ptr[i] / sum; } return a; } Ref MLPPActivation::softmax_deriv(const Ref &z) { MLPPLinAlg alg; - std::vector> a; - a.resize(z.size()); - for (int i = 0; i < z.size(); i++) { - a[i] = softmax(z[i]); + Size2i z_size = z->size(); + + Ref a; + a.instance(); + a->resize(z_size); + + Ref row_tmp; + row_tmp.instance(); + row_tmp->resize(z_size.x); + + for (int i = 0; i < z_size.y; ++i) { + z->get_row_into_mlpp_vector(i, row_tmp); + + Ref sfn = softmax_deriv(z); + + a->set_row_mlpp_vector(i, sfn); } return a; @@ -177,45 +216,87 @@ Ref MLPPActivation::softmax_deriv(const Ref &z) { Ref MLPPActivation::adj_softmax_norm(const Ref &z) { MLPPLinAlg alg; - std::vector a; - real_t C = -*std::max_element(z.begin(), z.end()); - z = alg.scalarAdd(C, z); + int size = z->size(); + const real_t *z_ptr = z->ptr(); + real_t c = -Math_INF; - return softmax(z); + for (int i = 0; i < size; ++i) { + int zpi = z_ptr[i]; + + if (c < zpi) { + c = zpi; + } + } + + c = -c; + + Ref n = alg.scalar_addnv(c, z); + + return softmax_norm(n); } Ref MLPPActivation::adj_softmax_norm(const Ref &z) { MLPPLinAlg alg; - std::vector> a; - a.resize(z.size()); + Ref n = z->duplicate(); - for (int i = 0; i < z.size(); i++) { - a[i] = adjSoftmax(z[i]); + Size2i size = z->size(); + + Ref row_rmp; + row_rmp.instance(); + row_rmp->resize(size.x); + + for (int i = 0; i < size.y; ++i) { + z->get_row_into_mlpp_vector(i, row_rmp); + + Ref nv = adj_softmax_norm(row_rmp); + + n->set_row_mlpp_vector(i, nv); } - return a; + return n; } -Ref MLPPActivation::adj_softmax(const Ref &z) { +Ref MLPPActivation::adj_softmax_deriv(const Ref &z) { MLPPLinAlg alg; - std::vector a; - real_t C = -*std::max_element(z.begin(), z.end()); - z = alg.scalarAdd(C, z); + int size = z->size(); + const real_t *z_ptr = z->ptr(); + real_t c = -Math_INF; - return softmax(z); -} -Ref MLPPActivation::adj_softmax(const Ref &z) { - MLPPLinAlg alg; + for (int i = 0; i < size; ++i) { + int zpi = z_ptr[i]; - std::vector> a; - a.resize(z.size()); - - for (int i = 0; i < z.size(); i++) { - a[i] = adjSoftmax(z[i]); + if (c < zpi) { + c = zpi; + } } - return a; + c = -c; + + Ref n = alg.scalar_addnv(c, z); + + return adj_softmax_deriv(n); +} +Ref MLPPActivation::adj_softmax_deriv(const Ref &z) { + MLPPLinAlg alg; + + Ref n = z->duplicate(); + + Size2i size = z->size(); + + Ref row_rmp; + row_rmp.instance(); + row_rmp->resize(size.x); + + for (int i = 0; i < size.y; ++i) { + z->get_row_into_mlpp_vector(i, row_rmp); + + Ref nv = adj_softmax_deriv(row_rmp); + + n->set_row_mlpp_vector(i, nv); + } + + return n; } //SOFTMAX DERIV @@ -223,45 +304,68 @@ Ref MLPPActivation::adj_softmax(const Ref &z) { Ref MLPPActivation::softmax_deriv_norm(const Ref &z) { MLPPLinAlg alg; - std::vector> deriv; - std::vector a = softmax(z); - deriv.resize(a.size()); + Ref a = softmax_norm(z); - for (int i = 0; i < deriv.size(); i++) { - deriv[i].resize(a.size()); - } + int z_size = z->size(); + int a_size = a->size(); - for (int i = 0; i < a.size(); i++) { - for (int j = 0; j < z.size(); j++) { + Ref deriv; + deriv.instance(); + deriv->resize(Size2i(a_size, a_size)); + + const real_t *a_ptr = a->ptr(); + + for (int i = 0; i < z_size; ++i) { + for (int j = 0; j < z_size; ++j) { if (i == j) { - deriv[i][j] = a[i] * (1 - a[i]); + deriv->set_element(i, j, a_ptr[i] * (1 - a_ptr[i])); } else { - deriv[i][j] = -a[i] * a[j]; + deriv->set_element(i, j, -a_ptr[i] * a_ptr[j]); } } } return deriv; } -std::vector> MLPPActivation::softmax_deriv_norm(const Ref &z) { +Vector> MLPPActivation::softmax_deriv_norm(const Ref &z) { MLPPLinAlg alg; - std::vector>> deriv; - std::vector> a = softmax(z); + int z_size_y = z->size().y; - deriv.resize(a.size()); - for (int i = 0; i < deriv.size(); i++) { - deriv[i].resize(a.size()); - } + Ref a = softmax_norm(z); + int a_size_y = a->size().y; + int a_size_x = a->size().x; + + Vector> deriv; + deriv.resize(a_size_y); + + Ref a_i_tmp; + a_i_tmp.instance(); + a_i_tmp->resize(a_size_x); + + Ref a_j_tmp; + a_j_tmp.instance(); + a_j_tmp->resize(a_size_x); + + for (int i = 0; i < deriv.size(); ++i) { + Ref d; + d.instance(); + d->resize(Size2i(a_size_x, z_size_y)); + + for (int j = 0; j < z_size_y; ++j) { + a->get_row_into_mlpp_vector(i, a_i_tmp); - for (int i = 0; i < a.size(); i++) { - for (int j = 0; j < z.size(); j++) { if (i == j) { - deriv[i][j] = alg.subtraction(a[i], alg.hadamard_product(a[i], a[i])); + Ref d_j = alg.subtractionnv(a_i_tmp, alg.hadamard_productnv(a_i_tmp, a_i_tmp)); + d->set_row_mlpp_vector(j, d_j); } else { - deriv[i][j] = alg.scalarMultiply(-1, alg.hadamard_product(a[i], a[j])); + a->get_row_into_mlpp_vector(j, a_j_tmp); + Ref d_j = alg.scalar_multiplynv(-1, alg.hadamard_productnv(a_i_tmp, a_j_tmp)); + d->set_row_mlpp_vector(j, d_j); } } + + deriv.write[i] = d; } return deriv; @@ -270,45 +374,68 @@ std::vector> MLPPActivation::softmax_deriv_norm(const Ref MLPPActivation::softmax_deriv_deriv(const Ref &z) { MLPPLinAlg alg; - std::vector> deriv; - std::vector a = softmax(z); - deriv.resize(a.size()); + Ref a = softmax_norm(z); - for (int i = 0; i < deriv.size(); i++) { - deriv[i].resize(a.size()); - } + int z_size = z->size(); + int a_size = a->size(); - for (int i = 0; i < a.size(); i++) { - for (int j = 0; j < z.size(); j++) { + Ref deriv; + deriv.instance(); + deriv->resize(Size2i(a_size, a_size)); + + const real_t *a_ptr = a->ptr(); + + for (int i = 0; i < z_size; ++i) { + for (int j = 0; j < z_size; ++j) { if (i == j) { - deriv[i][j] = a[i] * (1 - a[i]); + deriv->set_element(i, j, a_ptr[i] * (1 - a_ptr[i])); } else { - deriv[i][j] = -a[i] * a[j]; + deriv->set_element(i, j, -a_ptr[i] * a_ptr[j]); } } } return deriv; } -std::vector> MLPPActivation::softmax_deriv_deriv(const Ref &z) { +Vector> MLPPActivation::softmax_deriv_deriv(const Ref &z) { MLPPLinAlg alg; - std::vector>> deriv; - std::vector> a = softmax(z); + int z_size_y = z->size().y; - deriv.resize(a.size()); - for (int i = 0; i < deriv.size(); i++) { - deriv[i].resize(a.size()); - } + Ref a = softmax_norm(z); + int a_size_y = a->size().y; + int a_size_x = a->size().x; + + Vector> deriv; + deriv.resize(a_size_y); + + Ref a_i_tmp; + a_i_tmp.instance(); + a_i_tmp->resize(a_size_x); + + Ref a_j_tmp; + a_j_tmp.instance(); + a_j_tmp->resize(a_size_x); + + for (int i = 0; i < deriv.size(); ++i) { + Ref d; + d.instance(); + d->resize(Size2i(a_size_x, z_size_y)); + + for (int j = 0; j < z_size_y; ++j) { + a->get_row_into_mlpp_vector(i, a_i_tmp); - for (int i = 0; i < a.size(); i++) { - for (int j = 0; j < z.size(); j++) { if (i == j) { - deriv[i][j] = alg.subtraction(a[i], alg.hadamard_product(a[i], a[i])); + Ref d_j = alg.subtractionnv(a_i_tmp, alg.hadamard_productnv(a_i_tmp, a_i_tmp)); + d->set_row_mlpp_vector(j, d_j); } else { - deriv[i][j] = alg.scalarMultiply(-1, alg.hadamard_product(a[i], a[j])); + a->get_row_into_mlpp_vector(j, a_j_tmp); + Ref d_j = alg.scalar_multiplynv(-1, alg.hadamard_productnv(a_i_tmp, a_j_tmp)); + d->set_row_mlpp_vector(j, d_j); } } + + deriv.write[i] = d; } return deriv; @@ -321,21 +448,23 @@ real_t MLPPActivation::softplus_norm(real_t z) { } Ref MLPPActivation::softplus_norm(const Ref &z) { MLPPLinAlg alg; - return alg.log(alg.addition(alg.onevec(z.size()), alg.exp(z))); + + return alg.logv(alg.additionnv(alg.onevecv(z->size()), alg.expv(z))); } Ref MLPPActivation::softplus_norm(const Ref &z) { MLPPLinAlg alg; - return alg.log(alg.addition(alg.onemat(z.size(), z[0].size()), alg.exp(z))); + + return alg.logv(alg.additionnv(alg.onematm(z->size().x, z->size().y), alg.expv(z))); } real_t MLPPActivation::softplus_deriv(real_t z) { - return sigmoid(z); + return sigmoid_norm(z); } Ref MLPPActivation::softplus_deriv(const Ref &z) { - return sigmoid(z); + return sigmoid_norm(z); } Ref MLPPActivation::softplus_deriv(const Ref &z) { - return sigmoid(z); + return sigmoid_norm(z); } //SOFTSIGN @@ -346,12 +475,12 @@ real_t MLPPActivation::softsign_norm(real_t z) { Ref MLPPActivation::softsign_norm(const Ref &z) { MLPPLinAlg alg; - return alg.elementWiseDivision(z, alg.addition(alg.onevec(z.size()), alg.abs(z))); + return alg.element_wise_division(z, alg.additionnv(alg.onevecv(z->size()), alg.absv(z))); } Ref MLPPActivation::softsign_norm(const Ref &z) { MLPPLinAlg alg; - return alg.elementWiseDivision(z, alg.addition(alg.onemat(z.size(), z[0].size()), alg.abs(z))); + return alg.element_wise_divisionm(z, alg.additionnv(alg.onematm(z->size().x, z->size().y), alg.absm(z))); } real_t MLPPActivation::softsign_deriv(real_t z) { @@ -360,12 +489,12 @@ real_t MLPPActivation::softsign_deriv(real_t z) { Ref MLPPActivation::softsign_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.elementWiseDivision(alg.onevec(z.size()), alg.exponentiate(alg.addition(alg.onevec(z.size()), alg.abs(z)), 2)); + return alg.element_wise_division(alg.onevecv(z->size()), alg.exponentiatev(alg.additionnv(alg.onevecv(z->size()), alg.absv(z)), 2)); } Ref MLPPActivation::softsign_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.elementWiseDivision(alg.onemat(z.size(), z[0].size()), alg.exponentiate(alg.addition(alg.onemat(z.size(), z[0].size()), alg.abs(z)), 2)); + return alg.element_wise_divisionm(alg.onematm(z->size().x, z->size().y), alg.exponentiatev(alg.additionm(alg.onematm(z->size().x, z->size().y), alg.absm(z)), 2)); } //GAUSSIANCDF @@ -376,13 +505,13 @@ real_t MLPPActivation::gaussian_cdf_norm(real_t z) { Ref MLPPActivation::gaussian_cdf_norm(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(0.5, alg.addition(alg.onevec(z.size()), alg.erf(alg.scalarMultiply(1 / sqrt(2), z)))); + return alg.scalar_multiplynv(0.5, alg.additionnv(alg.onevecv(z->size()), alg.erfv(alg.scalar_multiplynv(1 / sqrt(2), z)))); } Ref MLPPActivation::gaussian_cdf_norm(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(0.5, alg.addition(alg.onemat(z.size(), z[0].size()), alg.erf(alg.scalarMultiply(1 / sqrt(2), z)))); + return alg.scalar_multiplym(0.5, alg.additionm(alg.onematm(z->size().x, z->size().y), alg.erfm(alg.scalar_multiplym(1 / sqrt(2), z)))); } real_t MLPPActivation::gaussian_cdf_deriv(real_t z) { @@ -391,13 +520,13 @@ real_t MLPPActivation::gaussian_cdf_deriv(real_t z) { Ref MLPPActivation::gaussian_cdf_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(1 / sqrt(2 * M_PI), alg.exp(alg.scalarMultiply(-1 / 2, alg.hadamard_product(z, z)))); + return alg.scalar_multiplynv(1 / Math::sqrt(2 * M_PI), alg.expv(alg.scalar_multiplynv(-1 / 2.0, alg.hadamard_productnv(z, z)))); } Ref MLPPActivation::gaussian_cdf_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(1 / sqrt(2 * M_PI), alg.exp(alg.scalarMultiply(-1 / 2, alg.hadamard_product(z, z)))); + return alg.scalar_multiplym(1 / Math::sqrt(2 * M_PI), alg.expm(alg.scalar_multiplym(-1 / 2.0, alg.hadamard_productm(z, z)))); } //CLOGLOG @@ -408,13 +537,13 @@ real_t MLPPActivation::cloglog_norm(real_t z) { Ref MLPPActivation::cloglog_norm(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(-1, alg.scalarAdd(-1, alg.exp(alg.scalarMultiply(-1, alg.exp(z))))); + return alg.scalar_multiplynv(-1, alg.scalar_addnv(-1, alg.expv(alg.scalar_multiplynv(-1, alg.expv(z))))); } Ref MLPPActivation::cloglog_norm(const Ref &z) { MLPPLinAlg alg; - return alg.scalarMultiply(-1, alg.scalarAdd(-1, alg.exp(alg.scalarMultiply(-1, alg.exp(z))))); + return alg.scalar_multiplym(-1, alg.scalar_addm(-1, alg.expm(alg.scalar_multiplym(-1, alg.expm(z))))); } real_t MLPPActivation::cloglog_deriv(real_t z) { @@ -423,13 +552,13 @@ real_t MLPPActivation::cloglog_deriv(real_t z) { Ref MLPPActivation::cloglog_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.exp(alg.scalarMultiply(-1, alg.exp(z))); + return alg.expv(alg.scalar_multiplynv(-1, alg.expv(z))); } Ref MLPPActivation::cloglog_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.exp(alg.scalarMultiply(-1, alg.exp(z))); + return alg.expm(alg.scalar_multiplym(-1, alg.expm(z))); } //LOGIT @@ -440,12 +569,12 @@ real_t MLPPActivation::logit_norm(real_t z) { Ref MLPPActivation::logit_norm(const Ref &z) { MLPPLinAlg alg; - return alg.log(alg.elementWiseDivision(z, alg.subtraction(alg.onevec(z.size()), z))); + return alg.logv(alg.element_wise_division(z, alg.subtractionnv(alg.onevecv(z->size()), z))); } Ref MLPPActivation::logit_norm(const Ref &z) { MLPPLinAlg alg; - return alg.log(alg.elementWiseDivision(z, alg.subtraction(alg.onemat(z.size(), z[0].size()), z))); + return alg.logm(alg.element_wise_divisionm(z, alg.subtractionm(alg.onematm(z->size().x, z->size().y), z))); } real_t MLPPActivation::logit_deriv(real_t z) { @@ -454,16 +583,23 @@ real_t MLPPActivation::logit_deriv(real_t z) { Ref MLPPActivation::logit_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.subtraction(alg.elementWiseDivision(alg.onevec(z.size()), z), alg.elementWiseDivision(alg.onevec(z.size()), alg.subtraction(z, alg.onevec(z.size())))); + return alg.subtractionnv( + alg.element_wise_division(alg.onevecv(z->size()), z), + alg.element_wise_division(alg.onevecv(z->size()), alg.subtractionnv(z, alg.onevecv(z->size())))); } Ref MLPPActivation::logit_deriv(const Ref &z) { MLPPLinAlg alg; - return alg.subtraction(alg.elementWiseDivision(alg.onemat(z.size(), z[0].size()), z), alg.elementWiseDivision(alg.onemat(z.size(), z[0].size()), alg.subtraction(z, alg.onemat(z.size(), z[0].size())))); + return alg.subtractionm( + alg.element_wise_divisionm( + alg.onematm(z->size().x, z->size().y), z), + alg.element_wise_divisionm(alg.onematm(z->size().x, z->size().y), + alg.subtractionm(z, alg.onematm(z->size().x, z->size().y)))); } //UNITSTEP +/* real_t MLPPActivation::unit_step_norm(real_t z) { return z < 0 ? 0 : 1; } @@ -472,7 +608,7 @@ Ref MLPPActivation::unit_step_norm(const Ref &z) { a.resize(z.size()); for (int i = 0; i < a.size(); i++) { - a[i] = unitStep(z[i]); + a[i] = unit_step_norm(z[i]); } return a; } @@ -481,7 +617,7 @@ Ref MLPPActivation::unit_step_norm(const Ref &z) { a.resize(z.size()); for (int i = 0; i < a.size(); i++) { - a[i] = unitStep(z[i]); + a[i] = unit_step_norm(z[i]); } return a; } @@ -1251,9 +1387,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 405e0fd..306f3bf 100644 --- a/mlpp/activation/activation.h +++ b/mlpp/activation/activation.h @@ -11,6 +11,7 @@ #include "core/math/math_defs.h" #include "core/object/reference.h" +#include "core/object/func_ref.h" #include "../lin_alg/mlpp_matrix.h" #include "../lin_alg/mlpp_vector.h" @@ -19,6 +20,7 @@ //TODO this should probably be a singleton //TODO Activation functions should either have a variant which does not allocate, or they should just be reworked altogether +//TODO Methods here should probably use error macros, in a way where they get disabled in non-tools(?) (maybe release?) builds class MLPPActivation : public Reference { GDCLASS(MLPPActivation, Reference); @@ -54,8 +56,10 @@ public: }; public: + //TODO add override for vec, and real_t typedef Ref (MLPPActivation::*ActivationFunctionPointer)(const Ref &); ActivationFunctionPointer get_activation_function_ptr(const ActivationFunction func, const bool deriv = false); + Ref get_activation_function_funcref(const ActivationFunction func, const bool deriv = false); Ref run_activation_vector(const ActivationFunction func, const Ref &z, const bool deriv = false); Ref run_activation_matrix(const ActivationFunction func, const Ref &z, const bool deriv = false); @@ -71,6 +75,7 @@ public: //ACTIVATION FUNCTIONS //LINEAR + real_t linear_norm(real_t z); Ref linear_norm(const Ref &z); Ref linear_norm(const Ref &z); @@ -80,6 +85,7 @@ public: Ref linear_deriv(const Ref &z); //SIGMOID + real_t sigmoid_norm(real_t z); Ref sigmoid_norm(const Ref &z); Ref sigmoid_norm(const Ref &z); @@ -89,6 +95,7 @@ public: Ref sigmoid_deriv(const Ref &z); //SOFTMAX + Ref softmax_norm(const Ref &z); Ref softmax_norm(const Ref &z); @@ -100,16 +107,16 @@ public: Ref adj_softmax_norm(const Ref &z); Ref adj_softmax_norm(const Ref &z); - Ref adj_softmax(const Ref &z); - Ref adj_softmax(const Ref &z); + Ref adj_softmax_deriv(const Ref &z); + Ref adj_softmax_deriv(const Ref &z); //SOFTMAX DERIV Ref softmax_deriv_norm(const Ref &z); - std::vector> softmax_deriv_norm(const Ref &z); + Vector> softmax_deriv_norm(const Ref &z); Ref softmax_deriv_deriv(const Ref &z); - std::vector> softmax_deriv_deriv(const Ref &z); + Vector> softmax_deriv_deriv(const Ref &z); //SOFTPLUS diff --git a/mlpp/lin_alg/lin_alg.cpp b/mlpp/lin_alg/lin_alg.cpp index 258f1dd..fa03d26 100644 --- a/mlpp/lin_alg/lin_alg.cpp +++ b/mlpp/lin_alg/lin_alg.cpp @@ -288,7 +288,7 @@ Ref MLPPLinAlg::kronecker_productm(const Ref &A, const R return C; } -Ref MLPPLinAlg::elementWise_divisionm(const Ref &A, const Ref &B) { +Ref MLPPLinAlg::element_wise_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()); @@ -463,6 +463,118 @@ std::vector> MLPPLinAlg::cbrt(std::vector logm(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = Math::log(a_ptr[i]); + } + + return out; +} +Ref log10m(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = std::log10(a_ptr[i]); + } + + return out; +} +Ref expm(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = Math::exp(a_ptr[i]); + } + + return out; +} +Ref erfm(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = std::erf(a_ptr[i]); + } + + return out; +} +Ref exponentiatem(const Ref &A, real_t p) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = Math::pow(a_ptr[i], p); + } + + return out; +} +Ref sqrtm(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = Math::sqrt(a_ptr[i]); + } + + return out; +} +Ref cbrtm(const Ref &A) { + return exponentiatem(A, real_t(1) / real_t(3)); +} + std::vector> MLPPLinAlg::matrixPower(std::vector> A, int n) { std::vector> B = identity(A.size()); if (n == 0) { @@ -490,6 +602,25 @@ std::vector> MLPPLinAlg::abs(std::vector return B; } +Ref absm(const Ref &A) { + ERR_FAIL_COND_V(!A.is_valid(), Ref()); + + Ref out; + out.instance(); + + int data_size = A->data_size(); + out->resize(A->size()); + + const real_t *a_ptr = A->ptr(); + real_t *out_ptr = out->ptrw(); + + for (int i = 0; i < data_size; ++i) { + out_ptr[i] = ABS(a_ptr[i]); + } + + return out; +} + real_t MLPPLinAlg::det(std::vector> A, int d) { real_t deter = 0; std::vector> B; @@ -1253,6 +1384,48 @@ std::vector MLPPLinAlg::hadamard_product(std::vector a, std::vec return c; } +Ref MLPPLinAlg::hadamard_productnv(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; +} +void MLPPLinAlg::hadamard_productv(const Ref &a, const Ref &b, Ref out) { + ERR_FAIL_COND(!a.is_valid() || !b.is_valid() || !out.is_valid()); + + int size = a->size(); + + ERR_FAIL_COND(size != b->size()); + + if (unlikely(out->size() != size)) { + 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]; + } +} + std::vector MLPPLinAlg::elementWiseDivision(std::vector a, std::vector b) { std::vector c; c.resize(a.size()); @@ -1336,6 +1509,42 @@ std::vector MLPPLinAlg::scalarAdd(real_t scalar, std::vector a) return a; } +Ref MLPPLinAlg::scalar_addnv(real_t scalar, 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] = a_ptr[i] + scalar; + } + + return out; +} +void MLPPLinAlg::scalar_addv(real_t scalar, const Ref &a, Ref out) { + ERR_FAIL_COND(!a.is_valid() || !out.is_valid()); + + int size = a->size(); + + if (unlikely(out->size() != 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] = a_ptr[i] + scalar; + } +} + std::vector MLPPLinAlg::addition(std::vector a, std::vector b) { std::vector c; c.resize(a.size()); @@ -1668,6 +1877,25 @@ std::vector MLPPLinAlg::full(int n, int k) { return full; } +Ref absv(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] = ABS(a_ptr[i]); + } + + return out; +} + Ref MLPPLinAlg::zerovecv(int n) { Ref vec; vec.instance(); diff --git a/mlpp/lin_alg/lin_alg.h b/mlpp/lin_alg/lin_alg.h index 9f57367..6e235d7 100644 --- a/mlpp/lin_alg/lin_alg.h +++ b/mlpp/lin_alg/lin_alg.h @@ -8,6 +8,8 @@ // Created by Marc Melikyan on 1/8/21. // +//TODO Methods here should probably use error macros in a way where they get disabled in non-tools(?) (maybe release?) builds + #include "core/math/math_defs.h" #include "../lin_alg/mlpp_matrix.h" @@ -40,7 +42,7 @@ public: 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); + Ref element_wise_divisionm(const Ref &A, const Ref &B); std::vector> transpose(std::vector> A); std::vector> scalarMultiply(real_t scalar, std::vector> A); @@ -58,20 +60,27 @@ public: std::vector> sqrt(std::vector> A); std::vector> cbrt(std::vector> A); + Ref logm(const Ref &A); + Ref log10m(const Ref &A); + Ref expm(const Ref &A); + Ref erfm(const Ref &A); + Ref exponentiatem(const Ref &A, real_t p); + Ref sqrtm(const Ref &A); + Ref cbrtm(const Ref &A); + std::vector> matrixPower(std::vector> A, int n); std::vector> abs(std::vector> A); + Ref absm(const Ref &A); + real_t det(std::vector> A, int d); real_t trace(std::vector> A); std::vector> cofactor(std::vector> A, int n, int i, int j); - std::vector> adjoint(std::vector> A); - std::vector> inverse(std::vector> A); - std::vector> pinverse(std::vector> A); std::vector> zeromat(int n, int m); @@ -88,9 +97,7 @@ public: std::vector> rotate(std::vector> A, real_t theta, int axis = -1); std::vector> max(std::vector> A, std::vector> B); - real_t max(std::vector> A); - real_t min(std::vector> A); std::vector> round(std::vector> A); @@ -162,6 +169,8 @@ public: std::vector> outerProduct(std::vector a, std::vector b); // This multiplies a, bT std::vector hadamard_product(std::vector a, std::vector b); + Ref hadamard_productnv(const Ref &a, const Ref &b); + void hadamard_productv(const Ref &a, const Ref &b, Ref out); std::vector elementWiseDivision(std::vector a, std::vector b); Ref element_wise_division(const Ref &a, const Ref &b); @@ -171,13 +180,14 @@ public: void scalar_multiplyv(real_t scalar, const Ref &a, Ref out); std::vector scalarAdd(real_t scalar, std::vector a); + Ref scalar_addnv(real_t scalar, const Ref &a); + void scalar_addv(real_t scalar, const Ref &a, Ref out); std::vector addition(std::vector a, std::vector b); Ref additionnv(const Ref &a, const Ref &b); void additionv(const Ref &a, const Ref &b, Ref out); std::vector subtraction(std::vector a, std::vector b); - Ref subtractionnv(const Ref &a, const Ref &b); void subtractionv(const Ref &a, const Ref &b, Ref out); @@ -209,6 +219,8 @@ public: std::vector onevec(int n); std::vector full(int n, int k); + Ref absv(const Ref &a); + Ref zerovecv(int n); Ref onevecv(int n); Ref fullv(int n, int k);