libsemigroups  v3.6.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
matrix-helpers.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 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#ifndef LIBSEMIGROUPS_MATRIX_HELPERS_HPP_
20#define LIBSEMIGROUPS_MATRIX_HELPERS_HPP_
21
22#include <algorithm> // for sort, fill, min
23#include <bitset> // for bitset
24#include <cstddef> // for size_t
25#include <type_traits> // for enable_if_t
26#include <unordered_map> // for unordered_map
27#include <unordered_set> // for unordered_set
28#include <utility> // for move, forward
29#include <vector> // for vector
30
31#include "bitset.hpp" // for BitSet, IsBitSet
32#include "constants.hpp" // for UNDEFINED
33#include "debug.hpp" // for LIBSEMIGROUPS_...
34#include "exception.hpp" // for LIBSEMIGROUPS_...
35#include "is-matrix.hpp" // for IsBMat, IsStat...
36#include "matrix-class.hpp" // for DynamicNTPMatW...
37
38#include "detail/containers.hpp" // for StaticVector1
39#include "detail/matrix-exceptions.hpp" // for throw_if_not_s...
40
41namespace libsemigroups {
42 namespace detail {
43 template <typename T>
44 struct IsStdBitSetHelper : std::false_type {};
45
46 template <size_t N>
47 struct IsStdBitSetHelper<std::bitset<N>> : std::true_type {};
48
49 template <typename T>
50 static constexpr bool IsStdBitSet = IsStdBitSetHelper<T>::value;
51
52 template <typename T>
53 struct BitSetCapacity {
54 static constexpr size_t value = BitSet<1>::max_size();
55 };
56
57 template <size_t R, size_t C>
58 struct BitSetCapacity<StaticBMat<R, C>> {
59 static_assert(R == C, "the number of rows and columns must be equal");
60 static constexpr size_t value = R;
61 };
62
63 } // namespace detail
64
73 namespace matrix {
74
88 template <typename Mat>
89 [[nodiscard]] constexpr auto threshold(Mat const&) noexcept
90 -> std::enable_if_t<!detail::IsTruncMat<Mat>,
91 typename Mat::scalar_type> {
92 return UNDEFINED;
93 }
94
108 template <typename Mat>
109 [[nodiscard]] constexpr auto threshold(Mat const&) noexcept
110 -> std::enable_if_t<detail::IsTruncMat<Mat> && !IsMatWithSemiring<Mat>,
111 typename Mat::scalar_type> {
112 return detail::IsTruncMatHelper<Mat>::threshold;
113 }
114
130 template <typename Mat>
131 [[nodiscard]] auto threshold(Mat const& x) noexcept
132 -> std::enable_if_t<detail::IsTruncMat<Mat> && IsMatWithSemiring<Mat>,
133 typename Mat::scalar_type> {
134 return x.semiring()->threshold();
135 }
136
158 template <size_t T, size_t P, size_t R, size_t C, typename Scalar>
159 [[nodiscard]] constexpr Scalar
161 return P;
162 }
163
181 template <size_t T, size_t P, typename Scalar>
182 [[nodiscard]] constexpr Scalar
184 return P;
185 }
186
202 template <typename Scalar>
203 [[nodiscard]] Scalar
205 return x.semiring()->period();
206 }
207
209 // Matrix helpers - pow
211
246 // TODO(1) pow_no_checks
247 // TODO(2) version that changes x in-place
248 template <typename Mat>
249 [[nodiscard]] Mat pow(Mat const& x, typename Mat::scalar_type e);
250
252 // Matrix helpers - rows
254
274 template <typename Mat, typename = std::enable_if_t<IsDynamicMatrix<Mat>>>
275 [[nodiscard]] std::vector<typename Mat::RowView> rows(Mat const& x) {
277 x.rows(container);
278 return container;
279 }
280
301 template <typename Mat, typename = std::enable_if_t<IsStaticMatrix<Mat>>>
302 [[nodiscard]] detail::StaticVector1<typename Mat::RowView, Mat::nr_rows>
303 rows(Mat const& x) {
304 detail::StaticVector1<typename Mat::RowView, Mat::nr_rows> container;
305 x.rows(container);
306 return container;
307 }
308
310 // Matrix helpers - bitset_rows
312
344 template <typename Mat, size_t R, size_t C, typename Container>
345 void bitset_rows(Container&& views,
346 detail::StaticVector1<BitSet<C>, R>& result);
347
380 template <typename Mat, size_t R, size_t C, typename Container>
381 [[nodiscard]] auto bitset_rows(Container&& views);
382
411 template <typename Mat, size_t R, size_t C>
412 void bitset_rows(Mat const& x, detail::StaticVector1<BitSet<C>, R>& result);
413
432 template <typename Mat>
433 [[nodiscard]] auto bitset_rows(Mat const& x);
434
436 // Matrix helpers - bitset_row_basis
438
461 // This works with std::vector and StaticVector1, with value_type equal
462 // to std::bitset and BitSet.
463 template <typename Mat, typename Container>
464 void bitset_row_basis(Container&& rows, std::decay_t<Container>& result);
465
489 template <typename Mat, typename Container>
490 [[nodiscard]] std::decay_t<Container> bitset_row_basis(Container&& rows);
491
519 template <typename Mat, size_t M = detail::BitSetCapacity<Mat>::value>
520 [[nodiscard]] detail::StaticVector1<BitSet<M>, M>
521 bitset_row_basis(Mat const& x);
522
546 template <typename Mat, typename Container>
547 void bitset_row_basis(Mat const& x, Container& result);
548
550 // Matrix helpers - row_basis - MaxPlusTruncMat
552
580 template <typename Mat, typename Container>
581 std::enable_if_t<IsMaxPlusTruncMat<Mat>>
582 row_basis(Container&& views, std::decay_t<Container>& result);
583
585 // Matrix helpers - row_basis - BMat
587
588 // This version of row_basis for BMat's is used for compatibility
589 // with the MatrixCommon framework, i.e. so that BMat's exhibit the same
590 // interface/behaviour as other matrices.
591 //
592 // This version takes a container of row views of BMat, converts it to a
593 // container of BitSets, computes the row basis using the BitSets, then
594 // selects those row views in views that belong to the computed basis.
595
613 // TODO(2) complexity
614 template <typename Mat, typename Container>
615 std::enable_if_t<IsBMat<Mat>> row_basis(Container&& views,
616 std::decay_t<Container>& result);
617
619 // Matrix helpers - row_basis - generic helpers
621
643 // Row basis of rowspace of matrix <x> appended to <result>
644 template <typename Mat,
645 typename Container,
646 typename = std::enable_if_t<IsMatrix<Mat>>>
647 void row_basis(Mat const& x, Container& result) {
648 row_basis<Mat>(rows(x), result);
649 }
650
670 // Row basis of rowspace of matrix <x>
671 template <typename Mat, typename = std::enable_if_t<IsDynamicMatrix<Mat>>>
672 [[nodiscard]] std::vector<typename Mat::RowView> row_basis(Mat const& x) {
674 row_basis(x, container);
675 return container;
676 }
677
697 template <typename Mat, typename = std::enable_if_t<IsStaticMatrix<Mat>>>
698 [[nodiscard]] detail::StaticVector1<typename Mat::RowView, Mat::nr_rows>
699 row_basis(Mat const& x) {
700 detail::StaticVector1<typename Mat::RowView, Mat::nr_rows> container;
701 row_basis(x, container);
702 return container;
703 }
704
723 // TODO(2) complexity
724 template <typename Mat,
725 typename Container,
726 typename = std::enable_if_t<!IsMatrix<std::decay_t<Container>>>>
727 [[nodiscard]] std::decay_t<Container> row_basis(Container&& rows);
728
729 // TODO move
730 template <typename T>
731 struct RowSum {
732 void operator()(T& res, T const& pt, T const& x) const {
733 res = pt;
734 res += x;
735 }
736 };
737
738 // TODO(doc)
739 template <typename Mat,
740 typename Container,
741 typename = std::enable_if_t<IsMatrix<Mat>>>
742 void row_basis_rows(Mat const& x, Container& result);
743
744 // TODO(doc)
745 template <typename Mat,
746 typename Container,
747 typename = std::enable_if_t<IsStaticMatrix<Mat>>>
748 [[nodiscard]] detail::StaticVector1<typename Mat::Row, Mat::nr_rows>
749 row_basis_rows(Mat const& x);
750
751 // TODO(doc)
752 template <typename Mat,
753 typename Container,
754 typename = std::enable_if_t<IsDynamicMatrix<Mat>>>
755 [[nodiscard]] std::vector<typename Mat::Row> row_basis_rows(Mat const& x) {
757 row_basis_rows(x, container);
758 return container;
759 }
760
761 // This modifies the argument rows by moving out those in the basis
762 template <typename Mat,
763 typename Container,
764 typename = std::enable_if_t<IsStaticMatrix<Mat>>>
765 [[nodiscard]] detail::StaticVector1<typename Mat::Row, Mat::nr_rows>
766 row_basis_rows(Container&& rows);
767
769 // Matrix helpers - row_space_size
771
802 template <typename Mat, typename = std::enable_if_t<IsBMat<Mat>>>
803 [[nodiscard]] size_t row_space_size(Mat const& x);
804 } // namespace matrix
805} // namespace libsemigroups
806
807#include "matrix-helpers.tpp"
808#endif // LIBSEMIGROUPS_MATRIX_HELPERS_HPP_
StaticMatrix< BooleanPlus, BooleanProd, BooleanZero, BooleanOne, R, C, int > StaticBMat
Alias for static boolean matrices.
Definition matrix-class.hpp:2144
Undefined const UNDEFINED
Value for something undefined.
static constexpr bool IsMatWithSemiring
Helper variable template.
Definition is-matrix.hpp:127
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
Namespace for helper functions for matrices.
Definition matrix-exceptions.hpp:37
void bitset_row_basis(Container &&rows, std::decay_t< Container > &result)
Appends a basis for the space spanned by some bitsets to a container.
void bitset_rows(Container &&views, detail::StaticVector1< BitSet< C >, R > &result)
Converts a container of row views of a boolean matrix to bit sets, and append them to another contain...
constexpr Scalar period(StaticNTPMat< T, P, R, C, Scalar > const &) noexcept
Returns the period of a static ntp matrix.
Definition matrix-helpers.hpp:160
constexpr auto threshold(Mat const &) noexcept -> std::enable_if_t<!detail::IsTruncMat< Mat >, typename Mat::scalar_type >
Returns the threshold of a matrix.
Definition matrix-helpers.hpp:89
size_t row_space_size(Mat const &x)
Returns the size of the row space of a boolean matrix.
std::vector< typename Mat::RowView > rows(Mat const &x)
Returns a std::vector of row views into the rows of a dynamic matrix.
Definition matrix-helpers.hpp:275
Mat pow(Mat const &x, typename Mat::scalar_type e)
Returns a power of a matrix.
std::enable_if_t< IsMaxPlusTruncMat< Mat > > row_basis(Container &&views, std::decay_t< Container > &result)
Appends a basis for a space spanned by row views or bit sets to a container.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44