vector/utility.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 // Copyright (c) 2020-2021 Ilias Khairullin <ilias@nil.foundation>
5 //
6 // MIT License
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //---------------------------------------------------------------------------//
26 
27 #ifndef CRYPTO3_ALGEBRA_VECTOR_UTILITY_HPP
28 #define CRYPTO3_ALGEBRA_VECTOR_UTILITY_HPP
29 
31 
32 #include <tuple>
33 
34 namespace nil {
35  namespace crypto3 {
36  namespace algebra {
37 
50  template<typename F, typename T, typename... Vectors,
51  typename U = std::invoke_result_t<F, T, typename Vectors::value_type...>,
52  std::size_t N = detail::all_same_value<std::size_t, Vectors::size...>::value>
53  constexpr vector<U, N> elementwise(F f, const vector<T, N> &v, const Vectors &...vectors) {
54  vector<U, N> op_applied = {};
55  for (std::size_t i = 0; i < N; ++i)
56  op_applied[i] = std::apply(f, std::forward_as_tuple(v[i], vectors[i]...));
57  return op_applied;
58  }
59 
69  template<typename T, std::size_t N, typename F, typename U>
70  constexpr U accumulate(const vector<T, N> &v, U init, F &&f) {
71  U r = init;
72  for (std::size_t i = 0; i < vector<T, N>::size; ++i)
73  r = std::apply(std::forward<F>(f), std::forward_as_tuple(r, v[i]));
74  return r;
75  }
76 
83  template<typename T, typename U, std::size_t N>
84  constexpr vector<T, N> cast(const vector<U, N> &v) {
85  return elementwise([](const U u) { return static_cast<T>(u); }, v);
86  }
87 
94  template<std::size_t N, typename T>
95  constexpr vector<T, N> iota(T value = T()) {
96  vector<T, N> seq = {};
97  for (auto &x : seq) {
98  x = value;
99  value += 1; // equivalent to value++, see GCC Bug 91705
100  }
101  return seq;
102  }
103 
111  template<std::size_t N, typename T>
112  constexpr vector<T, N> linspace(T min, T max) {
113  return ((max - min) / (N - 1)) * iota<N, T>() + min;
114  }
115 
122  template<std::size_t N, typename T>
123  constexpr vector<T, N> fill(T value) {
124  vector<T, N> filled = {};
125  for (auto &x : filled)
126  x = value;
127  return filled;
128  }
129 
136  template<std::size_t N, typename F>
137  constexpr decltype(auto) generate(F &&f) {
138  return elementwise(f, iota<N, std::size_t>());
139  }
140 
149  template<std::size_t N, typename T>
150  constexpr vector<T, N> rotate(vector<T, N> v, int n) {
151  vector<T, N> rotated = {};
152  // add N (the modulus) to n until it is positive
153  while (n < 0)
154  n += N;
155  for (std::size_t i = 0; i < N; ++i)
156  rotated[i] = v[(i + n) % N];
157  return rotated;
158  }
159 
169  template<std::size_t M, typename T, std::size_t N>
170  constexpr vector<T, M> slice(vector<T, N> v, std::size_t start = 0) {
171 
172  vector<T, M> sliced = {};
173  for (std::size_t i = 0; i < M; ++i)
174  sliced[i] = v[i + start];
175 
176  return sliced;
177  }
178 
188  template<typename T, std::size_t N, std::size_t M>
190  vector<T, N + M> concatted = {};
191  for (std::size_t i = 0; i < N; ++i)
192  concatted[i] = a[i];
193  for (std::size_t i = 0; i < M; ++i)
194  concatted[i + N] = b[i];
195  return concatted;
196  }
197 
200  } // namespace algebra
201  } // namespace crypto3
202 } // namespace nil
203 #endif // CRYPTO3_ALGEBRA_VECTOR_UTILITY_HPP
constexpr decltype(auto) generate(F &&f)
generates a matrix as a function of its indices
Definition: matrix/utility.hpp:84
constexpr matrix< U, N, M > elementwise(F f, const matrix< T, N, M > &m, const Matrices &...matrices)
applies a function elementwise between many matrices
Definition: matrix/utility.hpp:55
constexpr matrix< T, N, M > fill(T value)
generates a matrix containing a single value
Definition: matrix/utility.hpp:102
constexpr matrix< T, N, M > cast(const matrix< U, N, M > &m)
casts a vector to another type
Definition: matrix/utility.hpp:72
constexpr T min(const vector< T, N > &v)
computes the minimum valued element
Definition: algebra/include/nil/crypto3/algebra/vector/math.hpp:135
constexpr vector< T, N > iota(T value=T())
generates a vector containing consecutive elements
Definition: vector/utility.hpp:95
constexpr vector< T, N > rotate(vector< T, N > v, int n)
shifts vector elements
Definition: vector/utility.hpp:150
constexpr vector< T, N+M > concat(vector< T, N > a, vector< T, M > b)
concatenates two vectors
Definition: vector/utility.hpp:189
constexpr vector< T, N > linspace(T min, T max)
generates a vector of equally spaced elements
Definition: vector/utility.hpp:112
constexpr vector< T, M > slice(vector< T, N > v, std::size_t start=0)
slices a vector into a subvector
Definition: vector/utility.hpp:170
constexpr U accumulate(const vector< T, N > &v, U init, F &&f)
accumulates an operation across a vector
Definition: vector/utility.hpp:70
constexpr T max(const vector< T, N > &v)
computes the maximum valued element
Definition: algebra/include/nil/crypto3/algebra/vector/math.hpp:146
Definition: pair.hpp:31
A container representing a vector.
Definition: vector.hpp:50