From 2e6094cf03dcd5b3ff56ae0bd0ada805dc72e4c3 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 25 Apr 2023 18:03:22 +0200 Subject: [PATCH] Moved lots of methods in MLPPTensor3's header to the .cpp file. --- mlpp/lin_alg/mlpp_tensor3.cpp | 822 ++++++++++++++++++++++++++++++++ mlpp/lin_alg/mlpp_tensor3.h | 854 ++-------------------------------- 2 files changed, 869 insertions(+), 807 deletions(-) diff --git a/mlpp/lin_alg/mlpp_tensor3.cpp b/mlpp/lin_alg/mlpp_tensor3.cpp index b9b91fc..73c460d 100644 --- a/mlpp/lin_alg/mlpp_tensor3.cpp +++ b/mlpp/lin_alg/mlpp_tensor3.cpp @@ -3,6 +3,534 @@ #include "core/io/image.h" +void MLPPTensor3::add_z_slice(const Vector &p_row) { + if (p_row.size() == 0) { + return; + } + + int fms = z_slice_data_size(); + + ERR_FAIL_COND(fms != p_row.size()); + + int ci = data_size(); + + ++_size.z; + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + const real_t *row_arr = p_row.ptr(); + + for (int i = 0; i < p_row.size(); ++i) { + _data[ci + i] = row_arr[i]; + } +} + +void MLPPTensor3::add_z_slice_pool_vector(const PoolRealArray &p_row) { + if (p_row.size() == 0) { + return; + } + + int fms = z_slice_data_size(); + + ERR_FAIL_COND(fms != p_row.size()); + + int ci = data_size(); + + ++_size.z; + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + PoolRealArray::Read rread = p_row.read(); + const real_t *row_arr = rread.ptr(); + + for (int i = 0; i < p_row.size(); ++i) { + _data[ci + i] = row_arr[i]; + } +} + +void MLPPTensor3::add_z_slice_mlpp_vector(const Ref &p_row) { + ERR_FAIL_COND(!p_row.is_valid()); + + int p_row_size = p_row->size(); + + if (p_row_size == 0) { + return; + } + + int fms = z_slice_data_size(); + + ERR_FAIL_COND(fms != p_row_size); + + int ci = data_size(); + + ++_size.z; + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + const real_t *row_ptr = p_row->ptr(); + + for (int i = 0; i < p_row_size; ++i) { + _data[ci + i] = row_ptr[i]; + } +} + +void MLPPTensor3::add_z_slice_mlpp_matrix(const Ref &p_matrix) { + ERR_FAIL_COND(!p_matrix.is_valid()); + + int other_data_size = p_matrix->data_size(); + + if (other_data_size == 0) { + return; + } + + Size2i matrix_size = p_matrix->size(); + Size2i fms = z_slice_size(); + + ERR_FAIL_COND(fms != matrix_size); + + int start_offset = data_size(); + + ++_size.z; + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + const real_t *other_ptr = p_matrix->ptr(); + + for (int i = 0; i < other_data_size; ++i) { + _data[start_offset + i] = other_ptr[i]; + } +} + +void MLPPTensor3::remove_z_slice(int p_index) { + ERR_FAIL_INDEX(p_index, _size.z); + + --_size.z; + + int ds = data_size(); + + if (ds == 0) { + memfree(_data); + _data = NULL; + return; + } + + int fmds = z_slice_data_size(); + + for (int i = calculate_z_slice_index(p_index); i < ds; ++i) { + _data[i] = _data[i + fmds]; + } + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); +} + +// Removes the item copying the last value into the position of the one to +// remove. It's generally faster than `remove`. +void MLPPTensor3::remove_z_slice_unordered(int p_index) { + ERR_FAIL_INDEX(p_index, _size.z); + + --_size.z; + + int ds = data_size(); + + if (ds == 0) { + memfree(_data); + _data = NULL; + return; + } + + int start_ind = calculate_z_slice_index(p_index); + int end_ind = calculate_z_slice_index(p_index + 1); + + for (int i = start_ind; i < end_ind; ++i) { + _data[i] = _data[ds + i]; + } + + _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); +} + +void MLPPTensor3::swap_z_slice(int p_index_1, int p_index_2) { + ERR_FAIL_INDEX(p_index_1, _size.z); + ERR_FAIL_INDEX(p_index_2, _size.z); + + int ind1_start = calculate_z_slice_index(p_index_1); + int ind2_start = calculate_z_slice_index(p_index_2); + + int fmds = z_slice_data_size(); + + for (int i = 0; i < fmds; ++i) { + SWAP(_data[ind1_start + i], _data[ind2_start + i]); + } +} + +void MLPPTensor3::resize(const Size3i &p_size) { + _size = p_size; + + int ds = data_size(); + + if (ds == 0) { + if (_data) { + memfree(_data); + _data = NULL; + } + + return; + } + + _data = (real_t *)memrealloc(_data, ds * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); +} + +void MLPPTensor3::set_shape(const Size3i &p_size) { + int ds = data_size(); + int new_data_size = p_size.x * p_size.y * p_size.z; + + ERR_FAIL_COND_MSG(ds != new_data_size, "The new size has a different volume than the old. If this is intended use resize()!"); + + _size = p_size; +} + +Vector MLPPTensor3::get_row_vector(int p_index_y, int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_y, _size.y, Vector()); + ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector()); + + Vector ret; + + if (unlikely(_size.x == 0)) { + return ret; + } + + ret.resize(_size.x); + + int ind_start = p_index_y * _size.x; + + real_t *row_ptr = ret.ptrw(); + + for (int i = 0; i < _size.x; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +PoolRealArray MLPPTensor3::get_row_pool_vector(int p_index_y, int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_y, _size.y, PoolRealArray()); + ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray()); + + PoolRealArray ret; + + if (unlikely(_size.x == 0)) { + return ret; + } + + ret.resize(_size.x); + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + PoolRealArray::Write w = ret.write(); + real_t *row_ptr = w.ptr(); + + for (int i = 0; i < _size.x; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +Ref MLPPTensor3::get_row_mlpp_vector(int p_index_y, int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_y, _size.y, Ref()); + ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); + + Ref ret; + ret.instance(); + + if (unlikely(_size.x == 0)) { + return ret; + } + + ret->resize(_size.x); + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + real_t *row_ptr = ret->ptrw(); + + for (int i = 0; i < _size.x; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +void MLPPTensor3::get_row_into_mlpp_vector(int p_index_y, int p_index_z, Ref target) const { + ERR_FAIL_COND(!target.is_valid()); + ERR_FAIL_INDEX(p_index_y, _size.y); + ERR_FAIL_INDEX(p_index_z, _size.z); + + if (unlikely(target->size() != _size.x)) { + target->resize(_size.x); + } + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + real_t *row_ptr = target->ptrw(); + + for (int i = 0; i < _size.x; ++i) { + row_ptr[i] = _data[ind_start + i]; + } +} + +void MLPPTensor3::set_row_vector(int p_index_y, int p_index_z, const Vector &p_row) { + ERR_FAIL_COND(p_row.size() != _size.x); + ERR_FAIL_INDEX(p_index_y, _size.y); + ERR_FAIL_INDEX(p_index_z, _size.z); + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + const real_t *row_ptr = p_row.ptr(); + + for (int i = 0; i < _size.x; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +void MLPPTensor3::set_row_pool_vector(int p_index_y, int p_index_z, const PoolRealArray &p_row) { + ERR_FAIL_COND(p_row.size() != _size.x); + ERR_FAIL_INDEX(p_index_y, _size.y); + ERR_FAIL_INDEX(p_index_z, _size.z); + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + PoolRealArray::Read r = p_row.read(); + const real_t *row_ptr = r.ptr(); + + for (int i = 0; i < _size.x; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +void MLPPTensor3::set_row_mlpp_vector(int p_index_y, int p_index_z, const Ref &p_row) { + ERR_FAIL_COND(!p_row.is_valid()); + ERR_FAIL_COND(p_row->size() != _size.x); + ERR_FAIL_INDEX(p_index_y, _size.y); + ERR_FAIL_INDEX(p_index_z, _size.z); + + int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; + + const real_t *row_ptr = p_row->ptr(); + + for (int i = 0; i < _size.x; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +Vector MLPPTensor3::get_z_slice_vector(int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector()); + + Vector ret; + + int fmds = z_slice_data_size(); + + if (unlikely(fmds == 0)) { + return ret; + } + + ret.resize(fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + real_t *row_ptr = ret.ptrw(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +PoolRealArray MLPPTensor3::get_z_slice_pool_vector(int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray()); + + PoolRealArray ret; + + int fmds = z_slice_data_size(); + + if (unlikely(fmds == 0)) { + return ret; + } + + ret.resize(fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + PoolRealArray::Write w = ret.write(); + real_t *row_ptr = w.ptr(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +Ref MLPPTensor3::get_z_slice_mlpp_vector(int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); + + Ref ret; + ret.instance(); + + int fmds = z_slice_data_size(); + + if (unlikely(fmds == 0)) { + return ret; + } + + ret->resize(fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + real_t *row_ptr = ret->ptrw(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +void MLPPTensor3::get_z_slice_into_mlpp_vector(int p_index_z, Ref target) const { + ERR_FAIL_INDEX(p_index_z, _size.z); + + int fmds = z_slice_data_size(); + + if (unlikely(target->size() != fmds)) { + target->resize(fmds); + } + + int ind_start = calculate_z_slice_index(p_index_z); + + real_t *row_ptr = target->ptrw(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } +} + +Ref MLPPTensor3::get_z_slice_mlpp_matrix(int p_index_z) const { + ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); + + Ref ret; + ret.instance(); + + int fmds = z_slice_data_size(); + + if (unlikely(fmds == 0)) { + return ret; + } + + ret->resize(z_slice_size()); + + int ind_start = calculate_z_slice_index(p_index_z); + + real_t *row_ptr = ret->ptrw(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } + + return ret; +} + +void MLPPTensor3::get_z_slice_into_mlpp_matrix(int p_index_z, Ref target) const { + ERR_FAIL_INDEX(p_index_z, _size.z); + + int fmds = z_slice_data_size(); + Size2i fms = z_slice_size(); + + if (unlikely(target->size() != fms)) { + target->resize(fms); + } + + int ind_start = calculate_z_slice_index(p_index_z); + + real_t *row_ptr = target->ptrw(); + + for (int i = 0; i < fmds; ++i) { + row_ptr[i] = _data[ind_start + i]; + } +} + +void MLPPTensor3::set_z_slice_vector(int p_index_z, const Vector &p_row) { + ERR_FAIL_INDEX(p_index_z, _size.z); + + int fmds = z_slice_data_size(); + + ERR_FAIL_COND(p_row.size() != fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + const real_t *row_ptr = p_row.ptr(); + + for (int i = 0; i < fmds; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +void MLPPTensor3::set_z_slice_pool_vector(int p_index_z, const PoolRealArray &p_row) { + ERR_FAIL_INDEX(p_index_z, _size.z); + + int fmds = z_slice_data_size(); + + ERR_FAIL_COND(p_row.size() != fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + PoolRealArray::Read r = p_row.read(); + const real_t *row_ptr = r.ptr(); + + for (int i = 0; i < fmds; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +void MLPPTensor3::set_z_slice_mlpp_vector(int p_index_z, const Ref &p_row) { + ERR_FAIL_INDEX(p_index_z, _size.z); + ERR_FAIL_COND(!p_row.is_valid()); + + int fmds = z_slice_data_size(); + + ERR_FAIL_COND(p_row->size() != fmds); + + int ind_start = calculate_z_slice_index(p_index_z); + + const real_t *row_ptr = p_row->ptr(); + + for (int i = 0; i < fmds; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + +void MLPPTensor3::set_z_slice_mlpp_matrix(int p_index_z, const Ref &p_mat) { + ERR_FAIL_INDEX(p_index_z, _size.z); + ERR_FAIL_COND(!p_mat.is_valid()); + + int fmds = z_slice_data_size(); + + ERR_FAIL_COND(p_mat->size() != z_slice_size()); + + int ind_start = calculate_z_slice_index(p_index_z); + + const real_t *row_ptr = p_mat->ptr(); + + for (int i = 0; i < fmds; ++i) { + _data[ind_start + i] = row_ptr[i]; + } +} + void MLPPTensor3::add_z_slices_image(const Ref &p_img, const int p_channels) { ERR_FAIL_COND(!p_img.is_valid()); @@ -975,6 +1503,270 @@ std::vector>> MLPPTensor3::vector_wise_tensor_pr } */ +void MLPPTensor3::fill(real_t p_val) { + if (!_data) { + return; + } + + int ds = data_size(); + for (int i = 0; i < ds; ++i) { + _data[i] = p_val; + } +} + +Vector MLPPTensor3::to_flat_vector() const { + Vector ret; + ret.resize(data_size()); + real_t *w = ret.ptrw(); + memcpy(w, _data, sizeof(real_t) * data_size()); + return ret; +} + +PoolRealArray MLPPTensor3::to_flat_pool_vector() const { + PoolRealArray pl; + if (data_size()) { + pl.resize(data_size()); + typename PoolRealArray::Write w = pl.write(); + real_t *dest = w.ptr(); + + for (int i = 0; i < data_size(); ++i) { + dest[i] = static_cast(_data[i]); + } + } + return pl; +} + +Vector MLPPTensor3::to_flat_byte_array() const { + Vector ret; + ret.resize(data_size() * sizeof(real_t)); + uint8_t *w = ret.ptrw(); + memcpy(w, _data, sizeof(real_t) * data_size()); + return ret; +} + +Ref MLPPTensor3::duplicate() const { + Ref ret; + ret.instance(); + + ret->set_from_mlpp_tensor3r(*this); + + return ret; +} + +void MLPPTensor3::set_from_mlpp_tensor3(const Ref &p_from) { + ERR_FAIL_COND(!p_from.is_valid()); + + resize(p_from->size()); + + int ds = p_from->data_size(); + const real_t *ptr = p_from->ptr(); + + for (int i = 0; i < ds; ++i) { + _data[i] = ptr[i]; + } +} + +void MLPPTensor3::set_from_mlpp_tensor3r(const MLPPTensor3 &p_from) { + resize(p_from.size()); + + int ds = p_from.data_size(); + const real_t *ptr = p_from.ptr(); + + for (int i = 0; i < ds; ++i) { + _data[i] = ptr[i]; + } +} + +void MLPPTensor3::set_from_mlpp_matrix(const Ref &p_from) { + ERR_FAIL_COND(!p_from.is_valid()); + + Size2i mat_size = p_from->size(); + resize(Size3i(mat_size.x, mat_size.y, 1)); + + int ds = p_from->data_size(); + const real_t *ptr = p_from->ptr(); + + for (int i = 0; i < ds; ++i) { + _data[i] = ptr[i]; + } +} + +void MLPPTensor3::set_from_mlpp_matrixr(const MLPPMatrix &p_from) { + Size2i mat_size = p_from.size(); + resize(Size3i(mat_size.x, mat_size.y, 1)); + + int ds = p_from.data_size(); + const real_t *ptr = p_from.ptr(); + + for (int i = 0; i < ds; ++i) { + _data[i] = ptr[i]; + } +} + +void MLPPTensor3::set_from_mlpp_vectors(const Vector> &p_from) { + if (p_from.size() == 0) { + reset(); + return; + } + + if (!p_from[0].is_valid()) { + reset(); + return; + } + + resize(Size3i(p_from[0]->size(), p_from.size(), 1)); + + if (data_size() == 0) { + reset(); + return; + } + + for (int i = 0; i < p_from.size(); ++i) { + const Ref &r = p_from[i]; + + ERR_CONTINUE(!r.is_valid()); + ERR_CONTINUE(r->size() != _size.x); + + int start_index = i * _size.x; + + const real_t *from_ptr = r->ptr(); + for (int j = 0; j < _size.x; j++) { + _data[start_index + j] = from_ptr[j]; + } + } +} + +void MLPPTensor3::set_from_mlpp_matricess(const Vector> &p_from) { + if (p_from.size() == 0) { + reset(); + return; + } + + if (!p_from[0].is_valid()) { + reset(); + return; + } + + resize(Size3i(p_from[0]->size().x, p_from[0]->size().y, p_from.size())); + + if (data_size() == 0) { + reset(); + return; + } + + Size2i fms = z_slice_size(); + int fmds = z_slice_data_size(); + + for (int i = 0; i < p_from.size(); ++i) { + const Ref &r = p_from[i]; + + ERR_CONTINUE(!r.is_valid()); + ERR_CONTINUE(r->size() != fms); + + int start_index = calculate_z_slice_index(i); + + const real_t *from_ptr = r->ptr(); + for (int j = 0; j < fmds; j++) { + _data[start_index + j] = from_ptr[j]; + } + } +} + +void MLPPTensor3::set_from_mlpp_vectors_array(const Array &p_from) { + if (p_from.size() == 0) { + reset(); + return; + } + + Ref v0 = p_from[0]; + + if (!v0.is_valid()) { + reset(); + return; + } + + resize(Size3i(v0->size(), p_from.size(), 1)); + + if (data_size() == 0) { + reset(); + return; + } + + for (int i = 0; i < p_from.size(); ++i) { + Ref r = p_from[i]; + + ERR_CONTINUE(!r.is_valid()); + ERR_CONTINUE(r->size() != _size.x); + + int start_index = i * _size.x; + + const real_t *from_ptr = r->ptr(); + for (int j = 0; j < _size.x; j++) { + _data[start_index + j] = from_ptr[j]; + } + } +} + +void MLPPTensor3::set_from_mlpp_matrices_array(const Array &p_from) { + if (p_from.size() == 0) { + reset(); + return; + } + + Ref v0 = p_from[0]; + + if (!v0.is_valid()) { + reset(); + return; + } + + resize(Size3i(v0->size().x, v0->size().y, p_from.size())); + + if (data_size() == 0) { + reset(); + return; + } + + Size2i fms = z_slice_size(); + int fmds = z_slice_data_size(); + + for (int i = 0; i < p_from.size(); ++i) { + Ref r = p_from[i]; + + ERR_CONTINUE(!r.is_valid()); + ERR_CONTINUE(r->size() != fms); + + int start_index = calculate_z_slice_index(i); + + const real_t *from_ptr = r->ptr(); + for (int j = 0; j < fmds; j++) { + _data[start_index + j] = from_ptr[j]; + } + } +} + +bool MLPPTensor3::is_equal_approx(const Ref &p_with, real_t tolerance) const { + ERR_FAIL_COND_V(!p_with.is_valid(), false); + + if (unlikely(this == p_with.ptr())) { + return true; + } + + if (_size != p_with->size()) { + return false; + } + + int ds = data_size(); + + for (int i = 0; i < ds; ++i) { + if (!Math::is_equal_approx(_data[i], p_with->_data[i], tolerance)) { + return false; + } + } + + return true; +} + String MLPPTensor3::to_string() { String str; @@ -1004,6 +1796,36 @@ String MLPPTensor3::to_string() { return str; } +MLPPTensor3::MLPPTensor3() { + _data = NULL; +} + +MLPPTensor3::MLPPTensor3(const MLPPMatrix &p_from) { + _data = NULL; + + Size2i mat_size = p_from.size(); + resize(Size3i(mat_size.x, mat_size.y, 1)); + + int ds = p_from.data_size(); + const real_t *ptr = p_from.ptr(); + + for (int i = 0; i < ds; ++i) { + _data[i] = ptr[i]; + } +} + +MLPPTensor3::MLPPTensor3(const Array &p_from) { + _data = NULL; + + set_from_mlpp_matrices_array(p_from); +} + +MLPPTensor3::~MLPPTensor3() { + if (_data) { + reset(); + } +} + std::vector MLPPTensor3::to_flat_std_vector() const { std::vector ret; ret.resize(data_size()); diff --git a/mlpp/lin_alg/mlpp_tensor3.h b/mlpp/lin_alg/mlpp_tensor3.h index c3d0621..ae95f80 100644 --- a/mlpp/lin_alg/mlpp_tensor3.h +++ b/mlpp/lin_alg/mlpp_tensor3.h @@ -29,170 +29,17 @@ public: return _data; } - _FORCE_INLINE_ void add_z_slice(const Vector &p_row) { - if (p_row.size() == 0) { - return; - } - - int fms = z_slice_data_size(); - - ERR_FAIL_COND(fms != p_row.size()); - - int ci = data_size(); - - ++_size.z; - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - const real_t *row_arr = p_row.ptr(); - - for (int i = 0; i < p_row.size(); ++i) { - _data[ci + i] = row_arr[i]; - } - } - - _FORCE_INLINE_ void add_z_slice_pool_vector(const PoolRealArray &p_row) { - if (p_row.size() == 0) { - return; - } - - int fms = z_slice_data_size(); - - ERR_FAIL_COND(fms != p_row.size()); - - int ci = data_size(); - - ++_size.z; - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - PoolRealArray::Read rread = p_row.read(); - const real_t *row_arr = rread.ptr(); - - for (int i = 0; i < p_row.size(); ++i) { - _data[ci + i] = row_arr[i]; - } - } - - _FORCE_INLINE_ void add_z_slice_mlpp_vector(const Ref &p_row) { - ERR_FAIL_COND(!p_row.is_valid()); - - int p_row_size = p_row->size(); - - if (p_row_size == 0) { - return; - } - - int fms = z_slice_data_size(); - - ERR_FAIL_COND(fms != p_row_size); - - int ci = data_size(); - - ++_size.z; - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - const real_t *row_ptr = p_row->ptr(); - - for (int i = 0; i < p_row_size; ++i) { - _data[ci + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void add_z_slice_mlpp_matrix(const Ref &p_matrix) { - ERR_FAIL_COND(!p_matrix.is_valid()); - - int other_data_size = p_matrix->data_size(); - - if (other_data_size == 0) { - return; - } - - Size2i matrix_size = p_matrix->size(); - Size2i fms = z_slice_size(); - - ERR_FAIL_COND(fms != matrix_size); - - int start_offset = data_size(); - - ++_size.z; - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - const real_t *other_ptr = p_matrix->ptr(); - - for (int i = 0; i < other_data_size; ++i) { - _data[start_offset + i] = other_ptr[i]; - } - } - - void remove_z_slice(int p_index) { - ERR_FAIL_INDEX(p_index, _size.z); - - --_size.z; - - int ds = data_size(); - - if (ds == 0) { - memfree(_data); - _data = NULL; - return; - } - - int fmds = z_slice_data_size(); - - for (int i = calculate_z_slice_index(p_index); i < ds; ++i) { - _data[i] = _data[i + fmds]; - } - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } + void add_z_slice(const Vector &p_row); + void add_z_slice_pool_vector(const PoolRealArray &p_row); + void add_z_slice_mlpp_vector(const Ref &p_row); + void add_z_slice_mlpp_matrix(const Ref &p_matrix); + void remove_z_slice(int p_index); // Removes the item copying the last value into the position of the one to // remove. It's generally faster than `remove`. - void remove_z_slice_unordered(int p_index) { - ERR_FAIL_INDEX(p_index, _size.z); + void remove_z_slice_unordered(int p_index); - --_size.z; - - int ds = data_size(); - - if (ds == 0) { - memfree(_data); - _data = NULL; - return; - } - - int start_ind = calculate_z_slice_index(p_index); - int end_ind = calculate_z_slice_index(p_index + 1); - - for (int i = start_ind; i < end_ind; ++i) { - _data[i] = _data[ds + i]; - } - - _data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } - - void swap_z_slice(int p_index_1, int p_index_2) { - ERR_FAIL_INDEX(p_index_1, _size.z); - ERR_FAIL_INDEX(p_index_2, _size.z); - - int ind1_start = calculate_z_slice_index(p_index_1); - int ind2_start = calculate_z_slice_index(p_index_2); - - int fmds = z_slice_data_size(); - - for (int i = 0; i < fmds; ++i) { - SWAP(_data[ind1_start + i], _data[ind2_start + i]); - } - } + void swap_z_slice(int p_index_1, int p_index_2); _FORCE_INLINE_ void clear() { resize(Size3i()); } _FORCE_INLINE_ void reset() { @@ -209,32 +56,8 @@ public: _FORCE_INLINE_ int data_size() const { return _size.x * _size.y * _size.z; } _FORCE_INLINE_ Size3i size() const { return _size; } - void resize(const Size3i &p_size) { - _size = p_size; - - int ds = data_size(); - - if (ds == 0) { - if (_data) { - memfree(_data); - _data = NULL; - } - - return; - } - - _data = (real_t *)memrealloc(_data, ds * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } - - void set_shape(const Size3i &p_size) { - int ds = data_size(); - int new_data_size = p_size.x * p_size.y * p_size.z; - - ERR_FAIL_COND_MSG(ds != new_data_size, "The new size has a different volume than the old. If this is intended use resize()!"); - - _size = p_size; - } + void resize(const Size3i &p_size); + void set_shape(const Size3i &p_size); _FORCE_INLINE_ int calculate_index(int p_index_y, int p_index_x, int p_index_z) const { return p_index_y * _size.x + p_index_x + _size.x * _size.y * p_index_z; @@ -281,341 +104,26 @@ public: _data[p_index_y * _size.x + p_index_x + _size.x * _size.y * p_index_z] = p_val; } - _FORCE_INLINE_ Vector get_row_vector(int p_index_y, int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_y, _size.y, Vector()); - ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector()); - - Vector ret; - - if (unlikely(_size.x == 0)) { - return ret; - } - - ret.resize(_size.x); - - int ind_start = p_index_y * _size.x; - - real_t *row_ptr = ret.ptrw(); - - for (int i = 0; i < _size.x; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ PoolRealArray get_row_pool_vector(int p_index_y, int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_y, _size.y, PoolRealArray()); - ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray()); - - PoolRealArray ret; - - if (unlikely(_size.x == 0)) { - return ret; - } - - ret.resize(_size.x); - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - PoolRealArray::Write w = ret.write(); - real_t *row_ptr = w.ptr(); - - for (int i = 0; i < _size.x; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ Ref get_row_mlpp_vector(int p_index_y, int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_y, _size.y, Ref()); - ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); - - Ref ret; - ret.instance(); - - if (unlikely(_size.x == 0)) { - return ret; - } - - ret->resize(_size.x); - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - real_t *row_ptr = ret->ptrw(); - - for (int i = 0; i < _size.x; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ void get_row_into_mlpp_vector(int p_index_y, int p_index_z, Ref target) const { - ERR_FAIL_COND(!target.is_valid()); - ERR_FAIL_INDEX(p_index_y, _size.y); - ERR_FAIL_INDEX(p_index_z, _size.z); - - if (unlikely(target->size() != _size.x)) { - target->resize(_size.x); - } - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - real_t *row_ptr = target->ptrw(); - - for (int i = 0; i < _size.x; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - } - - _FORCE_INLINE_ void set_row_vector(int p_index_y, int p_index_z, const Vector &p_row) { - ERR_FAIL_COND(p_row.size() != _size.x); - ERR_FAIL_INDEX(p_index_y, _size.y); - ERR_FAIL_INDEX(p_index_z, _size.z); - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - const real_t *row_ptr = p_row.ptr(); - - for (int i = 0; i < _size.x; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void set_row_pool_vector(int p_index_y, int p_index_z, const PoolRealArray &p_row) { - ERR_FAIL_COND(p_row.size() != _size.x); - ERR_FAIL_INDEX(p_index_y, _size.y); - ERR_FAIL_INDEX(p_index_z, _size.z); - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - PoolRealArray::Read r = p_row.read(); - const real_t *row_ptr = r.ptr(); - - for (int i = 0; i < _size.x; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void set_row_mlpp_vector(int p_index_y, int p_index_z, const Ref &p_row) { - ERR_FAIL_COND(!p_row.is_valid()); - ERR_FAIL_COND(p_row->size() != _size.x); - ERR_FAIL_INDEX(p_index_y, _size.y); - ERR_FAIL_INDEX(p_index_z, _size.z); - - int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z; - - const real_t *row_ptr = p_row->ptr(); - - for (int i = 0; i < _size.x; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ Vector get_z_slice_vector(int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector()); - - Vector ret; - - int fmds = z_slice_data_size(); - - if (unlikely(fmds == 0)) { - return ret; - } - - ret.resize(fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - real_t *row_ptr = ret.ptrw(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ PoolRealArray get_z_slice_pool_vector(int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray()); - - PoolRealArray ret; - - int fmds = z_slice_data_size(); - - if (unlikely(fmds == 0)) { - return ret; - } - - ret.resize(fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - PoolRealArray::Write w = ret.write(); - real_t *row_ptr = w.ptr(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ Ref get_z_slice_mlpp_vector(int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); - - Ref ret; - ret.instance(); - - int fmds = z_slice_data_size(); - - if (unlikely(fmds == 0)) { - return ret; - } - - ret->resize(fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - real_t *row_ptr = ret->ptrw(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ void get_z_slice_into_mlpp_vector(int p_index_z, Ref target) const { - ERR_FAIL_INDEX(p_index_z, _size.z); - - int fmds = z_slice_data_size(); - - if (unlikely(target->size() != fmds)) { - target->resize(fmds); - } - - int ind_start = calculate_z_slice_index(p_index_z); - - real_t *row_ptr = target->ptrw(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - } - - _FORCE_INLINE_ Ref get_z_slice_mlpp_matrix(int p_index_z) const { - ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref()); - - Ref ret; - ret.instance(); - - int fmds = z_slice_data_size(); - - if (unlikely(fmds == 0)) { - return ret; - } - - ret->resize(z_slice_size()); - - int ind_start = calculate_z_slice_index(p_index_z); - - real_t *row_ptr = ret->ptrw(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - - return ret; - } - - _FORCE_INLINE_ void get_z_slice_into_mlpp_matrix(int p_index_z, Ref target) const { - ERR_FAIL_INDEX(p_index_z, _size.z); - - int fmds = z_slice_data_size(); - Size2i fms = z_slice_size(); - - if (unlikely(target->size() != fms)) { - target->resize(fms); - } - - int ind_start = calculate_z_slice_index(p_index_z); - - real_t *row_ptr = target->ptrw(); - - for (int i = 0; i < fmds; ++i) { - row_ptr[i] = _data[ind_start + i]; - } - } - - _FORCE_INLINE_ void set_z_slice_vector(int p_index_z, const Vector &p_row) { - ERR_FAIL_INDEX(p_index_z, _size.z); - - int fmds = z_slice_data_size(); - - ERR_FAIL_COND(p_row.size() != fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - const real_t *row_ptr = p_row.ptr(); - - for (int i = 0; i < fmds; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void set_z_slice_pool_vector(int p_index_z, const PoolRealArray &p_row) { - ERR_FAIL_INDEX(p_index_z, _size.z); - - int fmds = z_slice_data_size(); - - ERR_FAIL_COND(p_row.size() != fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - PoolRealArray::Read r = p_row.read(); - const real_t *row_ptr = r.ptr(); - - for (int i = 0; i < fmds; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void set_z_slice_mlpp_vector(int p_index_z, const Ref &p_row) { - ERR_FAIL_INDEX(p_index_z, _size.z); - ERR_FAIL_COND(!p_row.is_valid()); - - int fmds = z_slice_data_size(); - - ERR_FAIL_COND(p_row->size() != fmds); - - int ind_start = calculate_z_slice_index(p_index_z); - - const real_t *row_ptr = p_row->ptr(); - - for (int i = 0; i < fmds; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } - - _FORCE_INLINE_ void set_z_slice_mlpp_matrix(int p_index_z, const Ref &p_mat) { - ERR_FAIL_INDEX(p_index_z, _size.z); - ERR_FAIL_COND(!p_mat.is_valid()); - - int fmds = z_slice_data_size(); - - ERR_FAIL_COND(p_mat->size() != z_slice_size()); - - int ind_start = calculate_z_slice_index(p_index_z); - - const real_t *row_ptr = p_mat->ptr(); - - for (int i = 0; i < fmds; ++i) { - _data[ind_start + i] = row_ptr[i]; - } - } + Vector get_row_vector(int p_index_y, int p_index_z) const; + PoolRealArray get_row_pool_vector(int p_index_y, int p_index_z) const; + Ref get_row_mlpp_vector(int p_index_y, int p_index_z) const; + void get_row_into_mlpp_vector(int p_index_y, int p_index_z, Ref target) const; + + void set_row_vector(int p_index_y, int p_index_z, const Vector &p_row); + void set_row_pool_vector(int p_index_y, int p_index_z, const PoolRealArray &p_row); + void set_row_mlpp_vector(int p_index_y, int p_index_z, const Ref &p_row); + + Vector get_z_slice_vector(int p_index_z) const; + PoolRealArray get_z_slice_pool_vector(int p_index_z) const; + Ref get_z_slice_mlpp_vector(int p_index_z) const; + void get_z_slice_into_mlpp_vector(int p_index_z, Ref target) const; + Ref get_z_slice_mlpp_matrix(int p_index_z) const; + void get_z_slice_into_mlpp_matrix(int p_index_z, Ref target) const; + + void set_z_slice_vector(int p_index_z, const Vector &p_row); + void set_z_slice_pool_vector(int p_index_z, const PoolRealArray &p_row); + void set_z_slice_mlpp_vector(int p_index_z, const Ref &p_row); + void set_z_slice_mlpp_matrix(int p_index_z, const Ref &p_mat); public: //Image api @@ -700,301 +208,33 @@ public: //std::vector>> vector_wise_tensor_product(std::vector>> A, std::vector> B); public: - void fill(real_t p_val) { - if (!_data) { - return; - } + void fill(real_t p_val); - int ds = data_size(); - for (int i = 0; i < ds; ++i) { - _data[i] = p_val; - } - } + Vector to_flat_vector() const; + PoolRealArray to_flat_pool_vector() const; + Vector to_flat_byte_array() const; - Vector to_flat_vector() const { - Vector ret; - ret.resize(data_size()); - real_t *w = ret.ptrw(); - memcpy(w, _data, sizeof(real_t) * data_size()); - return ret; - } + Ref duplicate() const; - PoolRealArray to_flat_pool_vector() const { - PoolRealArray pl; - if (data_size()) { - pl.resize(data_size()); - typename PoolRealArray::Write w = pl.write(); - real_t *dest = w.ptr(); + void set_from_mlpp_tensor3(const Ref &p_from); + void set_from_mlpp_tensor3r(const MLPPTensor3 &p_from); - for (int i = 0; i < data_size(); ++i) { - dest[i] = static_cast(_data[i]); - } - } - return pl; - } + void set_from_mlpp_matrix(const Ref &p_from); + void set_from_mlpp_matrixr(const MLPPMatrix &p_from); + void set_from_mlpp_vectors(const Vector> &p_from); + void set_from_mlpp_matricess(const Vector> &p_from); - Vector to_flat_byte_array() const { - Vector ret; - ret.resize(data_size() * sizeof(real_t)); - uint8_t *w = ret.ptrw(); - memcpy(w, _data, sizeof(real_t) * data_size()); - return ret; - } + void set_from_mlpp_vectors_array(const Array &p_from); + void set_from_mlpp_matrices_array(const Array &p_from); - Ref duplicate() const { - Ref ret; - ret.instance(); - - ret->set_from_mlpp_tensor3r(*this); - - return ret; - } - - _FORCE_INLINE_ void set_from_mlpp_tensor3(const Ref &p_from) { - ERR_FAIL_COND(!p_from.is_valid()); - - resize(p_from->size()); - - int ds = p_from->data_size(); - const real_t *ptr = p_from->ptr(); - - for (int i = 0; i < ds; ++i) { - _data[i] = ptr[i]; - } - } - - _FORCE_INLINE_ void set_from_mlpp_tensor3r(const MLPPTensor3 &p_from) { - resize(p_from.size()); - - int ds = p_from.data_size(); - const real_t *ptr = p_from.ptr(); - - for (int i = 0; i < ds; ++i) { - _data[i] = ptr[i]; - } - } - - _FORCE_INLINE_ void set_from_mlpp_matrix(const Ref &p_from) { - ERR_FAIL_COND(!p_from.is_valid()); - - Size2i mat_size = p_from->size(); - resize(Size3i(mat_size.x, mat_size.y, 1)); - - int ds = p_from->data_size(); - const real_t *ptr = p_from->ptr(); - - for (int i = 0; i < ds; ++i) { - _data[i] = ptr[i]; - } - } - - _FORCE_INLINE_ void set_from_mlpp_matrixr(const MLPPMatrix &p_from) { - Size2i mat_size = p_from.size(); - resize(Size3i(mat_size.x, mat_size.y, 1)); - - int ds = p_from.data_size(); - const real_t *ptr = p_from.ptr(); - - for (int i = 0; i < ds; ++i) { - _data[i] = ptr[i]; - } - } - - _FORCE_INLINE_ void set_from_mlpp_vectors(const Vector> &p_from) { - if (p_from.size() == 0) { - reset(); - return; - } - - if (!p_from[0].is_valid()) { - reset(); - return; - } - - resize(Size3i(p_from[0]->size(), p_from.size(), 1)); - - if (data_size() == 0) { - reset(); - return; - } - - for (int i = 0; i < p_from.size(); ++i) { - const Ref &r = p_from[i]; - - ERR_CONTINUE(!r.is_valid()); - ERR_CONTINUE(r->size() != _size.x); - - int start_index = i * _size.x; - - const real_t *from_ptr = r->ptr(); - for (int j = 0; j < _size.x; j++) { - _data[start_index + j] = from_ptr[j]; - } - } - } - - _FORCE_INLINE_ void set_from_mlpp_matricess(const Vector> &p_from) { - if (p_from.size() == 0) { - reset(); - return; - } - - if (!p_from[0].is_valid()) { - reset(); - return; - } - - resize(Size3i(p_from[0]->size().x, p_from[0]->size().y, p_from.size())); - - if (data_size() == 0) { - reset(); - return; - } - - Size2i fms = z_slice_size(); - int fmds = z_slice_data_size(); - - for (int i = 0; i < p_from.size(); ++i) { - const Ref &r = p_from[i]; - - ERR_CONTINUE(!r.is_valid()); - ERR_CONTINUE(r->size() != fms); - - int start_index = calculate_z_slice_index(i); - - const real_t *from_ptr = r->ptr(); - for (int j = 0; j < fmds; j++) { - _data[start_index + j] = from_ptr[j]; - } - } - } - - _FORCE_INLINE_ void set_from_mlpp_vectors_array(const Array &p_from) { - if (p_from.size() == 0) { - reset(); - return; - } - - Ref v0 = p_from[0]; - - if (!v0.is_valid()) { - reset(); - return; - } - - resize(Size3i(v0->size(), p_from.size(), 1)); - - if (data_size() == 0) { - reset(); - return; - } - - for (int i = 0; i < p_from.size(); ++i) { - Ref r = p_from[i]; - - ERR_CONTINUE(!r.is_valid()); - ERR_CONTINUE(r->size() != _size.x); - - int start_index = i * _size.x; - - const real_t *from_ptr = r->ptr(); - for (int j = 0; j < _size.x; j++) { - _data[start_index + j] = from_ptr[j]; - } - } - } - - _FORCE_INLINE_ void set_from_mlpp_matrices_array(const Array &p_from) { - if (p_from.size() == 0) { - reset(); - return; - } - - Ref v0 = p_from[0]; - - if (!v0.is_valid()) { - reset(); - return; - } - - resize(Size3i(v0->size().x, v0->size().y, p_from.size())); - - if (data_size() == 0) { - reset(); - return; - } - - Size2i fms = z_slice_size(); - int fmds = z_slice_data_size(); - - for (int i = 0; i < p_from.size(); ++i) { - Ref r = p_from[i]; - - ERR_CONTINUE(!r.is_valid()); - ERR_CONTINUE(r->size() != fms); - - int start_index = calculate_z_slice_index(i); - - const real_t *from_ptr = r->ptr(); - for (int j = 0; j < fmds; j++) { - _data[start_index + j] = from_ptr[j]; - } - } - } - - _FORCE_INLINE_ bool is_equal_approx(const Ref &p_with, real_t tolerance = static_cast(CMP_EPSILON)) const { - ERR_FAIL_COND_V(!p_with.is_valid(), false); - - if (unlikely(this == p_with.ptr())) { - return true; - } - - if (_size != p_with->size()) { - return false; - } - - int ds = data_size(); - - for (int i = 0; i < ds; ++i) { - if (!Math::is_equal_approx(_data[i], p_with->_data[i], tolerance)) { - return false; - } - } - - return true; - } + bool is_equal_approx(const Ref &p_with, real_t tolerance = static_cast(CMP_EPSILON)) const; String to_string(); - _FORCE_INLINE_ MLPPTensor3() { - _data = NULL; - } - - _FORCE_INLINE_ MLPPTensor3(const MLPPMatrix &p_from) { - _data = NULL; - - Size2i mat_size = p_from.size(); - resize(Size3i(mat_size.x, mat_size.y, 1)); - - int ds = p_from.data_size(); - const real_t *ptr = p_from.ptr(); - - for (int i = 0; i < ds; ++i) { - _data[i] = ptr[i]; - } - } - - MLPPTensor3(const Array &p_from) { - _data = NULL; - - set_from_mlpp_matrices_array(p_from); - } - - _FORCE_INLINE_ ~MLPPTensor3() { - if (_data) { - reset(); - } - } + MLPPTensor3(); + MLPPTensor3(const MLPPMatrix &p_from); + MLPPTensor3(const Array &p_from); + ~MLPPTensor3(); // TODO: These are temporary std::vector to_flat_std_vector() const;