Xped
Loading...
Searching...
No Matches
Constfct.hpp
Go to the documentation of this file.
1#ifndef XPED_CONSTFCT_H_
2#define XPED_CONSTFCT_H_
3
4#include "seq/seq.h"
5
7
8template <std::size_t Rank>
9constexpr std::size_t trimDim(std::size_t leg)
10{
11 if(leg < Rank) { return Rank - 1; }
12 return Rank;
13}
14
15template <std::size_t Rank>
16constexpr std::size_t shift(std::size_t x, std::size_t /*unused*/)
17{
18 return x + Rank;
19}
20
21template <std::size_t Rank>
22constexpr bool isGreaterOrEqual(std::size_t x, std::size_t /*unused*/)
23{
24 return x >= Rank;
25}
26
27template <std::size_t Rank>
28constexpr bool isSmaller(std::size_t x, std::size_t /*unused*/)
29{
30 return x < Rank;
31}
32
33template <typename Perm, typename Perm::value_type... Is>
34constexpr auto inverse_perm_impl(seq::iseq<typename Perm::value_type, Is...>)
35{
36 return seq::iseq<typename Perm::value_type, seq::index_of<Is, Perm>...>{};
37}
38
39template <typename Perm, typename Indices = seq::make<typename Perm::value_type, Perm::size()>>
40constexpr auto inverse_permutation()
41{
42 return inverse_perm_impl<Perm>(Indices{});
43}
44
45template <int N>
46inline constexpr int posmod(int x)
47{
48 return (x % N + N) % N;
49}
50
51inline constexpr int posmod(int x, int N) { return (x % N + N) % N; }
52
53#if XPED_HAS_NTTP
54template <auto a1, std::size_t rank1, auto a2, std::size_t rank2, std::size_t rankres>
55consteval auto get_permutations()
56{
57 constexpr auto r1 = a1.size();
58 constexpr auto r2 = a2.size();
59 using value_type = typename decltype(a1)::value_type;
60 std::array<std::size_t, r1> ind1;
61 std::iota(ind1.begin(), ind1.end(), 0);
62 std::array<std::size_t, r2> ind2;
63 std::iota(ind2.begin(), ind2.end(), 0);
64
65 constexpr int max1 = std::max(0, *std::max_element(a1.begin(), a1.end()));
66 constexpr int max2 = std::max(0, *std::max_element(a2.begin(), a2.end()));
67 static_assert(max1 == max2);
68
69 std::array<std::size_t, r2> p2{};
70 std::array<int, r2> found2;
71 std::fill(found2.begin(), found2.end(), -1);
72 std::transform(ind2.begin(), ind2.begin() + max2, p2.begin(), [&found2](std::size_t ind) {
73 auto val = std::distance(a2.begin(), std::find(a2.begin(), a2.end(), ind + 1));
74 found2[ind] = val;
75 return val;
76 });
77 std::transform(ind2.begin() + max2, ind2.end(), p2.begin() + max2, [ind2, &found2](std::size_t ind) {
78 auto val =
79 *std::find_if(ind2.begin(), ind2.end(), [found2](std::size_t i) { return std::find(found2.begin(), found2.end(), i) == found2.end(); });
80 found2[ind] = val;
81 return val;
82 });
83
84 std::array<std::size_t, r1> p1{};
85 std::array<int, r1> found1;
86 std::fill(found1.begin(), found1.end(), -1);
87 std::transform(ind1.begin(), ind1.begin() + max1, p1.begin() + a1.size() - max1, [&found1](std::size_t ind) {
88 auto val = std::distance(a1.begin(), std::find(a1.begin(), a1.end(), ind + 1));
89 found1[ind] = val;
90 return val;
91 });
92 std::transform(ind1.begin() + max1, ind1.end(), p1.begin(), [ind1, &found1](std::size_t ind) {
93 auto val =
94 *std::find_if(ind1.begin(), ind1.end(), [found1](std::size_t i) { return std::find(found1.begin(), found1.end(), i) == found1.end(); });
95 found1[ind] = val;
96 return val;
97 });
98 std::array<std::size_t, r1 + r2 - 2 * max1> pres{};
99 std::iota(pres.begin(), pres.end(), 0);
100 std::array<value_type, r1 + r2 - 2 * max1> tmp{};
101 auto second_half = std::copy_if(a1.begin(), a1.end(), tmp.begin(), [](int i) { return i < 0; });
102 std::copy_if(a2.begin(), a2.end(), second_half, [](int i) { return i < 0; });
103 std::sort(pres.begin(), pres.end(), [tmp](std::size_t i, std::size_t j) { return tmp[i] > tmp[j]; });
104 constexpr int shift1 = static_cast<value_type>(rank1) - static_cast<value_type>(a1.size()) + static_cast<value_type>(max1);
105 constexpr int shift2 = static_cast<value_type>(rank2) - static_cast<value_type>(max2);
106 constexpr int shiftres = static_cast<value_type>(a1.size()) - static_cast<value_type>(max1) - static_cast<value_type>(rankres);
107 return std::make_tuple(p1, shift1, p2, shift2, pres, shiftres);
108}
109
110template <const auto A, typename decltype(A)::value_type... Is>
111auto as_sequence_impl(seq::iseq<typename decltype(A)::value_type, Is...>)
112{
113 return seq::iseq<typename decltype(A)::value_type, A[Is]...>{};
114}
115
116template <const auto A, typename Indices = seq::make<typename decltype(A)::value_type, std::tuple_size<decltype(A)>::value>>
117auto as_sequence()
118{
119 return as_sequence_impl<A>(Indices{});
120}
121
122#endif
123} // namespace Xped::util::constFct
124#endif
Definition: Constfct.hpp:6
constexpr std::size_t trimDim(std::size_t leg)
Definition: Constfct.hpp:9
constexpr std::size_t shift(std::size_t x, std::size_t)
Definition: Constfct.hpp:16
constexpr auto inverse_perm_impl(seq::iseq< typename Perm::value_type, Is... >)
Definition: Constfct.hpp:34
constexpr auto inverse_permutation()
Definition: Constfct.hpp:40
constexpr bool isSmaller(std::size_t x, std::size_t)
Definition: Constfct.hpp:28
constexpr int posmod(int x)
Definition: Constfct.hpp:46
constexpr bool isGreaterOrEqual(std::size_t x, std::size_t)
Definition: Constfct.hpp:22
@ A
Definition: SubLattice.hpp:10