From 02b2f5a2d79196000eab5729943ee7fb803bfa19 Mon Sep 17 00:00:00 2001 From: Hossein Moein Date: Sat, 9 Nov 2024 13:34:36 -0500 Subject: [PATCH] Basics of matrix object is done --- docs/HTML/self_contained.html | 2 +- include/DataFrame/Utils/Matrix.h | 799 ++++++++++++++++++++++++++++- include/DataFrame/Utils/Matrix.tcc | 10 +- src/CommonMakefile.mk | 15 +- test/CMakeLists.txt | 7 + test/matrix_tester.cc | 79 +++ 6 files changed, 900 insertions(+), 12 deletions(-) create mode 100644 test/matrix_tester.cc diff --git a/docs/HTML/self_contained.html b/docs/HTML/self_contained.html index 44def6e1..35c17038 100644 --- a/docs/HTML/self_contained.html +++ b/docs/HTML/self_contained.html @@ -51,7 +51,7 @@ It also has some disadvantages:
diff --git a/include/DataFrame/Utils/Matrix.h b/include/DataFrame/Utils/Matrix.h index b10b03f2..964b3897 100644 --- a/include/DataFrame/Utils/Matrix.h +++ b/include/DataFrame/Utils/Matrix.h @@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include // ---------------------------------------------------------------------------- @@ -75,20 +76,22 @@ class Matrix { void reserve(size_type rows, size_type cols); size_type rows() const noexcept; - size_type columns() const noexcept; + size_type cols() const noexcept; + + static constexpr matrix_orient orientation(); public: void resize(size_type rows, size_type cols, const_reference def_v = T()); - reference at (size_type r, size_type c); - const_reference at (size_type r, size_type c) const; + reference at(size_type r, size_type c); + const_reference at(size_type r, size_type c) const; reference operator() (size_type r, size_type c); const_reference operator() (size_type r, size_type c) const; // Set the given column or row from the given iterator. // col_data/row_Data iterators must be valid for the length of - // cols_/rows_. + // columns/rows. // template void set_column(I col_data, size_type col); @@ -104,15 +107,801 @@ class Matrix { size_type cols_ { 0 }; storage_t matrix_ { }; + // + // Iterators + // + public: + class row_iterator; + class row_const_iterator : public std::random_access_iterator_tag { + + public: + + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using size_type = long; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using difference_type = typename std::vector::difference_type; + + public: + + inline row_const_iterator () = default; + + inline row_const_iterator(const self_t *m, + size_type row = 0, + size_type col = 0) + : mptr_ (m), row_ (row), col_(col) { } + + inline bool operator == (const row_const_iterator &rhs) const { + + return (mptr_ == rhs.mptr_ && + row_ == rhs.row_ && + col_ == rhs.col_); + } + inline bool operator != (const row_const_iterator &rhs) const { + + return (! (*this == rhs)); + } + inline bool + operator > (const row_const_iterator &rhs) const noexcept { + + return (row_ > rhs.row_ || (row_ == rhs.row_ && col_ > rhs.col_)); + } + inline bool + operator >= (const row_const_iterator &rhs) const noexcept { + + return (row_ > rhs.row_ || (row_ == rhs.row_ && col_ >= rhs.col_)); + } + inline bool + operator < (const row_const_iterator &rhs) const noexcept { + + return (! (*this >= rhs)); + } + inline bool + operator <= (const row_const_iterator &rhs) const noexcept { + + return (! (*this > rhs)); + } + + // Following STL style, this iterator appears as a pointer + // to value_type. + // + inline const_pointer operator -> () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + inline const_reference operator * () const noexcept { + + return (mptr_->at(row_, col_)); + } + inline operator const_pointer () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + + // We are following STL style iterator interface. + // + inline row_const_iterator &operator ++ () noexcept { // ++Prefix + + col_ += 1; + if (col_ >= mptr_->cols()) { col_ = 0; row_ += 1; } + return (*this); + } + inline row_const_iterator operator ++ (int) noexcept { // Postfix++ + + const size_type row = row_; + const size_type col = col_; + + col_ += 1; + if (col_ >= mptr_->cols()) { col_ = 0; row_ += 1; } + return (row_const_iterator (mptr_, row, col)); + } + + inline row_const_iterator &operator += (size_type i) noexcept { + + col_ += i; + if (col_ >= mptr_->cols()) { + row_ += col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (*this); + } + + inline row_const_iterator &operator -- () noexcept { // --Prefix + + col_ -= 1; + if (col_ < 0) { col_ = mptr_->cols() - 1; row_ -= 1; } + return (*this); + } + inline row_const_iterator operator -- (int) noexcept { // Postfix-- + + const size_type row = row_; + const size_type col = col_; + + col_ -= 1; + if (col_ < 0) { col_ = mptr_->cols() - 1; row_ -= 1; } + return (row_const_iterator (mptr_, row, col)); + } + + inline row_const_iterator &operator -= (int i) noexcept { + + col_ -= i; + if (col_ < 0) { + row_ -= col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (*this); + } + + inline row_const_iterator operator + (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + col_ += i; + if (col_ >= mptr_->cols()) { + row_ += col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (row_const_iterator (mptr_, row, col)); + } + + inline row_const_iterator operator - (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + col_ -= i; + if (col_ < 0) { + row_ -= col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (row_const_iterator (mptr_, row, col)); + } + + inline row_const_iterator operator + (int i) noexcept { + + return (*this + size_type(i)); + } + + inline row_const_iterator operator - (int i) noexcept { + + return (*this - size_type(i)); + } + + friend difference_type + operator - (row_const_iterator lhs, row_const_iterator rhs) noexcept { + + const size_type row_diff = lhs.row_ - rhs.row_; + const size_type col_diff = lhs.col_ - rhs.col_; + + assert(lhs.mptr_ == rhs.mptr); + return (difference_type( + std::abs(row_diff) * rhs.mptr_->cols() - col_diff)); + } + + private: + + const self_t *mptr_ { nullptr }; + size_type row_ { 0 }; + size_type col_ { 0 }; + }; + + // It goes through the matrix row-by-row starting at [0, 0] + // + class row_iterator : public std::random_access_iterator_tag { + + public: + + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using size_type = long; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using difference_type = typename std::vector::difference_type; + + public: + + inline row_iterator () = default; + + inline row_iterator (self_t *m, size_type row = 0, size_type col = 0) + : mptr_ (m), row_ (row), col_(col) { } + + inline bool operator == (const row_iterator &rhs) const { + + return (mptr_ == rhs.mptr_ && + row_ == rhs.row_ && + col_ == rhs.col_); + } + inline bool operator != (const row_iterator &rhs) const { + + return (! (*this == rhs)); + } + inline bool operator > (const row_iterator &rhs) const noexcept { + + return (row_ > rhs.row_ || (row_ == rhs.row_ && col_ > rhs.col_)); + } + inline bool operator >= (const row_iterator &rhs) const noexcept { + + return (row_ > rhs.row_ || (row_ == rhs.row_ && col_ >= rhs.col_)); + } + inline bool operator < (const row_iterator &rhs) const noexcept { + + return (! (*this >= rhs)); + } + inline bool operator <= (const row_iterator &rhs) const noexcept { + + return (! (*this > rhs)); + } + + // Following STL style, this iterator appears as a pointer + // to value_type. + // + inline pointer operator -> () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + inline reference operator * () const noexcept { + + return (mptr_->at(row_, col_)); + } + inline operator pointer () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + + // We are following STL style iterator interface. + // + inline row_iterator &operator ++ () noexcept { // ++Prefix + + col_ += 1; + if (col_ >= mptr_->cols()) { col_ = 0; row_ += 1; } + return (*this); + } + inline row_iterator operator ++ (int) noexcept { // Postfix++ + + const size_type row = row_; + const size_type col = col_; + + col_ += 1; + if (col_ >= mptr_->cols()) { col_ = 0; row_ += 1; } + return (row_iterator (mptr_, row, col)); + } + + inline row_iterator &operator += (size_type i) noexcept { + + col_ += i; + if (col_ >= mptr_->cols()) { + row_ += col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (*this); + } + + inline row_iterator &operator -- () noexcept { // --Prefix + + col_ -= 1; + if (col_ < 0) { col_ = mptr_->cols() - 1; row_ -= 1; } + return (*this); + } + inline row_iterator operator -- (int) noexcept { // Postfix-- + + const size_type row = row_; + const size_type col = col_; + + col_ -= 1; + if (col_ < 0) { col_ = mptr_->cols() - 1; row_ -= 1; } + return (row_iterator (mptr_, row, col)); + } + + inline row_iterator &operator -= (int i) noexcept { + + col_ -= i; + if (col_ < 0) { + row_ -= col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (*this); + } + + inline row_iterator operator + (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + col_ += i; + if (col_ >= mptr_->cols()) { + row_ += col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (row_iterator (mptr_, row, col)); + } + + inline row_iterator operator - (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + col_ -= i; + if (col_ < 0) { + row_ -= col_ / mptr_->cols(); + col_ %= mptr_->cols(); + } + return (row_iterator (mptr_, row, col)); + } + + inline row_iterator operator + (int i) noexcept { + + return (*this + size_type(i)); + } + + inline row_iterator operator - (int i) noexcept { + + return (*this - size_type(i)); + } + + friend difference_type + operator - (row_iterator lhs, row_iterator rhs) noexcept { + + const size_type row_diff = lhs.row_ - rhs.row_; + const size_type col_diff = lhs.col_ - rhs.col_; + + assert(lhs.mptr_ == rhs.mptr); + return (difference_type( + std::abs(row_diff) * rhs.mptr_->cols() - col_diff)); + } + + private: + + self_t *mptr_ { nullptr }; + size_type row_ { 0 }; + size_type col_ { 0 }; + }; + + class col_iterator; + class col_const_iterator : public std::random_access_iterator_tag { + + public: + + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using size_type = long; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using difference_type = typename std::vector::difference_type; + + public: + + inline col_const_iterator () = default; + + inline col_const_iterator(const self_t *m, + size_type row = 0, + size_type col = 0) + : mptr_ (m), row_ (row), col_(col) { } + + inline bool operator == (const col_const_iterator &rhs) const { + + return (mptr_ == rhs.mptr_ && + row_ == rhs.row_ && + col_ == rhs.col_); + } + inline bool operator != (const col_const_iterator &rhs) const { + + return (! (*this == rhs)); + } + inline bool + operator > (const col_const_iterator &rhs) const noexcept { + + return (col_ > rhs.col_ || (col_ == rhs.col_ && row_ > rhs.row_)); + } + inline bool + operator >= (const col_const_iterator &rhs) const noexcept { + + return (col_ > rhs.col_ || (col_ == rhs.col_ && row_ >= rhs.row_)); + } + inline bool + operator < (const col_const_iterator &rhs) const noexcept { + + return (! (*this >= rhs)); + } + inline bool + operator <= (const col_const_iterator &rhs) const noexcept { + + return (! (*this > rhs)); + } + + // Following STL style, this iterator appears as a pointer + // to value_type. + // + inline const_pointer operator -> () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + inline const_reference operator * () const noexcept { + + return (mptr_->at(row_, col_)); + } + inline operator const_pointer () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + + // We are following STL style iterator interface. + // + inline col_const_iterator &operator ++ () noexcept { // ++Prefix + + row_ += 1; + if (row_ >= mptr_->rows()) { row_ = 0; col_ += 1; } + return (*this); + } + inline col_const_iterator operator ++ (int) noexcept { // Postfix++ + + const size_type row = row_; + const size_type col = col_; + + row_ += 1; + if (row_ >= mptr_->rows()) { row_ = 0; col_ += 1; } + return (col_const_iterator (mptr_, row, col)); + } + + inline col_const_iterator &operator += (size_type i) noexcept { + + row_ += i; + if (row_ >= mptr_->rows()) { + col_ += row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (*this); + } + + inline col_const_iterator &operator -- () noexcept { // --Prefix + + row_ -= 1; + if (row_ < 0) { row_ = mptr_->rows() - 1; col_ -= 1; } + return (*this); + } + inline col_const_iterator operator -- (int) noexcept { // Postfix-- + + const size_type row = row_; + const size_type col = col_; + + row_ -= 1; + if (row_ < 0) { row_ = mptr_->rows() - 1; col_ -= 1; } + return (col_const_iterator (mptr_, row, col)); + } + + inline col_const_iterator &operator -= (int i) noexcept { + + row_ -= i; + if (row_ < 0) { + col_ -= row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (*this); + } + + inline col_const_iterator operator + (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + row_ += i; + if (row_ >= mptr_->rows()) { + col_ += row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (col_const_iterator (mptr_, row, col)); + } + + inline col_const_iterator operator - (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + row_ -= i; + if (row_ < 0) { + col_ -= row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (col_const_iterator (mptr_, row, col)); + } + + inline col_const_iterator operator + (int i) noexcept { + + return (*this + size_type(i)); + } + + inline col_const_iterator operator - (int i) noexcept { + + return (*this - size_type(i)); + } + + friend difference_type + operator - (col_const_iterator lhs, col_const_iterator rhs) noexcept { + + const size_type row_diff = lhs.row_ - rhs.row_; + const size_type col_diff = lhs.col_ - rhs.col_; + + assert(lhs.mptr_ == rhs.mptr); + return (difference_type( + std::abs(row_diff) * rhs.mptr_->cols() - col_diff)); + } + + private: + + const self_t *mptr_ { nullptr }; + size_type row_ { 0 }; + size_type col_ { 0 }; + }; + + // It goes through the matrix row-by-row starting at [0, 0] + // + class col_iterator : public std::random_access_iterator_tag { + + public: + + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using size_type = long; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using difference_type = typename std::vector::difference_type; + + public: + + inline col_iterator() = default; + + inline col_iterator (self_t *m, size_type row = 0, size_type col = 0) + : mptr_ (m), row_ (row), col_(col) { } + + inline bool operator == (const col_iterator &rhs) const { + + return (mptr_ == rhs.mptr_ && + row_ == rhs.row_ && + col_ == rhs.col_); + } + inline bool operator != (const col_iterator &rhs) const { + + return (! (*this == rhs)); + } + inline bool operator > (const col_iterator &rhs) const noexcept { + + return (col_ > rhs.col_ || (col_ == rhs.col_ && row_ > rhs.row_)); + } + inline bool operator >= (const col_iterator &rhs) const noexcept { + + return (col_ > rhs.col_ || (col_ == rhs.col_ && row_ >= rhs.row_)); + } + inline bool operator < (const col_iterator &rhs) const noexcept { + + return (! (*this >= rhs)); + } + inline bool operator <= (const col_iterator &rhs) const noexcept { + + return (! (*this > rhs)); + } + + // Following STL style, this iterator appears as a pointer + // to value_type. + // + inline pointer operator -> () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + inline reference operator * () const noexcept { + + return (mptr_->at(row_, col_)); + } + inline operator pointer () const noexcept { + + return (&(mptr_->at(row_, col_))); + } + + // We are following STL style iterator interface. + // + inline col_iterator &operator ++ () noexcept { // ++Prefix + + row_ += 1; + if (row_ >= mptr_->rows()) { row_ = 0; col_ += 1; } + return (*this); + } + inline col_iterator operator ++ (int) noexcept { // Postfix++ + + const size_type row = row_; + const size_type col = col_; + + row_ += 1; + if (row_ >= mptr_->rows()) { row_ = 0; col_ += 1; } + return (col_iterator (mptr_, row, col)); + } + + inline col_iterator &operator += (size_type i) noexcept { + + row_ += i; + if (row_ >= mptr_->rows()) { + col_ += row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (*this); + } + + inline col_iterator &operator -- () noexcept { // --Prefix + + row_ -= 1; + if (row_ < 0) { row_ = mptr_->rows() - 1; col_ -= 1; } + return (*this); + } + inline col_iterator operator -- (int) noexcept { // Postfix-- + + const size_type row = row_; + const size_type col = col_; + + row_ -= 1; + if (row_ < 0) { row_ = mptr_->rows() - 1; col_ -= 1; } + return (col_iterator (mptr_, row, col)); + } + + inline col_iterator &operator -= (int i) noexcept { + + row_ -= i; + if (row_ < 0) { + col_ -= row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (*this); + } + + inline col_iterator operator + (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + row_ += i; + if (row_ >= mptr_->rows()) { + col_ += row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (col_iterator (mptr_, row, col)); + } + + inline col_iterator operator - (size_type i) noexcept { + + const size_type row = row_; + const size_type col = col_; + + row_ -= i; + if (row_ < 0) { + col_ -= row_ / mptr_->rows(); + row_ %= mptr_->rows(); + } + return (col_iterator (mptr_, row, col)); + } + + inline col_iterator operator + (int i) noexcept { + + return (*this + size_type(i)); + } + + inline col_iterator operator - (int i) noexcept { + + return (*this - size_type(i)); + } + + friend difference_type + operator - (col_iterator lhs, col_iterator rhs) noexcept { + + const size_type row_diff = lhs.row_ - rhs.row_; + const size_type col_diff = lhs.col_ - rhs.col_; + + assert(lhs.mptr_ == rhs.mptr); + return (difference_type( + std::abs(row_diff) * rhs.mptr_->cols() - col_diff)); + } + + private: + + self_t *mptr_ { nullptr }; + size_type row_ { 0 }; + size_type col_ { 0 }; + }; + +public: + + // Forwards + // + inline row_iterator row_begin() noexcept { + + return (row_iterator(this, 0, 0)); + } + inline row_const_iterator row_cbegin() const noexcept { + + return (row_const_iterator(this, 0, 0)); + } + inline row_iterator row_end() noexcept { + + return (row_iterator(this, rows(), cols())); + } + inline row_const_iterator row_cend() const noexcept { + + return (row_const_iterator(this, rows(), cols())); + } + + inline col_iterator col_begin() noexcept { + + return (col_iterator(this, 0, 0)); + } + inline col_const_iterator col_cbegin() const noexcept { + + return (col_const_iterator(this, 0, 0)); + } + inline col_iterator col_end() noexcept { + + return (col_iterator(this, rows(), cols())); + } + inline col_const_iterator col_cend() const noexcept { + + return (col_const_iterator(this, rows(), cols())); + } + + using reverse_row_iterator = std::reverse_iterator; + using reverse_row_const_iterator = + std::reverse_iterator; + using reverse_col_iterator = std::reverse_iterator; + using reverse_col_const_iterator = + std::reverse_iterator; + + // Reverses + // + inline reverse_row_iterator row_rbegin() noexcept { + + return (std::make_reverse_iterator(row_end())); + } + inline reverse_row_const_iterator row_crbegin() const noexcept { + + return (std::make_reverse_iterator(row_cend())); + } + inline reverse_row_iterator row_rend() noexcept { + + return (std::make_reverse_iterator(row_begin())); + } + inline reverse_row_const_iterator row_crend() const noexcept { + + return (std::make_reverse_iterator(row_cbegin())); + } + + inline reverse_col_iterator col_rbegin() noexcept { + + return (std::make_reverse_iterator(col_end())); + } + inline reverse_col_const_iterator col_crbegin() const noexcept { + + return (std::make_reverse_iterator(col_cend())); + } + inline reverse_col_iterator col_rend() noexcept { + + return (std::make_reverse_iterator(col_begin())); + } + inline reverse_col_const_iterator col_crend() const noexcept { + + return (std::make_reverse_iterator(col_cbegin())); + } }; } // namespace hmdf // ---------------------------------------------------------------------------- -#ifdef HMDF_DO_NOT_INCLUDE_TCC_FILES +#ifndef HMDF_DO_NOT_INCLUDE_TCC_FILES # include #endif // HMDF_DO_NOT_INCLUDE_TCC_FILES diff --git a/include/DataFrame/Utils/Matrix.tcc b/include/DataFrame/Utils/Matrix.tcc index ce9a6df8..f6c03e2d 100644 --- a/include/DataFrame/Utils/Matrix.tcc +++ b/include/DataFrame/Utils/Matrix.tcc @@ -63,7 +63,7 @@ Matrix::swap(Matrix &rhs) noexcept { template bool -Matrix::empty() noexcept { +Matrix::empty() const noexcept { return (rows_ == 0 && cols_ == 0); } @@ -160,10 +160,16 @@ template void Matrix::set_row(I row_data, size_type row) { - for (size_type c = 0; c < columns(); ++c) + for (size_type c = 0; c < cols(); ++c) at(row, c) = *row_data++; } +// ---------------------------------------------------------------------------- + +template +constexpr matrix_orient +Matrix::orientation() { return (MO); } + } // namespace hmdf // ---------------------------------------------------------------------------- diff --git a/src/CommonMakefile.mk b/src/CommonMakefile.mk index 73ac4bb9..4d808b2f 100644 --- a/src/CommonMakefile.mk +++ b/src/CommonMakefile.mk @@ -79,7 +79,9 @@ HEADERS = $(LOCAL_INCLUDE_DIR)/DataFrame/Vectors/HeteroVector.h \ $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/FixedSizePriorityQueue.h \ $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/AlignedAllocator.h \ $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/FixedSizeAllocator.h \ - $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/Endianness.h + $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/Endianness.h \ + $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/Matrix.h \ + $(LOCAL_INCLUDE_DIR)/DataFrame/Utils/Matrix.tcc LIB_NAME = DataFrame TARGET_LIB = $(LOCAL_LIB_DIR)/lib$(LIB_NAME).a @@ -101,7 +103,8 @@ TARGETS += $(TARGET_LIB) \ $(LOCAL_BIN_DIR)/vector_ptr_view_tester \ $(LOCAL_BIN_DIR)/meta_prog_tester \ $(LOCAL_BIN_DIR)/date_time_tester \ - $(LOCAL_BIN_DIR)/gen_rand_tester + $(LOCAL_BIN_DIR)/gen_rand_tester \ + $(LOCAL_BIN_DIR)/matrix_tester # ----------------------------------------------------------------------------- @@ -222,6 +225,10 @@ GEN_RAND_TESTER_OBJ = $(LOCAL_OBJ_DIR)/gen_rand_tester.o $(LOCAL_BIN_DIR)/gen_rand_tester: $(TARGET_LIB) $(GEN_RAND_TESTER_OBJ) $(CXX) -o $@ $(GEN_RAND_TESTER_OBJ) $(LIBS) +MATRIX_TESTER_OBJ = $(LOCAL_OBJ_DIR)/matrix_tester.o +$(LOCAL_BIN_DIR)/matrix_tester: $(TARGET_LIB) $(MATRIX_TESTER_OBJ) + $(CXX) -o $@ $(MATRIX_TESTER_OBJ) $(LIBS) + # ----------------------------------------------------------------------------- depend: @@ -236,7 +243,7 @@ clean: $(HELLO_WORLD_OBJ) $(DATAFRAME_PERFORMANCE_2_OBJ) \ $(DATAFRAME_THREAD_SAFTY_OBJ) $(DATAFRAME_TESTER_SCHEMA_OBJ) \ $(ALLOCATOR_TESTER_OBJ) $(LINKEDIN_BENCHMARK_OBJ) \ - $(DATAFRAME_READ_LARGE_FILE_OBJ) + $(DATAFRAME_READ_LARGE_FILE_OBJ) $(MATRIX_TESTER_OBJ) clobber: rm -f $(LIB_OBJS) $(TARGETS) $(DATAFRAME_TESTER_OBJ) $(VECTORS_TESTER_OBJ) \ @@ -248,7 +255,7 @@ clobber: $(ALLOCATOR_TESTER_OBJ) $(DATAFRAME_PERFORMANCE_OBJ) \ $(DATAFRAME_PERFORMANCE_2_OBJ) \ $(META_PROG_OBJ) $(LINKEDIN_BENCHMARK_OBJ) \ - $(DATAFRAME_READ_LARGE_FILE_OBJ) + $(DATAFRAME_READ_LARGE_FILE_OBJ) $(MATRIX_TESTER_OBJ) install_lib: cp -pf $(TARGET_LIB) $(PROJECT_LIB_DIR)/. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f312d6f6..0f6bdd0f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -52,6 +52,13 @@ if(MSVC) set_tests_properties(vectors_tester PROPERTIES DISABLED TRUE) endif() +add_executable(matrix_tester matrix_tester.cc) +target_link_libraries(matrix_tester PRIVATE DataFrame) +target_compile_options(matrix_tester + PRIVATE $<$:/bigobj> +) +add_test(NAME matrix_tester COMMAND matrix_tester) + if(NOT MSVC) # MSVC compiler craps out on immediately executing lambdas add_executable(allocator_tester allocator_tester.cc) diff --git a/test/matrix_tester.cc b/test/matrix_tester.cc new file mode 100644 index 00000000..5ed370e0 --- /dev/null +++ b/test/matrix_tester.cc @@ -0,0 +1,79 @@ +/* +Copyright (c) 2019-2026, Hossein Moein +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Hossein Moein and/or the DataFrame nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Hossein Moein BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include +#include + +using namespace hmdf; + +// ----------------------------------------------------------------------------- + +using row_mat_t = Matrix; +using col_mat_t = Matrix; + +static constexpr std::size_t ROWS = 5; +static constexpr std::size_t COLS = 6; + +// ----------------------------------------------------------------------------- + +int main(int, char *[]) { + + row_mat_t row_mat { ROWS, COLS }; + col_mat_t col_mat { ROWS, COLS }; + std::size_t value { 0 }; + + for (std::size_t r = 0; r < row_mat.rows(); ++r) + for (std::size_t c = 0; c < row_mat.cols(); ++c) + row_mat(r, c) = value++; + + value = 0; + for (std::size_t c = 0; c < col_mat.cols(); ++c) + for (std::size_t r = 0; r < col_mat.rows(); ++r) + col_mat(r, c) = value++; + + value = 0; + for (std::size_t r = 0; r < row_mat.rows(); ++r) + for (std::size_t c = 0; c < row_mat.cols(); ++c) + assert(row_mat(r, c) == value++); + + value = 0; + for (std::size_t c = 0; c < col_mat.cols(); ++c) + for (std::size_t r = 0; r < col_mat.rows(); ++r) + assert(col_mat(r, c) == value++); + + return (0); +} + +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode:C++ +// tab-width:4 +// c-basic-offset:4 +// End: