4#ifndef TETL_LINALG_EXPOSITION_HPP
5#define TETL_LINALG_EXPOSITION_HPP
7#include <etl/_complex/complex.hpp>
8#include <etl/_concepts/same_as.hpp>
9#include <etl/_concepts/unsigned_integral.hpp>
10#include <etl/_math/abs.hpp>
11#include <etl/_mdspan/layout.hpp>
12#include <etl/_mdspan/layout_left.hpp>
13#include <etl/_mdspan/layout_right.hpp>
14#include <etl/_mdspan/mdspan.hpp>
15#include <etl/_numeric/abs.hpp>
16#include <etl/_type_traits/always_false.hpp>
17#include <etl/_type_traits/bool_constant.hpp>
18#include <etl/_type_traits/common_type.hpp>
19#include <etl/_type_traits/declval.hpp>
20#include <etl/_type_traits/is_arithmetic.hpp>
21#include <etl/_type_traits/is_same.hpp>
22#include <etl/_type_traits/remove_const.hpp>
26template <
typename... Ts>
27using common_index_type_t = common_type_t<
typename Ts::index_type...>;
29namespace linalg_adl_checks {
37auto abs(T
const&) -> T =
delete;
39auto conj(T
const&) -> T =
delete;
41auto real(T
const&) -> T =
delete;
43auto imag(T
const&) -> T =
delete;
46concept has_abs =
requires { abs(declval<T>()); };
49concept has_conj =
requires { conj(declval<T>()); };
52concept has_real =
requires { real(declval<T>()); };
55concept has_imag =
requires { imag(declval<T>()); };
60concept has_adl_abs = linalg_adl_checks::has_abs<T>;
63concept has_adl_conj = linalg_adl_checks::has_conj<T>;
66concept has_adl_real = linalg_adl_checks::has_real<T>;
69concept has_adl_imag = linalg_adl_checks::has_imag<T>;
71inline constexpr auto abs_if_needed = []<
typename T>(T
const& val) {
72 if constexpr (unsigned_integral<T>) {
74 }
else if constexpr (is_arithmetic_v<T>) {
76 }
else if constexpr (has_adl_abs<T>) {
79 static_assert(always_false<T>);
83inline constexpr auto conj_if_needed = []<
typename T>(T
const& val) {
84 if constexpr (
not is_arithmetic_v<T>
and has_adl_conj<T>) {
91inline constexpr auto real_if_needed = []<
typename T>(T
const& val) {
92 if constexpr (
not is_arithmetic_v<T>
and has_adl_real<T>) {
99inline constexpr auto imag_if_needed = []<
typename T>(T
const& val) {
100 if constexpr (
not is_arithmetic_v<T>
and has_adl_imag<T>) {
113concept in_vector = is_mdspan_v<T>
and T::rank() == 1;
117concept out_vector = is_mdspan_v<T>
119 and same_as<remove_const_t<
typename T::element_type>,
typename T::element_type>
120 and T::is_always_unique();
124concept inout_vector = is_mdspan_v<T>
126 and same_as<remove_const_t<
typename T::element_type>,
typename T::element_type>
127 and T::is_always_unique();
131concept in_matrix = is_mdspan_v<T>
and T::rank() == 2;
135concept out_matrix = is_mdspan_v<T>
137 and is_same_v<remove_const_t<
typename T::element_type>,
typename T::element_type>
138 and T::is_always_unique();
142concept inout_matrix = is_mdspan_v<T>
144 and is_same_v<remove_const_t<
typename T::element_type>,
typename T::element_type>
145 and T::is_always_unique();
149concept in_object = is_mdspan_v<T>
and (T::rank() == 1
or T::rank() == 2);
153concept out_object = is_mdspan_v<T>
154 and (T::rank() == 1
or T::rank() == 2)
155 and is_same_v<remove_const_t<
typename T::element_type>,
typename T::element_type>
156 and T::is_always_unique();
160concept inout_object = is_mdspan_v<T>
161 and (T::rank() == 1
or T::rank() == 2)
162 and is_same_v<remove_const_t<
typename T::element_type>,
typename T::element_type>
163 and T::is_always_unique();
167template <
typename MDS1,
typename MDS2>
168 requires(is_mdspan_v<MDS1>
and is_mdspan_v<MDS2>)
169[[nodiscard]]
constexpr auto compatible_static_extents(
etl::size_t r1,
etl::size_t r2) ->
bool
173 or MDS1::static_extent(r1) == MDS2::static_extent(r2);
176template <in_vector In1, in_vector In2, in_vector Out>
177[[nodiscard]]
constexpr auto possibly_addable() ->
bool
179 return compatible_static_extents<Out, In1>(0, 0)
180 and compatible_static_extents<Out, In2>(0, 0)
181 and compatible_static_extents<In1, In2>(0, 0);
184template <in_matrix In1, in_matrix In2, in_matrix Out>
185[[nodiscard]]
constexpr auto possibly_addable() ->
bool
187 return compatible_static_extents<Out, In1>(0, 0)
188 and compatible_static_extents<Out, In1>(1, 1)
189 and compatible_static_extents<Out, In2>(0, 0)
190 and compatible_static_extents<Out, In2>(1, 1)
191 and compatible_static_extents<In1, In2>(0, 0)
192 and compatible_static_extents<In1, In2>(1, 1);
195template <in_matrix InMat, in_vector InVec, in_vector OutVec>
196[[nodiscard]]
constexpr auto possibly_multipliable() ->
bool
198 return compatible_static_extents<OutVec, InMat>(0, 0)
and compatible_static_extents<InMat, InVec>(1, 0);
201template <in_vector InVec, in_matrix InMat, in_vector OutVec>
202[[nodiscard]]
constexpr auto possibly_multipliable() ->
bool
204 return compatible_static_extents<OutVec, InMat>(0, 1)
and compatible_static_extents<InMat, InVec>(0, 0);
207template <in_matrix InMat1, in_matrix InMat2, in_matrix OutMat>
208[[nodiscard]]
constexpr auto possibly_multipliable() ->
bool
210 return compatible_static_extents<OutMat, InMat1>(0, 0)
211 and compatible_static_extents<OutMat, InMat2>(1, 1)
212 and compatible_static_extents<InMat1, InMat2>(1, 0);
215[[nodiscard]]
constexpr auto addable(in_vector
auto const& in1, in_vector
auto const& in2, in_vector
auto const& out)
218 return out.extent(0) == in1.extent(0)
and out.extent(0) == in2.extent(0);
221[[nodiscard]]
constexpr auto addable(in_matrix
auto const& in1, in_matrix
auto const& in2, in_matrix
auto const& out)
224 return out.extent(0) == in1.extent(0)
225 and out.extent(1) == in1.extent(1)
226 and out.extent(0) == in2.extent(0)
227 and out.extent(1) == in2.extent(1);
230[[nodiscard]]
constexpr auto
231multipliable(in_matrix
auto const& inMat, in_vector
auto const& inVec, in_vector
auto const& outVec) ->
bool
233 return outVec.extent(0) == inMat.extent(0)
and inMat.extent(1) == inVec.extent(0);
236[[nodiscard]]
constexpr auto
237multipliable(in_vector
auto const& inVec, in_matrix
auto const& inMat, in_vector
auto const& outVec) ->
bool
239 return outVec.extent(0) == inMat.extent(1)
and inMat.extent(0) == inVec.extent(0);
242[[nodiscard]]
constexpr auto
243multipliable(in_matrix
auto const& inMat1, in_matrix
auto const& inMat2, in_matrix
auto const& outMat) ->
bool
245 return outMat.extent(0) == inMat1.extent(0)
246 and outMat.extent(1) == inMat2.extent(1)
247 and inMat1.extent(1) == inMat2.extent(0);
constexpr auto dynamic_extent
etl::dynamic_extent is a constant of type etl::size_t that is used to differentiate etl::span of stat...
Definition dynamic_extent.hpp:15
Definition accessor_conjugate.hpp:13
Definition adjacent_find.hpp:9