TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
permutation.hpp
Go to the documentation of this file.
1// Copyright (c) 2019-2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Olivier Parcollet, Nils Wentzell
16
23#pragma once
24
25#include "../macros.hpp"
26#include "../stdutil/array.hpp"
28
29#include <algorithm>
30#include <array>
31#include <concepts>
32#include <cstddef>
33#include <cstdint>
34
35namespace nda {
36
53 template <size_t N>
54 constexpr std::array<int, N> decode(uint64_t binary_representation) {
56 for (int i = 0; i < N; ++i) result[i] = (binary_representation >> (4 * i)) & 0b1111ull;
57 return result;
58 }
59
70 template <size_t N>
71 constexpr uint64_t encode(std::array<int, N> const &a) {
72 uint64_t result = 0;
73 for (int i = 0; i < N; ++i) {
74 EXPECTS(0 <= a[i] and a[i] <= 15);
75 result += (static_cast<uint64_t>(a[i]) << (4 * i));
76 }
77 return result;
78 }
79
82} // namespace nda
83
84namespace nda::permutations {
85
102 template <std::integral Int, size_t N>
103 constexpr bool is_valid(std::array<Int, N> const &p) {
104 auto idx_counts = stdutil::make_initialized_array<N>(0);
105 for (auto idx : p) {
106 if (idx < 0 or idx > N - 1 or idx_counts[idx] > 0) return false;
107 idx_counts[idx] = 1;
108 }
109 return true;
110 }
111
124 template <std::integral Int, size_t N>
125 constexpr std::array<Int, N> compose(std::array<Int, N> const &p1, std::array<Int, N> const &p2) {
126 EXPECTS(is_valid(p1));
127 EXPECTS(is_valid(p2));
128 auto result = stdutil::make_initialized_array<N>(0);
129 for (int u = 0; u < N; ++u) result[u] = p1[p2[u]];
130 return result;
131 }
132
144 template <std::integral Int, size_t N>
145 constexpr std::array<Int, N> inverse(std::array<Int, N> const &p) {
146 EXPECTS(is_valid(p));
147 auto result = stdutil::make_initialized_array<N>(0);
148 for (int u = 0; u < N; ++u) result[p[u]] = u;
149 return result;
150 }
151
164 template <typename T, std::integral Int, size_t N>
165 constexpr std::array<T, N> apply_inverse(std::array<Int, N> const &p, std::array<T, N> const &a) {
166 EXPECTS(is_valid(p));
168 for (int u = 0; u < N; ++u) result[p[u]] = a[u];
169 return result;
170 }
171
185 template <typename T, std::integral Int, size_t N>
186 constexpr std::array<T, N> apply(std::array<Int, N> const &p, std::array<T, N> const &a) {
187 EXPECTS(is_valid(p));
189 for (int u = 0; u < N; ++u) result[u] = a[p[u]];
190 return result;
191 }
192
199 template <size_t N>
200 constexpr std::array<int, N> identity() {
201 auto result = stdutil::make_initialized_array<N>(0);
202 for (int i = 0; i < N; ++i) result[i] = i;
203 return result;
204 }
205
212 template <size_t N>
213 constexpr std::array<int, N> reverse_identity() {
214 auto result = stdutil::make_initialized_array<N>(0);
215 for (int i = 0; i < N; ++i) result[i] = N - 1 - i;
216 return result;
217 }
218
229 template <size_t N>
230 constexpr std::array<int, N> transposition(int i, int j) {
231 auto r = identity<N>();
232 r[i] = j;
233 r[j] = i;
234 return r;
235 }
236
248 template <size_t N>
249 constexpr std::array<int, N> cycle(int p, int pos = N) {
250 auto result = stdutil::make_initialized_array<N>(0);
251 pos = std::clamp(pos, 0, static_cast<int>(N));
252 for (int i = 0; i < N; ++i) result[i] = (i < pos ? (pos + i - p) % pos : i);
253 return result;
254 }
255
258} // namespace nda::permutations
Provides utility functions for std::array.
constexpr std::array< int, N > transposition(int i, int j)
Get the permutation representing a single given transposition.
constexpr std::array< Int, N > inverse(std::array< Int, N > const &p)
Inverse of a permutation.
constexpr std::array< int, N > decode(uint64_t binary_representation)
Decode a uint64_t into a std::array<int, N>.
constexpr bool is_valid(std::array< Int, N > const &p)
Check if a given array is a valid permutation.
constexpr std::array< T, N > apply_inverse(std::array< Int, N > const &p, std::array< T, N > const &a)
Apply the inverse of a permutation to a std::array.
constexpr std::array< int, N > identity()
Get the identity permutation.
constexpr uint64_t encode(std::array< int, N > const &a)
Encode a std::array<int, N> in a uint64_t.
constexpr std::array< int, N > reverse_identity()
Get the reverse identity permutation.
constexpr std::array< int, N > cycle(int p, int pos=N)
Perform a forward (partial) cyclic permutation of the identity p times.
constexpr std::array< Int, N > compose(std::array< Int, N > const &p1, std::array< Int, N > const &p2)
Composition of two permutations.
constexpr std::array< T, N > apply(std::array< Int, N > const &p, std::array< T, N > const &a)
Apply a permutation to a std::array.
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
Definition array.hpp:168
Macros used in the nda library.
Provides missing concepts for older compiler versions.