diff --git a/mlpp/lin_alg/mlpp_vector.cpp b/mlpp/lin_alg/mlpp_vector.cpp index 120c264..779d912 100644 --- a/mlpp/lin_alg/mlpp_vector.cpp +++ b/mlpp/lin_alg/mlpp_vector.cpp @@ -3,6 +3,260 @@ #include "mlpp_matrix.h" +void MLPPVector::push_back(real_t p_elem) { + ++_size; + + _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + _data[_size - 1] = p_elem; +} + +void MLPPVector::add_mlpp_vector(const Ref &p_other) { + ERR_FAIL_COND(!p_other.is_valid()); + + int other_size = p_other->size(); + + if (other_size == 0) { + return; + } + + int start_offset = _size; + + _size += other_size; + + _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); + + const real_t *other_ptr = p_other->ptr(); + + for (int i = 0; i < other_size; ++i) { + _data[start_offset + i] = other_ptr[i]; + } +} + +void MLPPVector::remove(real_t p_index) { + ERR_FAIL_INDEX(p_index, _size); + + --_size; + + if (_size == 0) { + memfree(_data); + _data = NULL; + return; + } + + for (int i = p_index; i < _size; i++) { + _data[i] = _data[i + 1]; + } + + _data = (real_t *)memrealloc(_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 MLPPVector::remove_unordered(int p_index) { + ERR_FAIL_INDEX(p_index, _size); + _size--; + + if (_size == 0) { + memfree(_data); + _data = NULL; + return; + } + + if (_size > p_index) { + _data[p_index] = _data[_size]; + } + + _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); +} + +void MLPPVector::erase(const real_t &p_val) { + int idx = find(p_val); + if (idx >= 0) { + remove(idx); + } +} + +int MLPPVector::erase_multiple_unordered(const real_t &p_val) { + int from = 0; + int count = 0; + while (true) { + int64_t idx = find(p_val, from); + + if (idx == -1) { + break; + } + remove_unordered(idx); + from = idx; + count++; + } + return count; +} + +void MLPPVector::invert() { + for (int i = 0; i < _size / 2; i++) { + SWAP(_data[i], _data[_size - i - 1]); + } +} + +void MLPPVector::resize(int p_size) { + _size = p_size; + + if (_size == 0) { + memfree(_data); + _data = NULL; + return; + } + + _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); + CRASH_COND_MSG(!_data, "Out of memory"); +} + +void MLPPVector::fill(real_t p_val) { + for (int i = 0; i < _size; i++) { + _data[i] = p_val; + } +} + +void MLPPVector::insert(int p_pos, real_t p_val) { + ERR_FAIL_INDEX(p_pos, _size + 1); + if (p_pos == _size) { + push_back(p_val); + } else { + resize(_size + 1); + for (int i = _size - 1; i > p_pos; i--) { + _data[i] = _data[i - 1]; + } + _data[p_pos] = p_val; + } +} + +int MLPPVector::find(const real_t &p_val, int p_from) const { + for (int i = p_from; i < _size; i++) { + if (_data[i] == p_val) { + return i; + } + } + return -1; +} + +void MLPPVector::ordered_insert(real_t p_val) { + int i; + for (i = 0; i < _size; i++) { + if (p_val < _data[i]) { + break; + } + } + insert(i, p_val); +} + +Vector MLPPVector::to_vector() const { + Vector ret; + ret.resize(size()); + real_t *w = ret.ptrw(); + memcpy(w, _data, sizeof(real_t) * _size); + return ret; +} + +PoolRealArray MLPPVector::to_pool_vector() const { + PoolRealArray pl; + if (size()) { + pl.resize(size()); + typename PoolRealArray::Write w = pl.write(); + real_t *dest = w.ptr(); + + for (int i = 0; i < size(); ++i) { + dest[i] = static_cast(_data[i]); + } + } + return pl; +} + +Vector MLPPVector::to_byte_array() const { + Vector ret; + ret.resize(_size * sizeof(real_t)); + uint8_t *w = ret.ptrw(); + memcpy(w, _data, sizeof(real_t) * _size); + return ret; +} + +Ref MLPPVector::duplicate() const { + Ref ret; + ret.instance(); + + ret->set_from_mlpp_vectorr(*this); + + return ret; +} + +void MLPPVector::set_from_mlpp_vectorr(const MLPPVector &p_from) { + if (_size != p_from.size()) { + resize(p_from.size()); + } + + for (int i = 0; i < p_from._size; i++) { + _data[i] = p_from._data[i]; + } +} + +void MLPPVector::set_from_mlpp_vector(const Ref &p_from) { + ERR_FAIL_COND(!p_from.is_valid()); + + if (_size != p_from->size()) { + resize(p_from->size()); + } + + for (int i = 0; i < p_from->_size; i++) { + _data[i] = p_from->_data[i]; + } +} + +void MLPPVector::set_from_vector(const Vector &p_from) { + if (_size != p_from.size()) { + resize(p_from.size()); + } + + resize(p_from.size()); + for (int i = 0; i < _size; i++) { + _data[i] = p_from[i]; + } +} + +void MLPPVector::set_from_pool_vector(const PoolRealArray &p_from) { + if (_size != p_from.size()) { + resize(p_from.size()); + } + + PoolRealArray::Read r = p_from.read(); + for (int i = 0; i < _size; i++) { + _data[i] = r[i]; + } +} + +bool MLPPVector::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; + } + + for (int i = 0; i < _size; ++i) { + if (!Math::is_equal_approx(_data[i], p_with->_data[i], tolerance)) { + return false; + } + } + + return true; +} + void MLPPVector::flatten_vectors(const Vector> &A) { int vsize = 0; for (int i = 0; i < A.size(); ++i) { @@ -1010,6 +1264,47 @@ String MLPPVector::to_string() { return str; } +MLPPVector::MLPPVector() { + _size = 0; + _data = NULL; +} +MLPPVector::MLPPVector(const MLPPVector &p_from) { + _size = 0; + _data = NULL; + + resize(p_from.size()); + for (int i = 0; i < p_from._size; i++) { + _data[i] = p_from._data[i]; + } +} + +MLPPVector::MLPPVector(const Vector &p_from) { + _size = 0; + _data = NULL; + + resize(p_from.size()); + for (int i = 0; i < _size; i++) { + _data[i] = p_from[i]; + } +} + +MLPPVector::MLPPVector(const PoolRealArray &p_from) { + _size = 0; + _data = NULL; + + resize(p_from.size()); + typename PoolRealArray::Read r = p_from.read(); + for (int i = 0; i < _size; i++) { + _data[i] = r[i]; + } +} + +MLPPVector::~MLPPVector() { + if (_data) { + reset(); + } +} + std::vector MLPPVector::to_std_vector() const { std::vector ret; ret.resize(size()); diff --git a/mlpp/lin_alg/mlpp_vector.h b/mlpp/lin_alg/mlpp_vector.h index 1adb5e9..9f0f97b 100644 --- a/mlpp/lin_alg/mlpp_vector.h +++ b/mlpp/lin_alg/mlpp_vector.h @@ -29,105 +29,19 @@ public: return _data; } - _FORCE_INLINE_ void push_back(real_t p_elem) { - ++_size; + void push_back(real_t p_elem); + void add_mlpp_vector(const Ref &p_other); - _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - _data[_size - 1] = p_elem; - } - - _FORCE_INLINE_ void add_mlpp_vector(const Ref &p_other) { - ERR_FAIL_COND(!p_other.is_valid()); - - int other_size = p_other->size(); - - if (other_size == 0) { - return; - } - - int start_offset = _size; - - _size += other_size; - - _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - - const real_t *other_ptr = p_other->ptr(); - - for (int i = 0; i < other_size; ++i) { - _data[start_offset + i] = other_ptr[i]; - } - } - - void remove(real_t p_index) { - ERR_FAIL_INDEX(p_index, _size); - - --_size; - - if (_size == 0) { - memfree(_data); - _data = NULL; - return; - } - - for (int i = p_index; i < _size; i++) { - _data[i] = _data[i + 1]; - } - - _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } + void remove(real_t 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_unordered(int p_index) { - ERR_FAIL_INDEX(p_index, _size); - _size--; + void remove_unordered(int p_index); - if (_size == 0) { - memfree(_data); - _data = NULL; - return; - } + void erase(const real_t &p_val); + int erase_multiple_unordered(const real_t &p_val); - if (_size > p_index) { - _data[p_index] = _data[_size]; - } - - _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } - - void erase(const real_t &p_val) { - int idx = find(p_val); - if (idx >= 0) { - remove(idx); - } - } - - int erase_multiple_unordered(const real_t &p_val) { - int from = 0; - int count = 0; - while (true) { - int64_t idx = find(p_val, from); - - if (idx == -1) { - break; - } - remove_unordered(idx); - from = idx; - count++; - } - return count; - } - - void invert() { - for (int i = 0; i < _size / 2; i++) { - SWAP(_data[i], _data[_size - i - 1]); - } - } + void invert(); _FORCE_INLINE_ void clear() { resize(0); } _FORCE_INLINE_ void reset() { @@ -141,18 +55,7 @@ public: _FORCE_INLINE_ bool empty() const { return _size == 0; } _FORCE_INLINE_ int size() const { return _size; } - void resize(int p_size) { - _size = p_size; - - if (_size == 0) { - memfree(_data); - _data = NULL; - return; - } - - _data = (real_t *)memrealloc(_data, _size * sizeof(real_t)); - CRASH_COND_MSG(!_data, "Out of memory"); - } + void resize(int p_size); _FORCE_INLINE_ const real_t &operator[](int p_index) const { CRASH_BAD_INDEX(p_index, _size); @@ -173,33 +76,10 @@ public: _data[p_index] = p_val; } - void fill(real_t p_val) { - for (int i = 0; i < _size; i++) { - _data[i] = p_val; - } - } + void fill(real_t p_val); + void insert(int p_pos, real_t p_val); - void insert(int p_pos, real_t p_val) { - ERR_FAIL_INDEX(p_pos, _size + 1); - if (p_pos == _size) { - push_back(p_val); - } else { - resize(_size + 1); - for (int i = _size - 1; i > p_pos; i--) { - _data[i] = _data[i - 1]; - } - _data[p_pos] = p_val; - } - } - - int find(const real_t &p_val, int p_from = 0) const { - for (int i = p_from; i < _size; i++) { - if (_data[i] == p_val) { - return i; - } - } - return -1; - } + int find(const real_t &p_val, int p_from = 0) const; template void sort_custom() { @@ -216,118 +96,20 @@ public: sort_custom<_DefaultComparator>(); } - void ordered_insert(real_t p_val) { - int i; - for (i = 0; i < _size; i++) { - if (p_val < _data[i]) { - break; - } - } - insert(i, p_val); - } + void ordered_insert(real_t p_val); - Vector to_vector() const { - Vector ret; - ret.resize(size()); - real_t *w = ret.ptrw(); - memcpy(w, _data, sizeof(real_t) * _size); - return ret; - } + Vector to_vector() const; + PoolRealArray to_pool_vector() const; + Vector to_byte_array() const; - PoolRealArray to_pool_vector() const { - PoolRealArray pl; - if (size()) { - pl.resize(size()); - typename PoolRealArray::Write w = pl.write(); - real_t *dest = w.ptr(); + Ref duplicate() const; - for (int i = 0; i < size(); ++i) { - dest[i] = static_cast(_data[i]); - } - } - return pl; - } + void set_from_mlpp_vectorr(const MLPPVector &p_from); + void set_from_mlpp_vector(const Ref &p_from); + void set_from_vector(const Vector &p_from); + void set_from_pool_vector(const PoolRealArray &p_from); - Vector to_byte_array() const { - Vector ret; - ret.resize(_size * sizeof(real_t)); - uint8_t *w = ret.ptrw(); - memcpy(w, _data, sizeof(real_t) * _size); - return ret; - } - - Ref duplicate() const { - Ref ret; - ret.instance(); - - ret->set_from_mlpp_vectorr(*this); - - return ret; - } - - _FORCE_INLINE_ void set_from_mlpp_vectorr(const MLPPVector &p_from) { - if (_size != p_from.size()) { - resize(p_from.size()); - } - - for (int i = 0; i < p_from._size; i++) { - _data[i] = p_from._data[i]; - } - } - - _FORCE_INLINE_ void set_from_mlpp_vector(const Ref &p_from) { - ERR_FAIL_COND(!p_from.is_valid()); - - if (_size != p_from->size()) { - resize(p_from->size()); - } - - for (int i = 0; i < p_from->_size; i++) { - _data[i] = p_from->_data[i]; - } - } - - _FORCE_INLINE_ void set_from_vector(const Vector &p_from) { - if (_size != p_from.size()) { - resize(p_from.size()); - } - - resize(p_from.size()); - for (int i = 0; i < _size; i++) { - _data[i] = p_from[i]; - } - } - - _FORCE_INLINE_ void set_from_pool_vector(const PoolRealArray &p_from) { - if (_size != p_from.size()) { - resize(p_from.size()); - } - - PoolRealArray::Read r = p_from.read(); - for (int i = 0; i < _size; i++) { - _data[i] = r[i]; - } - } - - _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; - } - - for (int i = 0; i < _size; ++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; void flatten_vectors(const Vector> &A); Ref flatten_vectorsn(const Vector> &A) const; @@ -438,46 +220,12 @@ public: String to_string(); - _FORCE_INLINE_ MLPPVector() { - _size = 0; - _data = NULL; - } - _FORCE_INLINE_ MLPPVector(const MLPPVector &p_from) { - _size = 0; - _data = NULL; + MLPPVector(); + MLPPVector(const MLPPVector &p_from); + MLPPVector(const Vector &p_from); + MLPPVector(const PoolRealArray &p_from); - resize(p_from.size()); - for (int i = 0; i < p_from._size; i++) { - _data[i] = p_from._data[i]; - } - } - - MLPPVector(const Vector &p_from) { - _size = 0; - _data = NULL; - - resize(p_from.size()); - for (int i = 0; i < _size; i++) { - _data[i] = p_from[i]; - } - } - - MLPPVector(const PoolRealArray &p_from) { - _size = 0; - _data = NULL; - - resize(p_from.size()); - typename PoolRealArray::Read r = p_from.read(); - for (int i = 0; i < _size; i++) { - _data[i] = r[i]; - } - } - - _FORCE_INLINE_ ~MLPPVector() { - if (_data) { - reset(); - } - } + ~MLPPVector(); // TODO: These are temporary std::vector to_std_vector() const;