#include "mlpp_vector.h" #include "mlpp_matrix.h" void MLPPVector::flatten_vectors(const Vector> &A) { int vsize = 0; for (int i = 0; i < A.size(); ++i) { vsize += A[i]->size(); } resize(vsize); int a_index = 0; real_t *a_ptr = 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; } } } Ref MLPPVector::flatten_vectorsn(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; } void MLPPVector::hadamard_product(const Ref &b) { ERR_FAIL_COND(!b.is_valid()); ERR_FAIL_COND(_size != b->size()); const real_t *a_ptr = ptr(); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] = a_ptr[i] * b_ptr[i]; } } Ref MLPPVector::hadamard_productn(const Ref &b) { ERR_FAIL_COND_V(!b.is_valid(), Ref()); Ref out; out.instance(); ERR_FAIL_COND_V(_size != b->size(), Ref()); out->resize(_size); const real_t *a_ptr = 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 MLPPVector::hadamard_productb(const Ref &a, const Ref &b) { ERR_FAIL_COND(!a.is_valid() || !b.is_valid()); int s = a->size(); ERR_FAIL_COND(s != b->size()); if (unlikely(size() != s)) { resize(s); } const real_t *a_ptr = a->ptr(); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] * b_ptr[i]; } } void MLPPVector::element_wise_division(const Ref &b) { ERR_FAIL_COND(!b.is_valid()); Ref out; out.instance(); ERR_FAIL_COND(_size != b->size()); const real_t *a_ptr = 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]; } } Ref MLPPVector::element_wise_divisionn(const Ref &b) { ERR_FAIL_COND_V(!b.is_valid(), Ref()); Ref out; out.instance(); ERR_FAIL_COND_V(_size != b->size(), Ref()); out->resize(_size); const real_t *a_ptr = 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 MLPPVector::element_wise_divisionb(const Ref &a, const Ref &b) { ERR_FAIL_COND(!a.is_valid() || !b.is_valid()); int s = a->size(); ERR_FAIL_COND(s != b->size()); resize(s); const real_t *a_ptr = a->ptr(); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] / b_ptr[i]; } } void MLPPVector::scalar_multiply(real_t scalar) { real_t *out_ptr = ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] = out_ptr[i] * scalar; } } Ref MLPPVector::scalar_multiplyn(real_t scalar) { Ref out; out.instance(); out->resize(_size); const real_t *a_ptr = ptr(); real_t *out_ptr = out->ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] = a_ptr[i] * scalar; } return out; } void MLPPVector::scalar_multiplyb(real_t scalar, const Ref &a) { int s = a->size(); if (unlikely(size() != s)) { resize(s); } const real_t *a_ptr = a->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] * scalar; } } void MLPPVector::scalar_add(real_t scalar) { real_t *out_ptr = ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] = out_ptr[i] + scalar; } } Ref MLPPVector::scalar_addn(real_t scalar) { Ref out; out.instance(); out->resize(_size); const real_t *a_ptr = ptr(); real_t *out_ptr = out->ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] = a_ptr[i] + scalar; } return out; } void MLPPVector::scalar_addb(real_t scalar, const Ref &a) { ERR_FAIL_COND(!a.is_valid()); int s = a->size(); if (unlikely(size() != s)) { resize(s); } const real_t *a_ptr = a->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] + scalar; } } void MLPPVector::add(const Ref &b) { ERR_FAIL_COND(!b.is_valid()); ERR_FAIL_COND(_size != b->size()); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] += b_ptr[i]; } } Ref MLPPVector::addn(const Ref &b) { ERR_FAIL_COND_V(!b.is_valid(), Ref()); ERR_FAIL_COND_V(_size != b->size(), Ref()); Ref out; out.instance(); out->resize(_size); const real_t *a_ptr = 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 MLPPVector::addb(const Ref &a, const Ref &b) { ERR_FAIL_COND(!a.is_valid() || !b.is_valid()); int s = a->size(); ERR_FAIL_COND(s != b->size()); if (unlikely(size() != s)) { resize(s); } const real_t *a_ptr = a->ptr(); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] + b_ptr[i]; } } void MLPPVector::sub(const Ref &b) { ERR_FAIL_COND(!b.is_valid()); ERR_FAIL_COND(_size != b->size()); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < _size; ++i) { out_ptr[i] -= b_ptr[i]; } } Ref MLPPVector::subn(const Ref &b) { ERR_FAIL_COND_V(!b.is_valid(), Ref()); ERR_FAIL_COND_V(_size != b->size(), Ref()); Ref out; out.instance(); out->resize(_size); const real_t *a_ptr = 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 MLPPVector::subb(const Ref &a, const Ref &b) { ERR_FAIL_COND(!a.is_valid() || !b.is_valid()); int s = a->size(); ERR_FAIL_COND(s != b->size()); if (unlikely(size() != s)) { resize(s); } const real_t *a_ptr = a->ptr(); const real_t *b_ptr = b->ptr(); real_t *out_ptr = ptrw(); for (int i = 0; i < s; ++i) { out_ptr[i] = a_ptr[i] - b_ptr[i]; } } Ref MLPPVector::lognv(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 MLPPVector::log10nv(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::log10(a_ptr[i]); } return out; } Ref MLPPVector::expnv(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 MLPPVector::erfnv(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::erf(a_ptr[i]); } return out; } Ref MLPPVector::exponentiatenv(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 MLPPVector::sqrtnv(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 MLPPVector::cbrtnv(const Ref &a) { return exponentiatenv(a, static_cast(1) / static_cast(3)); } real_t MLPPVector::dotnv(const Ref &a, const Ref &b) { int a_size = a->size(); ERR_FAIL_COND_V(a_size != b->size(), 0); const real_t *a_ptr = a->ptr(); const real_t *b_ptr = b->ptr(); real_t c = 0; for (int i = 0; i < a_size; ++i) { c += a_ptr[i] * b_ptr[i]; } return c; } /* std::vector MLPPVector::cross(std::vector a, std::vector b) { // Cross products exist in R^7 also. Though, I will limit it to R^3 as Wolfram does this. std::vector> mat = { onevec(3), a, b }; real_t det1 = det({ { a[1], a[2] }, { b[1], b[2] } }, 2); real_t det2 = -det({ { a[0], a[2] }, { b[0], b[2] } }, 2); real_t det3 = det({ { a[0], a[1] }, { b[0], b[1] } }, 2); return { det1, det2, det3 }; } */ Ref MLPPVector::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 MLPPVector::zerovecnv(int n) { Ref vec; vec.instance(); vec->resize(n); vec->fill(0); return vec; } Ref MLPPVector::onevecnv(int n) { Ref vec; vec.instance(); vec->resize(n); vec->fill(1); return vec; } Ref MLPPVector::fullnv(int n, int k) { Ref vec; vec.instance(); vec->resize(n); vec->fill(k); return vec; } Ref MLPPVector::sinnv(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::sin(a_ptr[i]); } return out; } Ref MLPPVector::cosnv(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::cos(a_ptr[i]); } return out; } Ref MLPPVector::maxnvv(const Ref &a, const Ref &b) { Ref ret; ret.instance(); ERR_FAIL_COND_V(!a.is_valid() || !b.is_valid(), ret); int a_size = a->size(); ERR_FAIL_COND_V(a_size != b->size(), ret); ret->resize(a_size); const real_t *aa = a->ptr(); const real_t *ba = b->ptr(); real_t *ret_ptr = ret->ptrw(); for (int i = 0; i < a_size; i++) { real_t aa_i = aa[i]; real_t bb_i = ba[i]; if (aa_i > bb_i) { ret_ptr[i] = aa_i; } else { ret_ptr[i] = bb_i; } } return ret; } real_t MLPPVector::maxvr(const Ref &a) { ERR_FAIL_COND_V(!a.is_valid(), -Math_INF); int a_size = a->size(); const real_t *aa = a->ptr(); real_t max_element = -Math_INF; for (int i = 0; i < a_size; i++) { real_t current_element = aa[i]; if (current_element > max_element) { max_element = current_element; } } return max_element; } real_t MLPPVector::minvr(const Ref &a) { ERR_FAIL_COND_V(!a.is_valid(), Math_INF); int a_size = a->size(); const real_t *aa = a->ptr(); real_t min_element = Math_INF; for (int i = 0; i < a_size; i++) { real_t current_element = aa[i]; if (current_element > min_element) { min_element = current_element; } } return min_element; } /* std::vector> MLPPVector::round(std::vector> A) { std::vector> B; B.resize(A.size()); for (uint32_t i = 0; i < B.size(); i++) { B[i].resize(A[0].size()); } for (uint32_t i = 0; i < A.size(); i++) { for (uint32_t j = 0; j < A[i].size(); j++) { B[i][j] = Math::round(A[i][j]); } } return B; } */ real_t MLPPVector::euclidean_distance(const Ref &a, const Ref &b) { ERR_FAIL_COND_V(!a.is_valid() || !b.is_valid(), 0); int a_size = a->size(); ERR_FAIL_COND_V(a_size != b->size(), 0); const real_t *aa = a->ptr(); const real_t *ba = b->ptr(); real_t dist = 0; for (int i = 0; i < a_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); int a_size = a->size(); ERR_FAIL_COND_V(a_size != b->size(), 0); const real_t *aa = a->ptr(); const real_t *ba = b->ptr(); real_t dist = 0; for (int i = 0; i < a_size; i++) { dist += (aa[i] - ba[i]) * (aa[i] - ba[i]); } return dist; } /* real_t MLPPVector::norm_2(std::vector> A) { real_t sum = 0; for (uint32_t i = 0; i < A.size(); i++) { for (uint32_t j = 0; j < A[i].size(); j++) { sum += A[i][j] * A[i][j]; } } return Math::sqrt(sum); } */ 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 n_sq = 0; 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 sum = 0; for (int i = 0; i < a_size; ++i) { sum += a_ptr[i]; } return sum; } /* real_t MLPPVector::cosineSimilarity(std::vector a, std::vector b) { return dot(a, b) / (norm_2(a) * norm_2(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; str += "[MLPPVector: "; for (int x = 0; x < _size; ++x) { str += String::num(_data[x]); str += " "; } str += "]"; return str; } std::vector MLPPVector::to_std_vector() const { std::vector ret; ret.resize(size()); real_t *w = &ret[0]; memcpy(w, _data, sizeof(real_t) * _size); return ret; } void MLPPVector::set_from_std_vector(const std::vector &p_from) { resize(p_from.size()); for (int i = 0; i < _size; i++) { _data[i] = p_from[i]; } } MLPPVector::MLPPVector(const std::vector &p_from) { _size = 0; _data = NULL; resize(p_from.size()); for (int i = 0; i < _size; i++) { _data[i] = p_from[i]; } } void MLPPVector::_bind_methods() { ClassDB::bind_method(D_METHOD("push_back", "elem"), &MLPPVector::push_back); ClassDB::bind_method(D_METHOD("add_mlpp_vector", "other"), &MLPPVector::push_back); ClassDB::bind_method(D_METHOD("remove", "index"), &MLPPVector::remove); ClassDB::bind_method(D_METHOD("remove_unordered", "index"), &MLPPVector::remove_unordered); ClassDB::bind_method(D_METHOD("erase", "val"), &MLPPVector::erase); ClassDB::bind_method(D_METHOD("erase_multiple_unordered", "val"), &MLPPVector::erase_multiple_unordered); ClassDB::bind_method(D_METHOD("invert"), &MLPPVector::invert); ClassDB::bind_method(D_METHOD("clear"), &MLPPVector::clear); ClassDB::bind_method(D_METHOD("reset"), &MLPPVector::reset); ClassDB::bind_method(D_METHOD("empty"), &MLPPVector::empty); ClassDB::bind_method(D_METHOD("size"), &MLPPVector::size); ClassDB::bind_method(D_METHOD("resize", "size"), &MLPPVector::resize); ClassDB::bind_method(D_METHOD("get_element", "index"), &MLPPVector::get_element); ClassDB::bind_method(D_METHOD("set_element", "index", "val"), &MLPPVector::set_element); ClassDB::bind_method(D_METHOD("fill", "val"), &MLPPVector::fill); ClassDB::bind_method(D_METHOD("insert", "pos", "val"), &MLPPVector::insert); ClassDB::bind_method(D_METHOD("find", "val", "from"), &MLPPVector::find, 0); ClassDB::bind_method(D_METHOD("sort"), &MLPPVector::sort); ClassDB::bind_method(D_METHOD("ordered_insert", "val"), &MLPPVector::ordered_insert); ClassDB::bind_method(D_METHOD("to_pool_vector"), &MLPPVector::to_pool_vector); ClassDB::bind_method(D_METHOD("to_byte_array"), &MLPPVector::to_byte_array); ClassDB::bind_method(D_METHOD("duplicate"), &MLPPVector::duplicate); ClassDB::bind_method(D_METHOD("set_from_mlpp_vector", "from"), &MLPPVector::set_from_mlpp_vector); ClassDB::bind_method(D_METHOD("set_from_pool_vector", "from"), &MLPPVector::set_from_pool_vector); ClassDB::bind_method(D_METHOD("is_equal_approx", "with", "tolerance"), &MLPPVector::is_equal_approx, CMP_EPSILON); }