libsemigroups  v3.6.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
matrix-class.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2020-2026 James D. Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// TODO(1) there're no complete set of init methods for matrices
20
21#ifndef LIBSEMIGROUPS_MATRIX_CLASS_HPP_
22#define LIBSEMIGROUPS_MATRIX_CLASS_HPP_
23
24#include <algorithm> // for min
25#include <array> // for array
26#include <cstddef> // for size_t
27#include <initializer_list> // for initializer_list
28#include <iosfwd> // for ostringstream
29#include <iterator> // for distance
30#include <string> // for string
31#include <tuple> // for tie
32#include <type_traits> // for false_type, is_signed, true_type
33#include <unordered_map> // for unordered_map
34#include <unordered_set> // for unordered_set
35#include <utility> // for forward, make_pair, pair
36#include <vector> // for vector
37
38#include "adapters.hpp" // for Degree
39#include "config.hpp" // for LIBSEMIGROUPS_PARSED_BY_DOXYGEN
40#include "constants.hpp" // for POSITIVE_INFINITY
41#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
42#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
43#include "is-matrix.hpp" // for IsMatrix
44#include "matrix-view.hpp" // for RowView
45
46#include "detail/containers.hpp" // for StaticVector1
47#include "detail/matrix-common.hpp" // for entry_repr
48#include "detail/matrix-exceptions.hpp" // for throw_if...
49#include "detail/string.hpp" // for detail::to_string
50
51namespace libsemigroups {
52
123
125 // StaticMatrix with compile time semiring arithmetic
127
161 template <typename PlusOp,
162 typename ProdOp,
163 typename ZeroOp,
164 typename OneOp,
165 size_t R,
166 size_t C,
167 typename Scalar>
169 : public detail::
170 MatrixStaticArithmetic<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>,
171 public detail::MatrixCommon<
172 std::array<Scalar, R * C>,
173 StaticMatrix<PlusOp, ProdOp, ZeroOp, OneOp, R, C, Scalar>,
174 StaticRowView<PlusOp, ProdOp, ZeroOp, OneOp, C, Scalar>> {
176 // StaticMatrix - Aliases - private
178
179 using MatrixCommon = ::libsemigroups::detail::MatrixCommon<
183 friend MatrixCommon;
184
185 public:
187 // StaticMatrix - Aliases - public
189
191 using scalar_type = typename MatrixCommon::scalar_type;
192
194 using scalar_reference = typename MatrixCommon::scalar_reference;
195
197 // clang-format off
198 // NOLINTNEXTLINE(whitespace/line_length)
199 using scalar_const_reference = typename MatrixCommon::scalar_const_reference;
200 // clang-format on
201
204
207
209 using Plus = PlusOp;
210
212 using Prod = ProdOp;
213
215 using Zero = ZeroOp;
216
218 using One = OneOp;
219
221 using iterator = typename MatrixCommon::iterator;
222
224 using const_iterator = typename MatrixCommon::const_iterator;
225
227 static constexpr size_t nr_rows = R;
228
230 static constexpr size_t nr_cols = C;
231
233 // StaticMatrix - Constructors + destructor - public
235
253
273 explicit StaticMatrix(
275 : MatrixCommon(m) {}
276
290 : MatrixCommon(m) {}
291
309 explicit StaticMatrix(RowView const& rv) : MatrixCommon(rv) {
310 static_assert(
311 R == 1,
312 "cannot construct Matrix with more than one row from RowView!");
313 }
314
318 StaticMatrix() = default;
319
323 StaticMatrix(StaticMatrix const&) = default;
324
329
334
339
340 ~StaticMatrix() = default;
341
342#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
343 // For uniformity of interface, the args do nothing
344 StaticMatrix(size_t r, size_t c);
345
346 // For uniformity of interface, the first arg does nothing
347 StaticMatrix(void const* ptr, std::initializer_list<scalar_type> const& c)
348 : StaticMatrix(c) {
349 (void) ptr;
350 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
351 }
352
353 // For uniformity of interface, the first arg does nothing
355 void const* ptr,
357 : StaticMatrix(m) {
358 (void) ptr;
359 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
360 }
361
362 // For uniformity of interface, the first arg does nothing
363 explicit StaticMatrix(void const* ptr, RowView const& rv)
364 : StaticMatrix(rv) {
365 (void) ptr;
366 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
367 }
368
369 // For uniformity of interface, no arg used for anything
370 StaticMatrix(void const* ptr, size_t r, size_t c) : StaticMatrix(r, c) {
371 (void) ptr;
372 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
373 }
374 static StaticMatrix one(size_t n);
375 static StaticMatrix one(void const* ptr, size_t n = 0);
376#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
377
379 // StaticMatrix - member function aliases - public
381#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
400 scalar_reference operator()(size_t r, size_t c);
401
415 scalar_reference at(size_t r, size_t c);
416
435 scalar_const_reference operator()(size_t r, size_t c) const;
436
450 scalar_const_reference at(size_t r, size_t c) const;
451
468 iterator begin() noexcept;
469
485
503 const_iterator cbegin() const noexcept;
504
524
538 bool operator==(StaticMatrix const& that) const;
539
541 bool operator==(RowView const& that) const;
542
554 bool operator!=(StaticMatrix const& that) const;
555
557 bool operator!=(RowView const& that) const;
558
572 bool operator<(StaticMatrix const& that) const;
573
575 bool operator<(RowView const& that) const;
576
590 bool operator>(StaticMatrix const& that) const;
591
608
620 size_t number_of_rows() const noexcept;
621
633 size_t number_of_cols() const noexcept;
634
652
669 StaticMatrix operator+(StaticMatrix const& that);
670
688
691
707 void operator+=(StaticMatrix const& that);
708
710 void operator+=(RowView const& that);
711
723 void operator+=(scalar_type a);
724
743
762 StaticMatrix operator*(StaticMatrix const& that);
763
775 void operator*=(scalar_type a);
776
794 StaticMatrix const& y);
795
813 void product_inplace(StaticMatrix const& x, StaticMatrix const& y);
814
830 RowView row_no_checks(size_t i) const;
831
842 RowView row(size_t i) const;
843
857 template <typename T>
858 void rows(T& x) const;
859
872 void swap(StaticMatrix& that) noexcept;
873
886 void transpose();
887
903
915 static StaticMatrix one() const;
916
930 size_t hash_value() const;
931
946 template <typename U>
947 bool operator<=(U const& that) const;
948
963 template <typename U>
964 bool operator>=(U const& that) const;
965
979
994
1005 scalar_type scalar_zero() const noexcept;
1006
1017 scalar_type scalar_one() const noexcept;
1018
1030 semiring_type const* semiring() const noexcept;
1031
1032#else
1033 using MatrixCommon::at;
1034 using MatrixCommon::begin;
1035 using MatrixCommon::cbegin;
1036 using MatrixCommon::cend;
1037 using MatrixCommon::coords;
1038 using MatrixCommon::end;
1039 using MatrixCommon::hash_value;
1040 using MatrixCommon::number_of_cols;
1041 using MatrixCommon::number_of_rows;
1042 using MatrixCommon::one;
1043 using MatrixCommon::operator!=;
1044 using MatrixCommon::operator();
1045 using MatrixCommon::operator*;
1046 using MatrixCommon::operator*=;
1047 using MatrixCommon::operator+;
1048 using MatrixCommon::operator+=;
1049 using MatrixCommon::operator<; // NOLINT(whitespace/operators)
1050 using MatrixCommon::operator<=;
1051 using MatrixCommon::operator==;
1052 using MatrixCommon::operator>; // NOLINT(whitespace/operators)
1053 using MatrixCommon::operator>=;
1054 using MatrixCommon::product_inplace_no_checks;
1055 using MatrixCommon::row;
1056 using MatrixCommon::row_no_checks;
1057 using MatrixCommon::rows;
1058 using MatrixCommon::scalar_one;
1059 using MatrixCommon::scalar_zero;
1060 using MatrixCommon::semiring;
1061 using MatrixCommon::swap;
1062 using MatrixCommon::transpose;
1063 using MatrixCommon::transpose_no_checks;
1064#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1065
1066 private:
1068 // StaticMatrix - implementation of MatrixCommon requirements - private
1070
1071 static constexpr size_t number_of_rows_impl() noexcept {
1072 return R;
1073 }
1074 static constexpr size_t number_of_cols_impl() noexcept {
1075 return C;
1076 }
1077 }; // class StaticMatrix
1078
1080 // DynamicMatrix with compile time semiring arithmetic
1082
1116 template <typename PlusOp,
1117 typename ProdOp,
1118 typename ZeroOp,
1119 typename OneOp,
1120 typename Scalar>
1121 class DynamicMatrix<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>
1122 : public detail::MatrixDynamicDim<Scalar>,
1123 public detail::MatrixCommon<
1124 std::vector<Scalar>,
1125 DynamicMatrix<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>,
1126 DynamicRowView<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>>,
1127 public detail::
1128 MatrixStaticArithmetic<PlusOp, ProdOp, ZeroOp, OneOp, Scalar> {
1129 using MatrixDynamicDim = ::libsemigroups::detail::MatrixDynamicDim<Scalar>;
1130 using MatrixCommon = ::libsemigroups::detail::MatrixCommon<
1133 DynamicRowView<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>>;
1134 friend MatrixCommon;
1135
1136 public:
1138 using scalar_type = typename MatrixCommon::scalar_type;
1139
1141 using scalar_reference = typename MatrixCommon::scalar_reference;
1142
1144 // clang-format off
1145 // NOLINTNEXTLINE(whitespace/line_length)
1146 using scalar_const_reference = typename MatrixCommon::scalar_const_reference;
1147 // clang-format on
1148
1151
1153 using RowView = DynamicRowView<PlusOp, ProdOp, ZeroOp, OneOp, Scalar>;
1154
1156 using Plus = PlusOp;
1157
1159 using Prod = ProdOp;
1160
1162 using Zero = ZeroOp;
1163
1165 using One = OneOp;
1166
1172 using semiring_type = void;
1173
1177 DynamicMatrix() = default;
1178
1182 DynamicMatrix(DynamicMatrix const&) = default;
1183
1188
1193
1198
1199 ~DynamicMatrix() = default;
1200
1219 DynamicMatrix(size_t r, size_t c) : MatrixDynamicDim(r, c), MatrixCommon() {
1220 resize(number_of_rows(), number_of_cols());
1221 }
1222
1243 : MatrixDynamicDim(1, c.size()), MatrixCommon(c) {}
1244
1267 : MatrixDynamicDim(m.size(), std::empty(m) ? 0 : m.begin()->size()),
1268 MatrixCommon(m) {}
1269
1285 : MatrixDynamicDim(m.size(), std::empty(m) ? 0 : m.begin()->size()),
1286 MatrixCommon(m) {}
1287
1299 explicit DynamicMatrix(RowView const& rv)
1300 : MatrixDynamicDim(1, rv.size()), MatrixCommon(rv) {}
1301
1302#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1303 // For uniformity of interface, the first arg does nothing
1304 DynamicMatrix(void const* ptr, size_t r, size_t c) : DynamicMatrix(r, c) {
1305 (void) ptr;
1306 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
1307 }
1308
1309 // For uniformity of interface, the first arg does nothing
1310 DynamicMatrix(void const* ptr, std::initializer_list<scalar_type> const& c)
1311 : DynamicMatrix(c) {
1312 (void) ptr;
1313 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
1314 }
1315
1316 // For uniformity of interface, the first arg does nothing
1317 DynamicMatrix(
1318 void const* ptr,
1319 std::initializer_list<std::initializer_list<scalar_type>> const& m)
1320 : DynamicMatrix(m) {
1321 (void) ptr;
1322 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
1323 }
1324
1325 static DynamicMatrix one(void const* ptr, size_t n) {
1326 (void) ptr;
1327 LIBSEMIGROUPS_ASSERT(ptr == nullptr);
1328 return one(n);
1329 }
1330#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1331
1344 static DynamicMatrix one(size_t n) {
1345 DynamicMatrix x(n, n);
1346 std::fill(x.begin(), x.end(), ZeroOp()());
1347 for (size_t r = 0; r < n; ++r) {
1348 x(r, r) = OneOp()();
1349 }
1350 return x;
1351 }
1352
1353#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1355 scalar_reference at(size_t r, size_t c);
1356
1358 scalar_reference at(size_t r, size_t c) const;
1359
1361 iterator begin() noexcept;
1362
1364 const_iterator cbegin() noexcept;
1365
1367 const_iterator cend() noexcept;
1368
1370 std::pair<scalar_type, scalar_type> coords(const_iterator it) const;
1371
1373 iterator end() noexcept;
1374
1376 size_t hash_value() const;
1377
1379 size_t number_of_cols() const noexcept;
1380
1382 size_t number_of_rows() const noexcept;
1383
1385 bool operator!=(DynamicMatrix const& that) const;
1386
1388 bool operator!=(RowView const& that) const;
1389
1391 scalar_reference operator()(size_t r, size_t c);
1392
1394 scalar_const_reference operator()(size_t r, size_t c) const;
1407
1410
1412 DynamicMatrix operator*(DynamicMatrix const& that);
1413
1415 void operator*=(scalar_type a);
1416
1419
1421 DynamicMatrix operator+(DynamicMatrix const& that);
1422
1425
1428
1430 void operator+=(DynamicMatrix const& that);
1431
1433 void operator+=(RowView const& that);
1434
1446 void operator+=(scalar_type a);
1447
1449 bool operator<(DynamicMatrix const& that) const;
1450
1452 bool operator<(RowView const& that) const;
1453
1455 template <typename T>
1456 bool operator<=(T const& that) const;
1457
1459 bool operator==(DynamicMatrix const& that) const;
1460
1462 bool operator==(RowView const& that) const;
1463
1465 bool operator>(DynamicMatrix const& that) const;
1466
1468 template <typename T>
1469 bool operator>=(T const& that) const;
1470
1473 DynamicMatrix const& y);
1474
1477
1479 RowView row(size_t i) const;
1480
1482 RowView row_no_checks(size_t i) const;
1483
1485 template <typename T>
1486 void rows(T& x) const;
1487
1489 scalar_type scalar_one() const noexcept;
1490
1492 scalar_type scalar_zero() const noexcept;
1493
1495 semiring_type const* semiring() const noexcept;
1496
1499
1502#else
1503 using MatrixCommon::at;
1504 using MatrixCommon::begin;
1505 using MatrixCommon::cbegin;
1506 using MatrixCommon::cend;
1507 using MatrixCommon::coords;
1508 using MatrixCommon::end;
1509 using MatrixCommon::hash_value;
1510 using MatrixCommon::number_of_cols;
1511 using MatrixCommon::number_of_rows;
1512 using MatrixCommon::one;
1513 using MatrixCommon::operator!=;
1514 using MatrixCommon::operator();
1515 using MatrixCommon::operator*;
1516 using MatrixCommon::operator*=;
1517 using MatrixCommon::operator+;
1518 using MatrixCommon::operator+=;
1519 using MatrixCommon::operator<; // NOLINT(whitespace/operators)
1520 using MatrixCommon::operator<=;
1521 using MatrixCommon::operator==;
1522 using MatrixCommon::operator>; // NOLINT(whitespace/operators)
1523 using MatrixCommon::operator>=;
1524 using MatrixCommon::product_inplace_no_checks;
1525 using MatrixCommon::row;
1526 using MatrixCommon::row_no_checks;
1527 using MatrixCommon::rows;
1528 using MatrixCommon::scalar_one;
1529 using MatrixCommon::scalar_zero;
1530 using MatrixCommon::semiring;
1531 // using MatrixCommon::swap; // Don't want this use the one below.
1532 using MatrixCommon::transpose;
1533 using MatrixCommon::transpose_no_checks;
1534#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1535
1537 void swap(DynamicMatrix& that) noexcept {
1538 static_cast<MatrixDynamicDim&>(*this).swap(
1539 static_cast<MatrixDynamicDim&>(that));
1540 static_cast<MatrixCommon&>(*this).swap(static_cast<MatrixCommon&>(that));
1541 }
1542
1543 private:
1544 using MatrixCommon::resize;
1545 };
1546
1548 // DynamicMatrix with runtime semiring arithmetic
1550
1585 template <typename Semiring, typename Scalar>
1586 class DynamicMatrix<Semiring, Scalar>
1587 : public detail::MatrixDynamicDim<Scalar>,
1588 public detail::MatrixCommon<std::vector<Scalar>,
1589 DynamicMatrix<Semiring, Scalar>,
1590 DynamicRowView<Semiring, Scalar>,
1591 Semiring> {
1592 using MatrixCommon = detail::MatrixCommon<std::vector<Scalar>,
1594 DynamicRowView<Semiring, Scalar>,
1595 Semiring>;
1596 friend MatrixCommon;
1597 using MatrixDynamicDim = ::libsemigroups::detail::MatrixDynamicDim<Scalar>;
1598
1599 public:
1601 using scalar_type = typename MatrixCommon::scalar_type;
1602
1604 using scalar_reference = typename MatrixCommon::scalar_reference;
1605
1607 // clang-format off
1608 // NOLINTNEXTLINE(whitespace/line_length)
1609 using scalar_const_reference = typename MatrixCommon::scalar_const_reference;
1610 // clang-format on
1611
1614
1616 using RowView = DynamicRowView<Semiring, Scalar>;
1617
1618 friend RowView;
1619
1621 using semiring_type = Semiring;
1622
1628 DynamicMatrix() = delete;
1629
1631 DynamicMatrix(DynamicMatrix const&) = default;
1632
1635
1638
1641
1656 DynamicMatrix(Semiring const* sr, size_t r, size_t c)
1657 : MatrixDynamicDim(r, c), MatrixCommon(), _semiring(sr) {
1658 resize(number_of_rows(), number_of_cols());
1659 }
1660
1677 Semiring const* sr,
1679
1695 explicit DynamicMatrix(Semiring const* sr,
1697 : MatrixDynamicDim(rws.size(), (rws.empty() ? 0 : rws.begin()->size())),
1698 MatrixCommon(rws),
1699 _semiring(sr) {}
1700
1714 explicit DynamicMatrix(Semiring const* sr,
1716 : MatrixDynamicDim(1, rw.size()), MatrixCommon(rw), _semiring(sr) {}
1717
1729 explicit DynamicMatrix(RowView const& rv)
1730 : MatrixDynamicDim(1, rv.size()),
1731 MatrixCommon(rv),
1732 _semiring(rv._matrix->semiring()) {}
1733
1748 // No static DynamicMatrix::one(size_t n) because we need a semiring!
1749 static DynamicMatrix one(Semiring const* semiring, size_t n);
1750
1751 ~DynamicMatrix() = default;
1752
1753#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1755 scalar_reference at(size_t r, size_t c);
1756
1758 scalar_reference at(size_t r, size_t c) const;
1759
1761 iterator begin() noexcept;
1762
1764 const_iterator cbegin() noexcept;
1765
1767 const_iterator cend() noexcept;
1768
1770 std::pair<scalar_type, scalar_type> coords(const_iterator it) const;
1771
1773 iterator end() noexcept;
1774
1776 size_t hash_value() const;
1777
1779 size_t number_of_cols() const noexcept;
1780
1782 size_t number_of_rows() const noexcept;
1783
1785 bool operator!=(DynamicMatrix const& that) const;
1786
1788 bool operator!=(RowView const& that) const;
1789
1791 scalar_reference operator()(size_t r, size_t c);
1792
1794 scalar_const_reference operator()(size_t r, size_t c) const;
1795
1798
1801
1803 DynamicMatrix operator*(DynamicMatrix const& that);
1804
1806 void operator*=(scalar_type a);
1807
1809 DynamicMatrix operator+(DynamicMatrix const& that);
1810
1813
1816
1818 void operator+=(DynamicMatrix const& that);
1819
1821 void operator+=(RowView const& that);
1822
1834 void operator+=(scalar_type a);
1835
1837 bool operator<(DynamicMatrix const& that) const;
1838
1840 bool operator<(RowView const& that) const;
1841
1843 template <typename T>
1844 bool operator<=(T const& that) const;
1845
1847 bool operator==(DynamicMatrix const& that) const;
1848
1850 bool operator==(RowView const& that) const;
1851
1853 bool operator>(DynamicMatrix const& that) const;
1854
1856 template <typename T>
1857 bool operator>=(T const& that) const;
1858
1861 DynamicMatrix const& y);
1862
1865
1867 RowView row(size_t i) const;
1868
1870 RowView row_no_checks(size_t i) const;
1871
1873 template <typename T>
1874 void rows(T& x) const;
1875
1877 scalar_type scalar_one() const noexcept;
1878
1880 scalar_type scalar_zero() const noexcept;
1881
1883 semiring_type const* semiring() const noexcept;
1884
1887
1890#else
1891 using MatrixCommon::at;
1892 using MatrixCommon::begin;
1893 using MatrixCommon::cbegin;
1894 using MatrixCommon::cend;
1895 using MatrixCommon::coords;
1896 using MatrixCommon::end;
1897 using MatrixCommon::hash_value;
1898 using MatrixCommon::number_of_cols;
1899 using MatrixCommon::number_of_rows;
1900 using MatrixCommon::one;
1901 using MatrixCommon::operator!=;
1902 using MatrixCommon::operator();
1903 using MatrixCommon::operator*;
1904 using MatrixCommon::operator*=;
1905 using MatrixCommon::operator+;
1906 using MatrixCommon::operator+=;
1907 using MatrixCommon::operator<; // NOLINT(whitespace/operators)
1908 using MatrixCommon::operator<=;
1909 using MatrixCommon::operator==;
1910 using MatrixCommon::operator>; // NOLINT(whitespace/operators)
1911 using MatrixCommon::operator>=;
1912 using MatrixCommon::product_inplace_no_checks;
1913 using MatrixCommon::row;
1914 using MatrixCommon::row_no_checks;
1915 using MatrixCommon::rows;
1916 using MatrixCommon::scalar_one;
1917 using MatrixCommon::scalar_zero;
1918 using MatrixCommon::semiring;
1919 // using MatrixCommon::swap; // Don't want this use the one below.
1920 using MatrixCommon::transpose;
1921 using MatrixCommon::transpose_no_checks;
1922#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1923
1925 void swap(DynamicMatrix& that) noexcept;
1926
1927 private:
1928 using MatrixCommon::resize;
1929
1930 scalar_type plus_no_checks_impl(scalar_type x,
1931 scalar_type y) const noexcept {
1932 return _semiring->plus_no_checks(x, y);
1933 }
1934
1935 scalar_type product_no_checks_impl(scalar_type x,
1936 scalar_type y) const noexcept {
1937 return _semiring->product_no_checks(x, y);
1938 }
1939
1940 scalar_type one_impl() const noexcept {
1941 return _semiring->scalar_one();
1942 }
1943
1944 scalar_type zero_impl() const noexcept {
1945 return _semiring->scalar_zero();
1946 }
1947
1948 Semiring const* semiring_impl() const noexcept {
1949 return _semiring;
1950 }
1951
1952 Semiring const* _semiring;
1953 };
1954
1956 // Helper structs to check if matrix is static, or has a pointer to a
1957 // semiring
1959
1960 namespace detail {
1961 template <typename PlusOp,
1962 typename ProdOp,
1963 typename ZeroOp,
1964 typename OneOp,
1965 size_t R,
1966 size_t C,
1967 typename Scalar>
1968 struct IsStaticMatrixHelper<
1969 StaticMatrix<PlusOp, ProdOp, ZeroOp, OneOp, R, C, Scalar>>
1970 : std::true_type {};
1971
1972 template <typename Semiring, typename Scalar>
1973 struct IsMatWithSemiringHelper<DynamicMatrix<Semiring, Scalar>>
1974 : std::true_type {};
1975 } // namespace detail
1976
1978 // Boolean matrices - compile time semiring arithmetic
1980
2014
2037 constexpr bool operator()(bool x, bool y) const noexcept {
2038 return x || y;
2039 }
2040 };
2041
2064 constexpr bool operator()(bool x, bool y) const noexcept {
2065 return x & y;
2066 }
2067 };
2068
2078 struct BooleanOne {
2089 constexpr bool operator()() const noexcept {
2090 return true;
2091 }
2092 };
2093
2114 constexpr bool operator()() const noexcept {
2115 return false;
2116 }
2117 };
2118
2127 // The use of `int` rather than `bool` as the scalar type for dynamic
2128 // boolean matrices is intentional, because the bit iterators implemented in
2129 // std::vector<bool> entail a significant performance penalty.
2131 = DynamicMatrix<BooleanPlus, BooleanProd, BooleanZero, BooleanOne, int>;
2132
2144 template <size_t R, size_t C>
2148 BooleanOne,
2149 R,
2150 C,
2151 int>;
2152
2166 // FLS + JDM considered adding BMat8 and decided it wasn't a good idea.
2167 template <size_t R = 0, size_t C = R>
2168 using BMat
2169 = std::conditional_t<R == 0 || C == 0, DynamicBMat, StaticBMat<R, C>>;
2170
2171 namespace detail {
2172 template <size_t R, size_t C>
2173 struct IsBMatHelper<StaticBMat<R, C>> : std::true_type {};
2174
2175 template <>
2176 struct IsBMatHelper<DynamicBMat> : std::true_type {};
2177 } // namespace detail
2178
2180 // Integer matrices - compile time semiring arithmetic
2182
2210
2222 //! \tparam Scalar the type of the entries in the matrix.
2223 template <typename Scalar>
2224 struct IntegerPlus {
2235 //! \exceptions
2236 //! \noexcept
2237 constexpr Scalar operator()(Scalar x, Scalar y) const noexcept {
2238 return x + y;
2239 }
2240 };
2241
2253 //! \tparam Scalar the type of the entries in the matrix.
2254 template <typename Scalar>
2255 struct IntegerProd {
2266 //! \exceptions
2267 //! \noexcept
2268 constexpr Scalar operator()(Scalar x, Scalar y) const noexcept {
2269 return x * y;
2270 }
2271 };
2272
2281 //! the additive identity of the integer semiring.
2282 template <typename Scalar>
2283 struct IntegerZero {
2291 //! \exceptions
2292 //! \noexcept
2293 constexpr Scalar operator()() const noexcept {
2294 return 0;
2295 }
2296 };
2297
2306 //! the multiplicative identity of the integer semiring.
2307 template <typename Scalar>
2308 struct IntegerOne {
2316 //! \exceptions
2317 //! \noexcept
2318 constexpr Scalar operator()() const noexcept {
2319 return 1;
2320 }
2321 };
2322
2333 template <typename Scalar>
2334 using DynamicIntMat = DynamicMatrix<IntegerPlus<Scalar>,
2338 Scalar>;
2339
2356 template <size_t R, size_t C, typename Scalar>
2361 R,
2362 C,
2363 Scalar>;
2364
2381 template <size_t R = 0, size_t C = R, typename Scalar = int>
2382 using IntMat = std::conditional_t<R == 0 || C == 0,
2385 namespace detail {
2386 template <size_t R, size_t C, typename Scalar>
2387 struct IsIntMatHelper<StaticIntMat<R, C, Scalar>> : std::true_type {};
2388
2389 template <typename Scalar>
2390 struct IsIntMatHelper<DynamicIntMat<Scalar>> : std::true_type {};
2391 } // namespace detail
2392
2394 // Max-plus matrices
2424
2448 // Static arithmetic
2449 template <typename Scalar>
2450 struct MaxPlusPlus {
2451 static_assert(std::is_signed<Scalar>::value,
2452 "MaxPlus requires a signed integer type as parameter!");
2465 Scalar operator()(Scalar x, Scalar y) const noexcept;
2466 };
2467
2488 //! integer type).
2489 template <typename Scalar>
2490 struct MaxPlusProd {
2491 static_assert(std::is_signed<Scalar>::value,
2492 "MaxPlus requires a signed integer type as parameter!");
2505 Scalar operator()(Scalar x, Scalar y) const noexcept;
2506 };
2507
2520 //! integer type).
2521 template <typename Scalar>
2522 struct MaxPlusZero {
2523 static_assert(std::is_signed<Scalar>::value,
2524 "MaxPlus requires a signed integer type as parameter!");
2532 //! \exceptions
2533 //! \noexcept
2534 constexpr Scalar operator()() const noexcept {
2535 return NEGATIVE_INFINITY;
2536 }
2537 };
2538
2549 template <typename Scalar>
2550 using DynamicMaxPlusMat = DynamicMatrix<MaxPlusPlus<Scalar>,
2554 Scalar>;
2555
2568 template <size_t R, size_t C, typename Scalar>
2573 R,
2574 C,
2575 Scalar>;
2576
2592 template <size_t R = 0, size_t C = R, typename Scalar = int>
2593 using MaxPlusMat = std::conditional_t<R == 0 || C == 0,
2596
2597 namespace detail {
2598 template <size_t R, size_t C, typename Scalar>
2599 struct IsMaxPlusMatHelper<StaticMaxPlusMat<R, C, Scalar>> : std::true_type {
2600 };
2601
2602 template <typename Scalar>
2603 struct IsMaxPlusMatHelper<DynamicMaxPlusMat<Scalar>> : std::true_type {};
2604 } // namespace detail
2605
2607 // Min-plus matrices
2609
2638
2660 //!
2661 template <typename Scalar>
2662 struct MinPlusPlus {
2663 static_assert(std::is_signed<Scalar>::value,
2664 "MinPlus requires a signed integer type as parameter!");
2677 Scalar operator()(Scalar x, Scalar y) const noexcept;
2678 };
2679
2700 //! integer type).
2701 template <typename Scalar>
2702 struct MinPlusProd {
2703 static_assert(std::is_signed<Scalar>::value,
2704 "MinPlus requires a signed integer type as parameter!");
2717 Scalar operator()(Scalar x, Scalar y) const noexcept;
2718 };
2719
2732 //! integer type).
2733 template <typename Scalar>
2734 struct MinPlusZero {
2735 static_assert(std::is_signed<Scalar>::value,
2736 "MinPlus requires a signed integer type as parameter!");
2744 //! \exceptions
2745 //! \noexcept
2746 constexpr Scalar operator()() const noexcept {
2747 return POSITIVE_INFINITY;
2748 }
2749 };
2750
2761 template <typename Scalar>
2762 using DynamicMinPlusMat = DynamicMatrix<MinPlusPlus<Scalar>,
2766 Scalar>;
2767
2780 template <size_t R, size_t C, typename Scalar>
2785 R,
2786 C,
2787 Scalar>;
2804 template <size_t R = 0, size_t C = R, typename Scalar = int>
2805 using MinPlusMat = std::conditional_t<R == 0 || C == 0,
2808
2809 namespace detail {
2810 template <size_t R, size_t C, typename Scalar>
2811 struct IsMinPlusMatHelper<StaticMinPlusMat<R, C, Scalar>> : std::true_type {
2812 };
2813
2814 template <typename Scalar>
2815 struct IsMinPlusMatHelper<DynamicMinPlusMat<Scalar>> : std::true_type {};
2816 } // namespace detail
2817
2819 // Max-plus matrices with threshold
2821
2867
2892 //! integer type).
2893 template <size_t T, typename Scalar>
2894 struct MaxPlusTruncProd {
2895 static_assert(std::is_signed<Scalar>::value,
2896 "MaxPlus requires a signed integer type as parameter!");
2909 Scalar operator()(Scalar x, Scalar y) const noexcept;
2910 };
2911
2925 //! signed integer type (defaults to \c int).
2926 template <typename Scalar = int>
2927 class MaxPlusTruncSemiring {
2928 static_assert(std::is_signed<Scalar>::value,
2929 "MaxPlus requires a signed integer type as parameter!");
2930
2931 public:
2935 MaxPlusTruncSemiring() = delete;
2936
2940 MaxPlusTruncSemiring(MaxPlusTruncSemiring const&) noexcept = default;
2941
2945 MaxPlusTruncSemiring(MaxPlusTruncSemiring&&) noexcept = default;
2946
2950 MaxPlusTruncSemiring& operator=(MaxPlusTruncSemiring const&) noexcept
2951 = default;
2952
2956 MaxPlusTruncSemiring& operator=(MaxPlusTruncSemiring&&) noexcept = default;
2957
2958 ~MaxPlusTruncSemiring() = default;
2959
2970 explicit MaxPlusTruncSemiring(Scalar threshold);
2971
2980 //! \exceptions
2981 //! \noexcept
2982 static constexpr Scalar scalar_one() noexcept {
2983 return 0;
2984 }
2985
2994 //! \exceptions
2995 //! \noexcept
2996 static constexpr Scalar scalar_zero() noexcept {
2997 return NEGATIVE_INFINITY;
2998 }
2999
3024 Scalar product_no_checks(Scalar x, Scalar y) const noexcept;
3025
3050 Scalar plus_no_checks(Scalar x, Scalar y) const noexcept;
3051
3062 //! \complexity
3063 //! Constant.
3064 Scalar threshold() const noexcept {
3065 return _threshold;
3066 }
3067
3068 public:
3069 Scalar const _threshold;
3070 };
3071
3084 template <size_t T, typename Scalar>
3085 using DynamicMaxPlusTruncMat = DynamicMatrix<MaxPlusPlus<Scalar>,
3089 Scalar>;
3090
3104 template <size_t T, size_t R, size_t C, typename Scalar>
3109 R,
3110 C,
3111 Scalar>;
3130 template <size_t T = 0, size_t R = 0, size_t C = R, typename Scalar = int>
3131 using MaxPlusTruncMat = std::conditional_t<
3132 R == 0 || C == 0,
3133 std::conditional_t<T == 0,
3134 DynamicMatrix<MaxPlusTruncSemiring<Scalar>, Scalar>,
3137
3138 namespace detail {
3139 template <size_t T, size_t R, size_t C, typename Scalar>
3140 struct IsMaxPlusTruncMatHelper<StaticMaxPlusTruncMat<T, R, C, Scalar>>
3141 : std::true_type {
3142 static constexpr Scalar threshold = T;
3143 };
3144
3145 template <size_t T, typename Scalar>
3146 struct IsMaxPlusTruncMatHelper<DynamicMaxPlusTruncMat<T, Scalar>>
3147 : std::true_type {
3148 static constexpr Scalar threshold = T;
3149 };
3150
3151 template <typename Scalar>
3152 struct IsMaxPlusTruncMatHelper<
3153 DynamicMatrix<MaxPlusTruncSemiring<Scalar>, Scalar>> : std::true_type {
3154 static constexpr Scalar threshold = UNDEFINED;
3155 };
3156
3157 template <typename T>
3158 struct IsTruncMatHelper<T, std::enable_if_t<IsMaxPlusTruncMat<T>>>
3159 : std::true_type {
3160 static constexpr typename T::scalar_type threshold
3161 = IsMaxPlusTruncMatHelper<T>::threshold;
3162 };
3163 } // namespace detail
3164
3166 // Min-plus matrices with threshold
3168
3214
3238 //! \tparam Scalar the type of the values in the semiring.
3239 template <size_t T, typename Scalar>
3240 struct MinPlusTruncProd {
3253 Scalar operator()(Scalar x, Scalar y) const noexcept;
3254 }; // MinPlusTruncProd
3255
3268 //! integral type.
3269 template <typename Scalar = int>
3270 class MinPlusTruncSemiring {
3271 static_assert(std::is_integral<Scalar>::value,
3272 "MinPlus requires an integral type as parameter!");
3273
3274 public:
3278 MinPlusTruncSemiring() = delete;
3279
3283 MinPlusTruncSemiring(MinPlusTruncSemiring const&) noexcept = default;
3284
3288 MinPlusTruncSemiring(MinPlusTruncSemiring&&) noexcept = default;
3289
3293 MinPlusTruncSemiring& operator=(MinPlusTruncSemiring const&) noexcept
3294 = default;
3295
3299 MinPlusTruncSemiring& operator=(MinPlusTruncSemiring&&) noexcept = default;
3300
3311 explicit MinPlusTruncSemiring(Scalar threshold);
3312
3321 //! \exceptions
3322 //! \noexcept
3323 static constexpr Scalar scalar_one() noexcept {
3324 return 0;
3325 }
3326
3336 //! \noexcept
3337 // TODO(1) These mem fns (one and zero) aren't needed?
3338 static constexpr Scalar scalar_zero() noexcept {
3339 return POSITIVE_INFINITY;
3340 }
3341
3366 Scalar product_no_checks(Scalar x, Scalar y) const noexcept;
3367
3392 Scalar plus_no_checks(Scalar x, Scalar y) const noexcept;
3393
3404 //! \complexity
3405 //! Constant.
3406 Scalar threshold() const noexcept {
3407 return _threshold;
3408 }
3409
3410 public:
3411 Scalar const _threshold;
3412 };
3413
3426 template <size_t T, typename Scalar>
3427 using DynamicMinPlusTruncMat = DynamicMatrix<MinPlusPlus<Scalar>,
3431 Scalar>;
3432
3446 template <size_t T, size_t R, size_t C, typename Scalar>
3451 R,
3452 C,
3453 Scalar>;
3454
3473 template <size_t T = 0, size_t R = 0, size_t C = R, typename Scalar = int>
3474 using MinPlusTruncMat = std::conditional_t<
3475 R == 0 || C == 0,
3476 std::conditional_t<T == 0,
3477 DynamicMatrix<MinPlusTruncSemiring<Scalar>, Scalar>,
3480
3481 namespace detail {
3482 template <size_t T, size_t R, size_t C, typename Scalar>
3483 struct IsMinPlusTruncMatHelper<StaticMinPlusTruncMat<T, R, C, Scalar>>
3484 : std::true_type {
3485 static constexpr Scalar threshold = T;
3486 };
3487
3488 template <size_t T, typename Scalar>
3489 struct IsMinPlusTruncMatHelper<DynamicMinPlusTruncMat<T, Scalar>>
3490 : std::true_type {
3491 static constexpr Scalar threshold = T;
3492 };
3493
3494 template <typename Scalar>
3495 struct IsMinPlusTruncMatHelper<
3496 DynamicMatrix<MinPlusTruncSemiring<Scalar>, Scalar>> : std::true_type {
3497 static constexpr Scalar threshold = UNDEFINED;
3498 };
3499
3500 template <typename T>
3501 struct IsTruncMatHelper<T, std::enable_if_t<IsMinPlusTruncMat<T>>>
3502 : std::true_type {
3503 static constexpr typename T::scalar_type threshold
3504 = IsMinPlusTruncMatHelper<T>::threshold;
3505 };
3506 } // namespace detail
3507
3509 // NTP matrices
3511
3564
3565 namespace detail {
3566 template <size_t T, size_t P, typename Scalar>
3567 constexpr Scalar thresholdperiod(Scalar x) noexcept;
3568
3569 template <typename Scalar>
3570 inline Scalar thresholdperiod(Scalar x,
3571 Scalar threshold,
3572 Scalar period) noexcept;
3573 } // namespace detail
3574
3597 // Static arithmetic
3598 template <size_t T, size_t P, typename Scalar>
3599 struct NTPPlus {
3609 //! \exceptions
3610 //! \noexcept
3611 constexpr Scalar operator()(Scalar x, Scalar y) const noexcept {
3612 return detail::thresholdperiod<T, P>(x + y);
3613 }
3614 };
3615
3638 //! \tparam Scalar the type of the values in the semiring.
3639 template <size_t T, size_t P, typename Scalar>
3640 struct NTPProd {
3652 //! \exceptions
3653 //! \noexcept
3654 constexpr Scalar operator()(Scalar x, Scalar y) const noexcept {
3655 return detail::thresholdperiod<T, P>(x * y);
3656 }
3657 };
3658
3672 // Dynamic arithmetic
3673 template <typename Scalar = size_t>
3674 class NTPSemiring {
3675 public:
3679 // Deleted to avoid uninitialised values of period and threshold.
3680 NTPSemiring() = delete;
3681
3685 NTPSemiring(NTPSemiring const&) = default;
3686
3690 NTPSemiring(NTPSemiring&&) = default;
3691
3695 NTPSemiring& operator=(NTPSemiring const&) = default;
3696
3700 NTPSemiring& operator=(NTPSemiring&&) = default;
3701
3702 ~NTPSemiring() = default;
3703
3714 //! \complexity
3715 //! Constant.
3716 NTPSemiring(Scalar t, Scalar p) : _period(p), _threshold(t) {
3717 if constexpr (std::is_signed<Scalar>::value) {
3718 if (t < 0) {
3720 "expected non-negative value for 1st argument, found {}", t);
3721 }
3722 }
3723 if (p <= 0) {
3725 "expected positive value for 2nd argument, found {}", p);
3726 }
3727 }
3728
3737 //! \exceptions
3738 //! \noexcept
3739 static constexpr Scalar scalar_one() noexcept {
3740 return 1;
3741 }
3742
3753 //! \complexity
3754 //! Constant.
3755 static constexpr Scalar scalar_zero() noexcept {
3756 return 0;
3757 }
3758
3781 //! \complexity
3782 //! Constant.
3783 Scalar product_no_checks(Scalar x, Scalar y) const noexcept {
3784 LIBSEMIGROUPS_ASSERT(x >= 0 && x <= _period + _threshold - 1);
3785 LIBSEMIGROUPS_ASSERT(y >= 0 && y <= _period + _threshold - 1);
3786 return detail::thresholdperiod(x * y, _threshold, _period);
3787 }
3788
3811 //! \complexity
3812 //! Constant.
3813 Scalar plus_no_checks(Scalar x, Scalar y) const noexcept {
3814 LIBSEMIGROUPS_ASSERT(x >= 0 && x <= _period + _threshold - 1);
3815 LIBSEMIGROUPS_ASSERT(y >= 0 && y <= _period + _threshold - 1);
3816 return detail::thresholdperiod(x + y, _threshold, _period);
3817 }
3818
3829 //! \complexity
3830 //! Constant.
3831 Scalar threshold() const noexcept {
3832 return _threshold;
3833 }
3834
3845 //! \complexity
3846 //! Constant.
3847 Scalar period() const noexcept {
3848 return _period;
3849 }
3850
3851 private:
3852 Scalar _period;
3853 Scalar _threshold;
3854 };
3855
3866 template <typename Scalar>
3867 using DynamicNTPMatWithSemiring = DynamicMatrix<NTPSemiring<Scalar>, Scalar>;
3868
3882 template <size_t T, size_t P, typename Scalar>
3883 using DynamicNTPMatWithoutSemiring = DynamicMatrix<NTPPlus<T, P, Scalar>,
3887 Scalar>;
3888
3908 template <size_t T, size_t P, size_t R, size_t C, typename Scalar>
3913 R,
3914 C,
3915 Scalar>;
3916
3939 template <size_t T = 0,
3940 size_t P = 0,
3941 size_t R = 0,
3942 size_t C = R,
3943 typename Scalar = size_t>
3944 using NTPMat = std::conditional_t<
3945 R == 0 || C == 0,
3946 std::conditional_t<T == 0 && P == 0,
3950
3951 namespace detail {
3952 template <typename Scalar>
3953 struct IsNTPMatHelper<DynamicNTPMatWithSemiring<Scalar>> : std::true_type {
3954 static constexpr Scalar threshold = UNDEFINED;
3955 static constexpr Scalar period = UNDEFINED;
3956 };
3957
3958 template <size_t T, size_t P, typename Scalar>
3959 struct IsNTPMatHelper<DynamicNTPMatWithoutSemiring<T, P, Scalar>>
3960 : std::true_type {
3961 static constexpr Scalar threshold = T;
3962 static constexpr Scalar period = P;
3963 };
3964
3965 template <size_t T, size_t P, size_t R, size_t C, typename Scalar>
3966 struct IsNTPMatHelper<StaticNTPMat<T, P, R, C, Scalar>> : std::true_type {
3967 static constexpr Scalar threshold = T;
3968 static constexpr Scalar period = P;
3969 };
3970
3971 template <typename T>
3972 struct IsTruncMatHelper<T, std::enable_if_t<IsNTPMat<T>>> : std::true_type {
3973 static constexpr typename T::scalar_type threshold
3974 = IsNTPMatHelper<T>::threshold;
3975 static constexpr typename T::scalar_type period
3976 = IsNTPMatHelper<T>::period;
3977 };
3978 } // namespace detail
3979
3981 // Projective max-plus matrices
3983
3984 namespace detail {
3985 template <typename T>
3986 class ProjMaxPlusMat : MatrixPolymorphicBase {
3987 public:
3988 using scalar_type = typename T::scalar_type;
3989 using scalar_reference = typename T::scalar_reference;
3990 using scalar_const_reference = typename T::scalar_const_reference;
3991 using semiring_type = void;
3992
3993 using container_type = typename T::container_type;
3994 using iterator = typename T::iterator;
3995 using const_iterator = typename T::const_iterator;
3996
3997 using underlying_matrix_type = T;
3998
3999 using RowView = typename T::RowView;
4000
4001 // Note that Rows are never normalised, and that's why we use the
4002 // underlying matrix Row type and not 1 x n ProjMaxPlusMat's instead
4003 // (since these will be normalised according to their entries, and
4004 // this might not correspond to the normalised entries of the matrix).
4005 using Row = typename T::Row;
4006
4007 scalar_type scalar_one() const noexcept {
4008 return _underlying_mat.scalar_one();
4009 }
4010
4011 scalar_type scalar_zero() const noexcept {
4012 return _underlying_mat.scalar_zero();
4013 }
4014
4016 // ProjMaxPlusMat - Constructors + destructor - public
4018
4019 ProjMaxPlusMat() : _is_normalized(false), _underlying_mat() {}
4020 ProjMaxPlusMat(ProjMaxPlusMat const&) = default;
4021 ProjMaxPlusMat(ProjMaxPlusMat&&) = default;
4022 ProjMaxPlusMat& operator=(ProjMaxPlusMat const&) = default;
4023 ProjMaxPlusMat& operator=(ProjMaxPlusMat&&) = default;
4024
4025 ProjMaxPlusMat(size_t r, size_t c)
4026 : _is_normalized(false), _underlying_mat(r, c) {}
4027
4028 // TODO(1) other missing constructors
4030 typename underlying_matrix_type::semiring_type const* semiring,
4031 size_t r,
4032 size_t c)
4033 : _is_normalized(false), _underlying_mat(semiring, r, c) {}
4034
4035 explicit ProjMaxPlusMat(std::vector<std::vector<scalar_type>> const& m)
4036 : _is_normalized(false), _underlying_mat(m) {
4037 normalize();
4038 }
4039
4041 std::initializer_list<std::initializer_list<scalar_type>> const& m)
4043 std::vector<std::vector<scalar_type>>(m.begin(), m.end())) {}
4044
4045 ~ProjMaxPlusMat() = default;
4046
4047 ProjMaxPlusMat one() const {
4048 return ProjMaxPlusMat(_underlying_mat.one());
4049 }
4050
4051 static ProjMaxPlusMat one(size_t n) {
4052 return ProjMaxPlusMat(T::one(n));
4053 }
4054
4056 // Comparison operators
4058
4059 bool operator==(ProjMaxPlusMat const& that) const {
4060 normalize();
4061 that.normalize();
4062 return _underlying_mat == that._underlying_mat;
4063 }
4064
4065 bool operator!=(ProjMaxPlusMat const& that) const {
4066 return !(_underlying_mat == that._underlying_mat);
4067 }
4068
4069 bool operator<(ProjMaxPlusMat const& that) const {
4070 normalize();
4071 that.normalize();
4072 return _underlying_mat < that._underlying_mat;
4073 }
4074
4075 bool operator>(ProjMaxPlusMat const& that) const {
4076 return that < *this;
4077 }
4078
4079 template <typename Thing>
4080 bool operator>=(Thing const& that) const {
4081 static_assert(IsMatrix<Thing> || std::is_same_v<Thing, RowView>);
4082 return that < *this || that == *this;
4083 }
4084
4085 // not noexcept because operator< isn't
4086 template <typename Thing>
4087 bool operator<=(Thing const& that) const {
4088 static_assert(IsMatrix<Thing> || std::is_same_v<Thing, RowView>);
4089 return *this < that || that == *this;
4090 }
4091
4093 // Attributes
4095
4096 scalar_reference operator()(size_t r, size_t c) {
4097 // to ensure the returned value is normalised
4098 normalize();
4099 // to ensure that the matrix is renormalised if the returned scalar is
4100 // assigned.
4101 _is_normalized = false;
4102 return _underlying_mat(r, c);
4103 }
4104
4105 scalar_reference at(size_t r, size_t c) {
4106 matrix::throw_if_bad_coords(*this, r, c);
4107 return this->operator()(r, c);
4108 }
4109
4110 scalar_const_reference operator()(size_t r, size_t c) const {
4111 normalize();
4112 return _underlying_mat(r, c);
4113 }
4114
4115 scalar_const_reference at(size_t r, size_t c) const {
4116 matrix::throw_if_bad_coords(*this, r, c);
4117 return this->operator()(r, c);
4118 }
4119
4120 size_t number_of_rows() const noexcept {
4121 return _underlying_mat.number_of_rows();
4122 }
4123
4124 size_t number_of_cols() const noexcept {
4125 return _underlying_mat.number_of_cols();
4126 }
4127
4128 size_t hash_value() const {
4129 normalize();
4130 return Hash<T>()(_underlying_mat);
4131 }
4132
4134 // Arithmetic operators - in-place
4136
4137 void product_inplace_no_checks(ProjMaxPlusMat const& A,
4138 ProjMaxPlusMat const& B) {
4139 _underlying_mat.product_inplace_no_checks(A._underlying_mat,
4140 B._underlying_mat);
4141 normalize(true); // force normalize
4142 }
4143
4144 void product_inplace(ProjMaxPlusMat const& A, ProjMaxPlusMat const& B) {
4145 _underlying_mat.product_inplace(A._underlying_mat, B._underlying_mat);
4146 normalize(true); // force normalize
4147 }
4148
4149 void plus_inplace_no_checks(ProjMaxPlusMat const& that) {
4150 _underlying_mat.plus_inplace_no_checks(that._underlying_mat);
4151 normalize(true); // force normalize
4152 }
4153
4154 void operator+=(ProjMaxPlusMat const& that) {
4155 _underlying_mat += that._underlying_mat;
4156 normalize(true); // force normalize
4157 }
4158
4159 void product_inplace_no_checks(ProjMaxPlusMat const& that) {
4160 _underlying_mat.product_inplace_no_checks(that._underlying_mat);
4161 normalize(true); // force normalize
4162 }
4163
4164 void operator*=(scalar_type a) {
4165 _underlying_mat *= a;
4166 normalize(true); // force normalize
4167 }
4168
4169 void operator+=(scalar_type a) {
4170 _underlying_mat += a;
4171 normalize(true); // force normalize
4172 }
4173
4174 void operator+=(RowView a) {
4175 _underlying_mat += a;
4176 normalize(true); // force normalize
4177 }
4178
4179 ProjMaxPlusMat operator*(scalar_type a) const {
4180 ProjMaxPlusMat result(*this);
4181 result *= a;
4182 return result;
4183 }
4184
4185 ProjMaxPlusMat operator+(scalar_type a) const {
4186 ProjMaxPlusMat result(*this);
4187 result += a;
4188 return result;
4189 }
4190
4192 // Arithmetic operators - not in-place
4194
4195 ProjMaxPlusMat plus_no_checks(ProjMaxPlusMat const& that) const {
4196 return ProjMaxPlusMat(
4197 plus_no_checks(_underlying_mat, that._underlying_mat));
4198 }
4199
4200 ProjMaxPlusMat operator+(ProjMaxPlusMat const& that) const {
4201 return ProjMaxPlusMat(_underlying_mat + that._underlying_mat);
4202 }
4203
4204 ProjMaxPlusMat product_no_checks(ProjMaxPlusMat const& that) const {
4205 return ProjMaxPlusMat(
4206 product_no_checks(_underlying_mat, that._underlying_mat));
4207 }
4208
4209 ProjMaxPlusMat operator*(ProjMaxPlusMat const& that) const {
4210 return ProjMaxPlusMat(_underlying_mat * that._underlying_mat);
4211 }
4212
4214 // Iterators
4216
4217 // The following should probably be commented out because I can't
4218 // currently think how to ensure that the matrix is normalised if it's
4219 // changed this way.
4220
4221 iterator begin() noexcept {
4222 // to ensure the returned value is normalised
4223 normalize();
4224 // to ensure that the matrix is renormalised if the returned scalar is
4225 // assigned.
4226 _is_normalized = false;
4227 return _underlying_mat.begin();
4228 }
4229
4230 iterator end() noexcept {
4231 // to ensure the returned value is normalised
4232 normalize();
4233 // to ensure that the matrix is renormalised if the returned scalar is
4234 // assigned.
4235 _is_normalized = false;
4236 return _underlying_mat.end();
4237 }
4238
4239 const_iterator begin() const noexcept {
4240 normalize();
4241 return _underlying_mat.begin();
4242 }
4243
4244 const_iterator end() const noexcept {
4245 normalize();
4246 return _underlying_mat.end();
4247 }
4248
4249 const_iterator cbegin() const noexcept {
4250 normalize();
4251 return _underlying_mat.cbegin();
4252 }
4253
4254 const_iterator cend() const noexcept {
4255 normalize();
4256 return _underlying_mat.cend();
4257 }
4258
4260 // Modifiers
4262
4263 void swap(ProjMaxPlusMat& that) noexcept {
4264 std::swap(_underlying_mat, that._underlying_mat);
4265 }
4266
4267 void transpose() noexcept {
4268 _underlying_mat.transpose();
4269 }
4270
4271 void transpose_no_checks() noexcept {
4272 _underlying_mat.transpose_no_checks();
4273 }
4274
4276 // Rows
4278
4279 RowView row(size_t i) const {
4280 normalize();
4281 return _underlying_mat.row(i);
4282 }
4283
4284 template <typename C>
4285 void rows(C& x) const {
4286 normalize();
4287 return _underlying_mat.rows(x);
4288 }
4289
4291 // Friend functions
4293
4294 friend std::ostream& operator<<(std::ostream& os,
4295 ProjMaxPlusMat const& x) {
4296 x.normalize();
4297 os << detail::to_string(x._underlying_mat);
4298 return os;
4299 }
4300
4301 T const& underlying_matrix() const noexcept {
4302 normalize();
4303 return _underlying_mat;
4304 }
4305
4306 private:
4307 explicit ProjMaxPlusMat(T&& mat)
4308 : _is_normalized(false), _underlying_mat(std::move(mat)) {
4309 normalize();
4310 }
4311
4312 void normalize(bool force = false) const;
4313
4314 mutable bool _is_normalized;
4315 mutable T _underlying_mat;
4316 };
4317 } // namespace detail
4318
4363
4377 template <size_t R, size_t C, typename Scalar>
4379 = detail::ProjMaxPlusMat<StaticMaxPlusMat<R, C, Scalar>>;
4380
4392 template <typename Scalar>
4394 = detail::ProjMaxPlusMat<DynamicMaxPlusMat<Scalar>>;
4395
4410 template <size_t R = 0, size_t C = R, typename Scalar = int>
4411 using ProjMaxPlusMat = std::conditional_t<R == 0 || C == 0,
4414
4415 namespace detail {
4416 template <size_t R, size_t C, typename Scalar>
4417 struct IsProjMaxPlusMatHelper<StaticProjMaxPlusMat<R, C, Scalar>>
4418 : std::true_type {};
4419
4420 template <typename Scalar>
4421 struct IsProjMaxPlusMatHelper<DynamicProjMaxPlusMat<Scalar>>
4422 : std::true_type {};
4423 } // namespace detail
4424
4441 //! \no_libsemigroups_except
4442 //!
4443 //! \warning This function does not detect overflows of `Mat::scalar_type`.
4444 template <typename Mat>
4445 auto operator+(typename Mat::scalar_type a, Mat const& x)
4446 -> std::enable_if_t<IsMatrix<Mat>, Mat> {
4447 return x + a;
4448 }
4449
4466 //! \no_libsemigroups_except
4467 //!
4468 //! \warning This function does not detect overflows of `Mat::scalar_type`.
4469 template <typename Mat>
4470 auto operator*(typename Mat::scalar_type a, Mat const& x)
4471 -> std::enable_if_t<IsMatrix<Mat>, Mat> {
4472 return x * a;
4473 }
4474} // namespace libsemigroups
4475
4476namespace std {
4477 template <size_t N,
4478 typename Mat,
4479 std::enable_if_t<libsemigroups::IsMatrix<Mat>>>
4480 inline void swap(Mat& x, Mat& y) noexcept {
4481 x.swap(y);
4482 }
4483} // namespace std
4484
4485#include "matrix-class.tpp"
4486#endif // LIBSEMIGROUPS_MATRIX_CLASS_HPP_
DynamicMatrix(std::initializer_list< scalar_type > const &c)
Construct a vector from a std::initializer_list.
Definition matrix-class.hpp:1242
DynamicMatrix(std::initializer_list< std::initializer_list< scalar_type > > const &m)
Construct a matrix from std::initializer_list of std::initializer_list of scalars.
Definition matrix-class.hpp:1265
DynamicMatrix & operator=(DynamicMatrix &&)=default
Default move assignment operator.
scalar_reference at(size_t r, size_t c)
Returns a reference to the specified entry of the matrix.
ProdOp Prod
Alias for the template parameter ProdOp.
Definition matrix-class.hpp:1159
void product_inplace_no_checks(DynamicMatrix const &x, DynamicMatrix const &y)
Multiplies x and y and stores the result in this.
DynamicMatrix & operator=(DynamicMatrix const &)=default
Default copy assignment operator.
DynamicMatrix Row
The type of a row of a DynamicMatrix.
Definition matrix-class.hpp:1150
PlusOp Plus
Alias for the template parameter PlusOp.
Definition matrix-class.hpp:1156
void rows(T &x) const
Add row views for every row in the matrix to a container.
scalar_type scalar_one() const noexcept
Returns the multiplicative identity of the underlying semiring.
typename MatrixCommon::scalar_const_reference scalar_const_reference
The type of const references to the entries in the matrix.
Definition matrix-class.hpp:1146
void swap(DynamicMatrix &that) noexcept
Swaps the contents of *this with the contents of that.
Definition matrix-class.hpp:1537
const_iterator cend() noexcept
Returns a const iterator pointing one beyond the last entry in the matrix.
static DynamicMatrix one(size_t n)
Construct the identity matrix.
Definition matrix-class.hpp:1344
DynamicMatrix(size_t r, size_t c)
Construct a matrix with given dimensions.
Definition matrix-class.hpp:1219
void product_inplace(DynamicMatrix const &x, DynamicMatrix const &y)
Multiplies x and y and stores the result in this.
ZeroOp Zero
Alias for the template parameter ZeroOp.
Definition matrix-class.hpp:1162
scalar_type scalar_zero() const noexcept
Returns the additive identity of the underlying semiring.
semiring_type const * semiring() const noexcept
Returns the underlying semiring.
OneOp One
Alias for the template parameter OneOp.
Definition matrix-class.hpp:1165
void semiring_type
Alias for the semiring type (void).
Definition matrix-class.hpp:1172
RowView row(size_t i) const
Returns a view into a row.
DynamicMatrix(RowView const &rv)
Construct a row from a row view.
Definition matrix-class.hpp:1299
iterator begin() noexcept
Returns an iterator pointing at the first entry.
size_t number_of_rows() const noexcept
Returns the number of rows of the matrix.
DynamicRowView< PlusOp, ProdOp, ZeroOp, OneOp, Scalar > RowView
The type of a row view into a DynamicMatrix.
Definition matrix-class.hpp:1153
void plus_inplace_no_checks(DynamicMatrix const &that)
Add a matrix to another matrix in-place.
DynamicMatrix product_no_checks(DynamicMatrix const &that)
Returns the product of two matrices.
RowView row_no_checks(size_t i) const
Returns a view into a row.
DynamicMatrix(std::vector< std::vector< scalar_type > > const &m)
Construct a matrix from std::vector of std::vector of scalars.
Definition matrix-class.hpp:1284
typename MatrixCommon::scalar_reference scalar_reference
The type of references to the entries in the matrix.
Definition matrix-class.hpp:1141
scalar_reference at(size_t r, size_t c) const
Returns a const reference to the specified entry of the matrix.
DynamicMatrix(DynamicMatrix const &)=default
Default copy constructor.
size_t hash_value() const
Return a hash value of a matrix.
const_iterator cbegin() noexcept
Returns a const iterator pointing at the first entry.
DynamicMatrix plus_no_checks(DynamicMatrix const &y) const
Returns the sum of two matrices.
DynamicMatrix(DynamicMatrix &&)=default
Default move constructor.
typename MatrixCommon::scalar_type scalar_type
The type of the entries in the matrix.
Definition matrix-class.hpp:1138
size_t number_of_cols() const noexcept
Returns the number of columns of the matrix.
std::pair< scalar_type, scalar_type > coords(const_iterator it) const
Get the coordinates of an iterator.
iterator end() noexcept
Returns an iterator pointing one beyond the last entry in the matrix.
DynamicMatrix(Semiring const *sr, std::initializer_list< std::initializer_list< scalar_type > > const &rws)
Construct a matrix over a given semiring (std::initializer_list of std::initializer_list).
DynamicMatrix & operator=(DynamicMatrix &&)=default
Default move assignment operator.
static DynamicMatrix one(Semiring const *semiring, size_t n)
Construct the identity matrix.
scalar_reference at(size_t r, size_t c)
Returns a reference to the specified entry of the matrix.
DynamicMatrix(Semiring const *sr, std::vector< std::vector< scalar_type > > const &rws)
Construct a matrix over a given semiring (std::vector of std::vector).
Definition matrix-class.hpp:1695
DynamicMatrix(Semiring const *sr, size_t r, size_t c)
Construct a matrix over a given semiring with given dimensions.
Definition matrix-class.hpp:1656
void product_inplace_no_checks(DynamicMatrix const &x, DynamicMatrix const &y)
Multiplies x and y and stores the result in this.
DynamicMatrix & operator=(DynamicMatrix const &)=default
Default copy assignment operator.
DynamicMatrix Row
Alias for the type of the rows of a DynamicMatrix.
Definition matrix-class.hpp:1613
void rows(T &x) const
Add row views for every row in the matrix to a container.
scalar_type scalar_one() const noexcept
Returns the multiplicative identity of the underlying semiring.
typename MatrixCommon::scalar_const_reference scalar_const_reference
Alias for const references to the template parameter Scalar.
Definition matrix-class.hpp:1609
void swap(DynamicMatrix &that) noexcept
Swaps the contents of *this with the contents of that.
const_iterator cend() noexcept
Returns a const iterator pointing one beyond the last entry in the matrix.
void product_inplace(DynamicMatrix const &x, DynamicMatrix const &y)
Multiplies x and y and stores the result in this.
scalar_type scalar_zero() const noexcept
Returns the additive identity of the underlying semiring.
void transpose_no_checks()
Transpose a matrix in-place.
semiring_type const * semiring() const noexcept
Returns the underlying semiring.
RowView row(size_t i) const
Returns a view into a row.
DynamicMatrix(RowView const &rv)
Construct a row over a given semiring (RowView).
Definition matrix-class.hpp:1729
iterator begin() noexcept
Returns an iterator pointing at the first entry.
size_t number_of_rows() const noexcept
Returns the number of rows of the matrix.
DynamicMatrix(Semiring const *sr, std::initializer_list< scalar_type > const &rw)
Construct a row over a given semiring (std::initializer_list).
Definition matrix-class.hpp:1714
void plus_inplace_no_checks(DynamicMatrix const &that)
Add a matrix to another matrix in-place.
DynamicMatrix product_no_checks(DynamicMatrix const &that)
Returns the product of two matrices.
RowView row_no_checks(size_t i) const
Returns a view into a row.
typename MatrixCommon::scalar_reference scalar_reference
Alias for references to the template parameter Scalar.
Definition matrix-class.hpp:1604
scalar_reference at(size_t r, size_t c) const
Returns a const reference to the specified entry of the matrix.
DynamicMatrix(DynamicMatrix const &)=default
Default copy constructor.
size_t hash_value() const
Return a hash value of a matrix.
const_iterator cbegin() noexcept
Returns a const iterator pointing at the first entry.
DynamicMatrix(DynamicMatrix &&)=default
Default move constructor.
typename MatrixCommon::scalar_type scalar_type
Alias for the template parameter Scalar.
Definition matrix-class.hpp:1601
DynamicRowView< Semiring, Scalar > RowView
Alias for the type of row views of a DynamicMatrix.
Definition matrix-class.hpp:1616
Semiring semiring_type
Alias for the template parameter Semiring.
Definition matrix-class.hpp:1621
size_t number_of_cols() const noexcept
Returns the number of columns of the matrix.
void transpose()
Transpose a matrix in-place.
std::pair< scalar_type, scalar_type > coords(const_iterator it) const
Get the coordinates of an iterator.
iterator end() noexcept
Returns an iterator pointing one beyond the last entry in the matrix.
Class representing a truncated max-plus semiring.
Definition matrix-class.hpp:2925
static constexpr Scalar scalar_zero() noexcept
Get the additive identity.
Definition matrix-class.hpp:2994
Scalar plus_no_checks(Scalar x, Scalar y) const noexcept
Addition in a truncated max-plus semiring.
Scalar product_no_checks(Scalar x, Scalar y) const noexcept
Multiplication in a truncated max-plus semiring.
MaxPlusTruncSemiring()=delete
Deleted default constructor.
Scalar threshold() const noexcept
Get the threshold.
Definition matrix-class.hpp:3062
static constexpr Scalar scalar_one() noexcept
Get the multiplicative identity.
Definition matrix-class.hpp:2980
Class representing a truncated min-plus semiring.
Definition matrix-class.hpp:3268
static constexpr Scalar scalar_zero() noexcept
Get the additive identity.
Definition matrix-class.hpp:3336
Scalar plus_no_checks(Scalar x, Scalar y) const noexcept
Addition in a truncated min-plus semiring.
Scalar product_no_checks(Scalar x, Scalar y) const noexcept
Multiplication in a truncated min-plus semiring.
Scalar threshold() const noexcept
Get the threshold.
Definition matrix-class.hpp:3404
static constexpr Scalar scalar_one() noexcept
Get the multiplicative identity.
Definition matrix-class.hpp:3321
MinPlusTruncSemiring()=delete
Deleted default constructor.
NTPSemiring & operator=(NTPSemiring const &)=default
Default copy assignment operator.
static constexpr Scalar scalar_zero() noexcept
Get the additive identity.
Definition matrix-class.hpp:3753
Scalar plus_no_checks(Scalar x, Scalar y) const noexcept
Addition in an ntp semiring.
Definition matrix-class.hpp:3811
NTPSemiring()=delete
Deleted default constructor.
Scalar product_no_checks(Scalar x, Scalar y) const noexcept
Multiplication in an ntp semiring.
Definition matrix-class.hpp:3781
Scalar period() const noexcept
Get the period.
Definition matrix-class.hpp:3845
Scalar threshold() const noexcept
Get the threshold.
Definition matrix-class.hpp:3829
static constexpr Scalar scalar_one() noexcept
Get the multiplicative identity.
Definition matrix-class.hpp:3737
Static matrix class.
Definition matrix-class.hpp:174
typename MatrixCommon::iterator iterator
Definition matrix-class.hpp:221
StaticMatrix(std::initializer_list< scalar_type > const &c)
Construct a row (from std::initializer_list).
typename MatrixCommon::const_iterator const_iterator
Definition matrix-class.hpp:224
scalar_const_reference at(size_t r, size_t c) const
Returns a const reference to the specified entry of the matrix.
scalar_reference at(size_t r, size_t c)
Returns a reference to the specified entry of the matrix.
StaticMatrix(StaticMatrix &&)=default
Default move constructor.
typename MatrixCommon::scalar_const_reference scalar_const_reference
Alias for const references to the template parameter Scalar.
Definition matrix-class.hpp:199
void product_inplace(StaticMatrix const &x, StaticMatrix const &y)
static constexpr size_t nr_rows
Definition matrix-class.hpp:227
scalar_reference operator()(size_t r, size_t c)
Returns a reference to the specified entry of the matrix.
void product_inplace_no_checks(StaticMatrix const &x, StaticMatrix const &y)
StaticMatrix(std::initializer_list< std::initializer_list< scalar_type > > const &m)
Construct a matrix.
Definition matrix-class.hpp:273
StaticRowView< PlusOp, ProdOp, ZeroOp, OneOp, C, Scalar > RowView
Definition matrix-class.hpp:206
static StaticMatrix one() const
Returns an identity matrix.
StaticMatrix(StaticMatrix const &)=default
Default copy constructor.
iterator begin() noexcept
Returns an iterator pointing at the first entry.
StaticMatrix(RowView const &rv)
Construct a row from a row view.
Definition matrix-class.hpp:309
StaticMatrix(std::vector< std::vector< scalar_type > > const &m)
Construct a matrix.
Definition matrix-class.hpp:289
StaticMatrix< PlusOp, ProdOp, ZeroOp, OneOp, 1, C, Scalar > Row
Alias for the type of the rows of a StaticMatrix.
Definition matrix-class.hpp:203
StaticMatrix()=default
Default constructor.
typename MatrixCommon::scalar_reference scalar_reference
Alias for references to the template parameter Scalar.
Definition matrix-class.hpp:194
typename MatrixCommon::scalar_type scalar_type
Alias for the template parameter Scalar.
Definition matrix-class.hpp:191
scalar_const_reference operator()(size_t r, size_t c) const
Returns a const reference to the specified entry of the matrix.
StaticMatrix & operator=(StaticMatrix &&)=default
Default move assignment operator.
StaticMatrix & operator=(StaticMatrix const &)=default
Default copy assignment operator.
std::pair< scalar_type, scalar_type > coords(const_iterator it) const
static constexpr size_t nr_cols
Definition matrix-class.hpp:230
Class for views into a row of a matrix over a semiring.
Definition matrix-view.hpp:92
T fill(T... args)
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
StaticMatrix< BooleanPlus, BooleanProd, BooleanZero, BooleanOne, R, C, int > StaticBMat
Alias for static boolean matrices.
Definition matrix-class.hpp:2144
DynamicMatrix< BooleanPlus, BooleanProd, BooleanZero, BooleanOne, int > DynamicBMat
Alias for dynamic boolean matrices.
Definition matrix-class.hpp:2130
std::conditional_t< R==0||C==0, DynamicBMat, StaticBMat< R, C > > BMat
Alias template for boolean matrices.
Definition matrix-class.hpp:2167
NegativeInfinity const NEGATIVE_INFINITY
Value for negative infinity.
Undefined const UNDEFINED
Value for something undefined.
PositiveInfinity const POSITIVE_INFINITY
Value for positive infinity.
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
StaticMatrix< IntegerPlus< Scalar >, IntegerProd< Scalar >, IntegerZero< Scalar >, IntegerOne< Scalar >, R, C, Scalar > StaticIntMat
Alias for static integer matrices.
Definition matrix-class.hpp:2355
std::conditional_t< R==0||C==0, DynamicIntMat< Scalar >, StaticIntMat< R, C, Scalar > > IntMat
Alias template for integer matrices.
Definition matrix-class.hpp:2380
DynamicMatrix< IntegerPlus< Scalar >, IntegerProd< Scalar >, IntegerZero< Scalar >, IntegerOne< Scalar >, Scalar > DynamicIntMat
Alias for dynamic integer matrices.
Definition matrix-class.hpp:2332
auto operator+(typename Mat::scalar_type a, Mat const &x) -> std::enable_if_t< IsMatrix< Mat >, Mat >
Add a scalar to a matrix.
Definition matrix-class.hpp:4441
constexpr bool IsMatrix
Helper variable template.
Definition is-matrix.hpp:87
std::conditional_t< R==0||C==0, DynamicMaxPlusMat< Scalar >, StaticMaxPlusMat< R, C, Scalar > > MaxPlusMat
Alias template for max-plus matrices.
Definition matrix-class.hpp:2591
StaticMatrix< MaxPlusPlus< Scalar >, MaxPlusProd< Scalar >, MaxPlusZero< Scalar >, IntegerZero< Scalar >, R, C, Scalar > StaticMaxPlusMat
Alias for static max-plus matrices.
Definition matrix-class.hpp:2567
DynamicMatrix< MaxPlusPlus< Scalar >, MaxPlusProd< Scalar >, MaxPlusZero< Scalar >, IntegerZero< Scalar >, Scalar > DynamicMaxPlusMat
Alias for dynamic max-plus matrices.
Definition matrix-class.hpp:2548
StaticMatrix< MaxPlusPlus< Scalar >, MaxPlusTruncProd< T, Scalar >, MaxPlusZero< Scalar >, IntegerZero< Scalar >, R, C, Scalar > StaticMaxPlusTruncMat
Alias for static truncated max-plus matrices.
Definition matrix-class.hpp:3103
DynamicMatrix< MaxPlusPlus< Scalar >, MaxPlusTruncProd< T, Scalar >, MaxPlusZero< Scalar >, IntegerZero< Scalar >, Scalar > DynamicMaxPlusTruncMat
Alias for dynamic truncated max-plus matrices.
Definition matrix-class.hpp:3083
std::conditional_t< R==0||C==0, std::conditional_t< T==0, DynamicMatrix< MaxPlusTruncSemiring< Scalar >, Scalar >, DynamicMaxPlusTruncMat< T, Scalar > >, StaticMaxPlusTruncMat< T, R, C, Scalar > > MaxPlusTruncMat
Alias template for truncated max-plus matrices.
Definition matrix-class.hpp:3129
DynamicMatrix< MinPlusPlus< Scalar >, MinPlusProd< Scalar >, MinPlusZero< Scalar >, IntegerZero< Scalar >, Scalar > DynamicMinPlusMat
Alias for dynamic min-plus matrices.
Definition matrix-class.hpp:2760
StaticMatrix< MinPlusPlus< Scalar >, MinPlusProd< Scalar >, MinPlusZero< Scalar >, IntegerZero< Scalar >, R, C, Scalar > StaticMinPlusMat
Alias for static min-plus matrices.
Definition matrix-class.hpp:2779
std::conditional_t< R==0||C==0, DynamicMinPlusMat< Scalar >, StaticMinPlusMat< R, C, Scalar > > MinPlusMat
Alias template for min-plus matrices.
Definition matrix-class.hpp:2803
std::conditional_t< R==0||C==0, std::conditional_t< T==0, DynamicMatrix< MinPlusTruncSemiring< Scalar >, Scalar >, DynamicMinPlusTruncMat< T, Scalar > >, StaticMinPlusTruncMat< T, R, C, Scalar > > MinPlusTruncMat
Alias template for truncated min-plus matrices.
Definition matrix-class.hpp:3472
DynamicMatrix< MinPlusPlus< Scalar >, MinPlusTruncProd< T, Scalar >, MinPlusZero< Scalar >, IntegerZero< Scalar >, Scalar > DynamicMinPlusTruncMat
Alias for dynamic truncated min-plus matrices.
Definition matrix-class.hpp:3425
StaticMatrix< MinPlusPlus< Scalar >, MinPlusTruncProd< T, Scalar >, MinPlusZero< Scalar >, IntegerZero< Scalar >, R, C, Scalar > StaticMinPlusTruncMat
Alias for static truncated min-plus matrices.
Definition matrix-class.hpp:3445
DynamicMatrix< NTPPlus< T, P, Scalar >, NTPProd< T, P, Scalar >, IntegerZero< Scalar >, IntegerOne< Scalar >, Scalar > DynamicNTPMatWithoutSemiring
Alias for ntp matrices with static threshold and period.
Definition matrix-class.hpp:3881
DynamicMatrix< NTPSemiring< Scalar >, Scalar > DynamicNTPMatWithSemiring
Alias for ntp matrices with dynamic threshold and period.
Definition matrix-class.hpp:3865
StaticMatrix< NTPPlus< T, P, Scalar >, NTPProd< T, P, Scalar >, IntegerZero< Scalar >, IntegerOne< Scalar >, R, C, Scalar > StaticNTPMat
Alias for ntp matrices with static threshold and period, and dimensions.
Definition matrix-class.hpp:3907
std::conditional_t< R==0||C==0, std::conditional_t< T==0 &&P==0, DynamicNTPMatWithSemiring< Scalar >, DynamicNTPMatWithoutSemiring< T, P, Scalar > >, StaticNTPMat< T, P, R, C, Scalar > > NTPMat
Alias template for ntp matrices.
Definition matrix-class.hpp:3942
std::conditional_t< R==0||C==0, DynamicProjMaxPlusMat< Scalar >, StaticProjMaxPlusMat< R, C, Scalar > > ProjMaxPlusMat
Alias template for projective max-plus matrices.
Definition matrix-class.hpp:4407
detail::ProjMaxPlusMat< DynamicMaxPlusMat< Scalar > > DynamicProjMaxPlusMat
Alias for dynamic projective max-plus matrices with run-time dimensions.
Definition matrix-class.hpp:4390
detail::ProjMaxPlusMat< StaticMaxPlusMat< R, C, Scalar > > StaticProjMaxPlusMat
Alias for static projective max-plus matrices with compile-time arithmetic and dimensions.
Definition matrix-class.hpp:4376
T move(T... args)
Bipartition one(Bipartition const &f)
Return the identity bipartition with the same degree as the given bipartition.
constexpr BMat8 transpose(BMat8 const &x) noexcept
Returns the transpose of a BMat8.
Definition bmat8.hpp:719
void throw_if_bad_coords(Mat const &x, size_t r, size_t c)
Throws the arguments do not index an entry of a matrix.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
Function object for returning the multiplicative identity.
Definition matrix-class.hpp:2078
constexpr bool operator()() const noexcept
Call operator returning the multiplication identity true of the boolean semiring.
Definition matrix-class.hpp:2089
Function object for addition in the boolean semiring.
Definition matrix-class.hpp:2024
constexpr bool operator()(bool x, bool y) const noexcept
Call operator for addition.
Definition matrix-class.hpp:2037
Function object for multiplication in the boolean semiring.
Definition matrix-class.hpp:2051
constexpr bool operator()(bool x, bool y) const noexcept
Call operator for multiplication.
Definition matrix-class.hpp:2064
Function object for returning the additive identity.
Definition matrix-class.hpp:2103
constexpr bool operator()() const noexcept
Call operator returning the additive identity false of the boolean semiring.
Definition matrix-class.hpp:2114
Function object for returning the multiplicative identity.
Definition matrix-class.hpp:2306
constexpr Scalar operator()() const noexcept
Call operator returning the integer 1.
Definition matrix-class.hpp:2316
Function object for addition in the ring of integers.
Definition matrix-class.hpp:2222
constexpr Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for addition.
Definition matrix-class.hpp:2235
Function object for multiplication in the ring of integers.
Definition matrix-class.hpp:2253
constexpr Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Definition matrix-class.hpp:2266
Function object for returning the additive identity.
Definition matrix-class.hpp:2281
constexpr Scalar operator()() const noexcept
Call operator returning the integer 0.
Definition matrix-class.hpp:2291
Function object for addition in the max-plus semiring.
Definition matrix-class.hpp:2448
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for addition.
Function object for multiplication in the max-plus semiring.
Definition matrix-class.hpp:2488
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Function object for multiplication in truncated max-plus semirings.
Definition matrix-class.hpp:2892
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Function object for returning the additive identity of the max-plus semiring.
Definition matrix-class.hpp:2520
constexpr Scalar operator()() const noexcept
Call operator for additive identity.
Definition matrix-class.hpp:2532
Function object for addition in the min-plus semiring.
Definition matrix-class.hpp:2660
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for addition.
Function object for multiplication in the min-plus semiring.
Definition matrix-class.hpp:2700
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Function object for multiplication in min-plus truncated semirings.
Definition matrix-class.hpp:3238
Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Function object for returning the additive identity of the min-plus semiring.
Definition matrix-class.hpp:2732
constexpr Scalar operator()() const noexcept
Call operator for additive identity.
Definition matrix-class.hpp:2744
Function object for addition in ntp semirings.
Definition matrix-class.hpp:3597
constexpr Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for addition.
Definition matrix-class.hpp:3609
Function object for multiplication in an ntp semirings.
Definition matrix-class.hpp:3638
constexpr Scalar operator()(Scalar x, Scalar y) const noexcept
Call operator for multiplication.
Definition matrix-class.hpp:3652
T swap(T... args)