Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynMat.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
50#ifndef TPL_DYNMAT_H
51#define TPL_DYNMAT_H
52
53#include <ah-errors.H>
54#include <ahDry.H>
55#include <tpl_dynArray.H>
56
57namespace Aleph {
58
116template <typename T>
118 : public LocateFunctions<DynMatrix<T>, T>,
119 public FunctionalMethods<DynMatrix<T>, T>
120{
121 size_t n = 0;
122 size_t m = 0;
123
125
127
128 [[nodiscard]] const T & read_array_entry(const size_t i) const noexcept
129 {
130 T * entry_ptr = array_ptr->test(i);
131 return entry_ptr == nullptr ? default_value : *entry_ptr;
132 }
133
134 T & write_array_entry(const size_t i, const T & data)
135 {
136 T & ref = array_ptr->touch(i) = data;
137 return ref;
138 }
139
140 T & write_array_entry(const size_t i, T && data)
141 {
142 T & ref = array_ptr->touch(i) = std::move(data);
143 return ref;
144 }
145
146 [[nodiscard]] constexpr size_t get_index(const size_t i,
147 const size_t j) const noexcept
148 {
149 return i * m + j;
150 }
151
152 void check_indices(const size_t i, const size_t j) const
153 {
155 << "DynMatrix: row index " << i << " out of range [0, " << n << ")";
157 << "DynMatrix: column index " << j << " out of range [0, " << m << ")";
158 }
159
160public:
161
164
166 using Item_Type = T;
167
169 using Key_Type = T;
170
181 void set_default_initial_value(const T & value)
182 {
183 default_value = value;
184 if (array_ptr)
185 array_ptr->set_default_initial_value(value);
186 }
187
193 {
194 return default_value;
195 }
196
204 void swap(DynMatrix & mat) noexcept
205 {
206 std::swap(n, mat.n);
207 std::swap(m, mat.m);
208 std::swap(default_value, mat.default_value);
209 std::swap(array_ptr, mat.array_ptr);
210 }
211
225 void set_dimension(const size_t num_rows, const size_t num_cols)
226 {
227 delete array_ptr;
228
229 n = num_rows;
230 m = num_cols;
231 size_t d, s, b;
232 const size_t N = n * m;
234
235 array_ptr = new DynArray<T>(d, s, b);
236 array_ptr->set_default_initial_value(default_value);
237 }
238
249 void allocate()
250 {
251 array_ptr->reserve(n * m);
252 }
253
266 DynMatrix(const size_t num_rows, const size_t num_cols, const T & zero = T())
268 {
270 << "DynMatrix dimensions must be > 0";
271 set_dimension(n, m);
272 }
273
283
287 {
288 delete array_ptr;
289 }
290
300 : n(mat.n), m(mat.m), array_ptr(nullptr), default_value(mat.default_value)
301 {
302 if (mat.array_ptr)
303 {
304 set_dimension(n, m);
305 *array_ptr = *mat.array_ptr;
306 }
307 }
308
317 : n(mat.n),
318 m(mat.m),
319 array_ptr(mat.array_ptr),
320 default_value(std::move(mat.default_value))
321 {
322 mat.n = mat.m = 0;
323 mat.array_ptr = nullptr;
324 mat.default_value = T();
325 }
326
337 {
338 if (this == &mat)
339 return *this;
340
342
343 if (n != mat.n || m != mat.m)
344 set_dimension(mat.n, mat.m);
345
346 if (mat.array_ptr)
347 array_ptr->copy_array(*mat.array_ptr);
348
349 return *this;
350 }
351
360 {
361 if (this == &mat)
362 return *this;
363
364 delete array_ptr;
365
366 n = mat.n;
367 m = mat.m;
368 default_value = std::move(mat.default_value);
369 array_ptr = mat.array_ptr;
370
371 mat.n = mat.m = 0;
372 mat.array_ptr = nullptr;
373 mat.default_value = T();
374
375 return *this;
376 }
377
386 [[nodiscard]] bool operator == (const DynMatrix<T> & mat) const
387 {
388 if (n != mat.n || m != mat.m)
389 return false;
390
391 const size_t N = n * m;
392 for (size_t i = 0; i < N; ++i)
393 if (read_array_entry(i) != mat.read_array_entry(i))
394 return false;
395
396 return true;
397 }
398
404 [[nodiscard]] bool operator != (const DynMatrix<T> & mat) const
405 {
406 return !(*this == mat);
407 }
408
413 [[nodiscard]] constexpr size_t rows() const noexcept { return n; }
414
419 [[nodiscard]] constexpr size_t cols() const noexcept { return m; }
420
425 [[nodiscard]] constexpr size_t size() const noexcept { return n * m; }
426
431 [[nodiscard]] constexpr bool is_square() const noexcept { return n == m; }
432
437 [[nodiscard]] constexpr bool is_empty() const noexcept { return n == 0 || m == 0; }
438
452 [[nodiscard]] const T & read(const size_t i, const size_t j) const
453 {
454 check_indices(i, j);
455 return read_array_entry(get_index(i, j));
456 }
457
466 [[nodiscard]] const T & read_ne(const size_t i, const size_t j) const noexcept
467 {
468 return read_array_entry(get_index(i, j));
469 }
470
486 T & write(const size_t i, const size_t j, const T & data)
487 {
488 check_indices(i, j);
489 return write_array_entry(get_index(i, j), data);
490 }
491
493 T & write(const size_t i, const size_t j, T && data)
494 {
495 check_indices(i, j);
496 return write_array_entry(get_index(i, j), std::move(data));
497 }
498
514 [[nodiscard]] T & access(const size_t i, const size_t j)
515 {
516 return array_ptr->access(get_index(i, j));
517 }
518
525 [[nodiscard]] const T & access(const size_t i, const size_t j) const
526 {
527 return array_ptr->access(get_index(i, j));
528 }
529
538 [[nodiscard]] T & operator () (const size_t i, const size_t j)
539 {
540 return access(i, j);
541 }
542
549 [[nodiscard]] const T & operator () (const size_t i, const size_t j) const
550 {
551 return access(i, j);
552 }
553
562 void fill(const T & value)
563 {
564 allocate();
565 for (size_t idx = 0; idx < n * m; ++idx)
566 array_ptr->access(idx) = value;
567 }
568
578 {
579 DynMatrix<T> result(m, n, default_value);
580 for (size_t i = 0; i < n; ++i)
581 for (size_t j = 0; j < m; ++j)
582 {
583 const T & val = read_array_entry(get_index(i, j));
584 if (&val != &default_value) // Only copy non-default entries
585 result.write(j, i, val);
586 }
587 return result;
588 }
589
599 {
600 const DynMatrix * mat_ptr = nullptr;
601 size_t curr_idx = 0;
602
603 public:
604
607
613 : mat_ptr(&mat), curr_idx(0) {}
614
620 {
621 return curr_idx < mat_ptr->size();
622 }
623
629 {
631 }
632
638 [[nodiscard]] const T & get_curr() const
639 {
641 << "DynMatrix::Iterator: no current element";
642 return get_curr_ne();
643 }
644
648
653 void next()
654 {
656 << "DynMatrix::Iterator: no more elements";
657 next_ne();
658 }
659
665 {
666 return curr_idx / mat_ptr->m;
667 }
668
674 {
675 return curr_idx % mat_ptr->m;
676 }
677
680 void reset() noexcept { curr_idx = 0; }
681 };
682
687 [[nodiscard]] Iterator get_it() const { return Iterator(*this); }
688
698 template <class Operation>
700 {
701 for (size_t i = 0; i < n * m; ++i)
703 return false;
704 return true;
705 }
706
708 template <class Operation>
710 {
711 return const_cast<const DynMatrix*>(this)->traverse(operation);
712 }
713
715 template <class Operation>
717 {
719 }
720
722 template <class Operation>
724 {
726 }
727
743 template <class Operation>
745 {
746 if (array_ptr == nullptr)
747 return true;
748
749 const size_t total = n * m;
750 for (size_t idx = 0; idx < total; ++idx)
751 if (T *entry = array_ptr->test(idx))
752 {
753 if (!operation(*entry))
754 return false;
755 }
756
757 return true;
758 }
759
761 template <class Operation>
763 {
764 if (array_ptr == nullptr)
765 return true;
766
767 const size_t total = n * m;
768 for (size_t idx = 0; idx < total; ++idx)
769 if (const T *entry = array_ptr->test(idx))
770 {
771 if (!operation(*entry))
772 return false;
773 }
774
775 return true;
776 }
777};
778
779} // end namespace Aleph
780
781#endif // TPL_DYNMAT_H
Exception handling system with formatted messages for Aleph-w.
#define ah_overflow_error_unless(C)
Throws std::overflow_error if condition does NOT hold.
Definition ah-errors.H:479
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Definition ah-errors.H:639
DRY (Don't Repeat Yourself) utilities and macros.
static void compute_sizes(const size_t n, size_t &d, size_t &s, size_t &b) noexcept
Given a dimension n, it proposes values for the directory, segment and block sizes.
Iterator for traversing matrix elements.
Definition tpl_dynMat.H:599
Iterator(const DynMatrix< T > &mat) noexcept
Construct an iterator for a matrix.
Definition tpl_dynMat.H:612
size_t get_row() const noexcept
Get the current row index.
Definition tpl_dynMat.H:664
const T & get_curr() const
Get the current element.
Definition tpl_dynMat.H:638
const T & get_curr_ne() const noexcept
Get the current element without bounds checking.
Definition tpl_dynMat.H:628
const DynMatrix * mat_ptr
Definition tpl_dynMat.H:600
void next_ne() noexcept
Advance to the next element without bounds checking.
Definition tpl_dynMat.H:647
bool has_curr() const noexcept
Check if iterator has a current element.
Definition tpl_dynMat.H:619
size_t get_col() const noexcept
Get the current column index.
Definition tpl_dynMat.H:673
void next()
Advance to the next element.
Definition tpl_dynMat.H:653
void reset() noexcept
Reset iterator to the beginning.
Definition tpl_dynMat.H:680
Dynamic matrix with sparse storage.
Definition tpl_dynMat.H:120
bool traverse_allocated(Operation &&operation)
Traverse entries in allocated memory blocks.
Definition tpl_dynMat.H:744
size_t n
Number of rows.
Definition tpl_dynMat.H:121
T & write(const size_t i, const size_t j, T &&data)
Definition tpl_dynMat.H:493
void set_dimension(const size_t num_rows, const size_t num_cols)
Change the matrix dimensions.
Definition tpl_dynMat.H:225
bool operator==(const DynMatrix< T > &mat) const
Equality comparison.
Definition tpl_dynMat.H:386
DynMatrix() noexcept=default
Default constructor - creates an invalid matrix.
T & write_array_entry(const size_t i, const T &data)
Definition tpl_dynMat.H:134
DynArray< T > * array_ptr
Definition tpl_dynMat.H:124
DynMatrix(DynMatrix< T > &&mat) noexcept
Move constructor.
Definition tpl_dynMat.H:316
T & operator()(const size_t i, const size_t j)
Subscript operator for allocated entries.
Definition tpl_dynMat.H:538
bool operator!=(const DynMatrix< T > &mat) const
Inequality comparison.
Definition tpl_dynMat.H:404
const T & read(const size_t i, const size_t j) const
Read the entry at position (i, j).
Definition tpl_dynMat.H:452
bool traverse(Operation &operation) const
Traverse all elements in row-major order.
Definition tpl_dynMat.H:699
constexpr bool is_empty() const noexcept
Check if the matrix is empty (uninitialized).
Definition tpl_dynMat.H:437
constexpr size_t cols() const noexcept
Get the number of columns.
Definition tpl_dynMat.H:419
Iterator get_it() const
Get an iterator positioned at the first element.
Definition tpl_dynMat.H:687
void swap(DynMatrix &mat) noexcept
Swap the contents of this matrix with another.
Definition tpl_dynMat.H:204
DynMatrix(const DynMatrix< T > &mat)
Copy constructor.
Definition tpl_dynMat.H:299
T & write(const size_t i, const size_t j, const T &data)
Write a value to position (i, j).
Definition tpl_dynMat.H:486
void check_indices(const size_t i, const size_t j) const
Definition tpl_dynMat.H:152
void allocate()
Pre-allocate memory for the entire matrix.
Definition tpl_dynMat.H:249
bool traverse(Operation &operation)
Definition tpl_dynMat.H:709
bool traverse_allocated(Operation &&operation) const
Definition tpl_dynMat.H:762
const T & get_default_value() const noexcept
Get the default value for unwritten entries.
Definition tpl_dynMat.H:192
constexpr size_t rows() const noexcept
Get the number of rows.
Definition tpl_dynMat.H:413
void set_default_initial_value(const T &value)
Set the default value for unwritten entries.
Definition tpl_dynMat.H:181
const T & read_ne(const size_t i, const size_t j) const noexcept
Read entry without bounds checking.
Definition tpl_dynMat.H:466
constexpr size_t size() const noexcept
Get the total number of entries.
Definition tpl_dynMat.H:425
bool traverse(Operation &&operation)
Definition tpl_dynMat.H:723
T Key_Type
Alias for Item_Type, required by functional mixins.
Definition tpl_dynMat.H:169
constexpr bool is_square() const noexcept
Check if the matrix is square.
Definition tpl_dynMat.H:431
T & access(const size_t i, const size_t j)
Direct access to an allocated entry.
Definition tpl_dynMat.H:514
DynMatrix(const size_t num_rows, const size_t num_cols, const T &zero=T())
Construct a matrix with specified dimensions.
Definition tpl_dynMat.H:266
DynMatrix< T > transpose() const
Create a transposed copy of the matrix.
Definition tpl_dynMat.H:577
DynMatrix< T > & operator=(const DynMatrix< T > &mat)
Copy assignment operator.
Definition tpl_dynMat.H:336
T Item_Type
The type of elements stored in the matrix.
Definition tpl_dynMat.H:166
void fill(const T &value)
Fill all entries with a value.
Definition tpl_dynMat.H:562
const T & read_array_entry(const size_t i) const noexcept
Definition tpl_dynMat.H:128
size_t m
Number of columns.
Definition tpl_dynMat.H:122
T & write_array_entry(const size_t i, T &&data)
Definition tpl_dynMat.H:140
bool traverse(Operation &&operation) const
Definition tpl_dynMat.H:716
constexpr size_t get_index(const size_t i, const size_t j) const noexcept
Definition tpl_dynMat.H:146
const T & access(const size_t i, const size_t j) const
Direct const access to an allocated entry.
Definition tpl_dynMat.H:525
Common methods to the Aleph-w ( ) containers.
Definition ah-dry.H:548
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:904
Common sequential searching methods on containers.
Definition ah-dry.H:164
#define N
Definition fib.C:294
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
Lazy and scalable dynamic array implementation.