opm-common
VectorUtil.hpp
1 #ifndef VECTORUTIL_H
2 #define VECTORUTIL_H
3 
4 #include <algorithm>
5 #include <array>
6 #include <cstddef>
7 #include <stdexcept>
8 #include <tuple>
9 #include <vector>
10 #include <iterator>
11 
12 namespace VectorUtil {
13 
14 
15 template<typename T = std::size_t>
16 std::tuple<std::vector<T>, std::vector<T>, std::vector<T>> generate_cartesian_product(std::size_t low_nx, std::size_t up_nx,
17  std::size_t low_ny, std::size_t up_ny,
18  std::size_t low_nz, std::size_t up_nz){
19  std::size_t list_size = (up_nx - low_nx + 1) * (up_ny - low_ny + 1) * (up_nz - low_nz + 1);
20  std::vector<T> i_list(list_size);
21  std::vector<T> j_list(list_size);
22  std::vector<T> k_list(list_size);
23  std::size_t index = 0;
24  for (std::size_t k_index = low_nz; k_index <= up_nz; k_index++)
25  {
26  for (std::size_t j_index = low_ny; j_index <= up_ny; j_index++)
27  {
28  for (std::size_t i_index = low_nx; i_index <= up_nx; i_index++)
29  {
30  i_list[index] = i_index;
31  j_list[index] = j_index;
32  k_list[index] = k_index;
33  index++;
34  }
35  }
36  }
37  return std::make_tuple(i_list, j_list, k_list);
38 
39 }
40 
41 
42 template <typename T = double>
43 std::tuple<std::array<T,4>, std::array<T,4>, std::array<T,4>>
44 appendNode(const std::array<T,3>& X, const std::array<T,3>& Y, const std::array<T,3>& Z,
45  const T& xc, const T& yc, const T& zc)
46 {
47  std::array<T,4> tX;
48  std::array<T,4> tY;
49  std::array<T,4> tZ;
50  std::ranges::copy(X, tX.begin());
51  tX[3]= xc;
52  std::ranges::copy(Y, tY.begin());
53  tY[3]= yc;
54  std::ranges::copy(Z, tZ.begin());
55  tZ[3]= zc;
56  return std::make_tuple(tX,tY,tZ);
57 }
58 
59 // Implementation of generation General Operation between two vectors of the same type
60 template <typename T, typename Operation>
61 std::vector<T> vectorOperation(const std::vector<T>& vecA, const std::vector<T>& vecB, Operation op) {
62  if (vecA.size() != vecB.size()) {
63  throw std::invalid_argument("Error: Vectors must have the same size!"); // Throwing exception
64  }
65  std::vector<T> result;
66  result.reserve(vecA.size());
67  // Use std::ranges::transform with the passed operation
68  std::ranges::transform(vecA, vecB.begin(), std::back_inserter(result), op);
69  return result;
70 }
71 
72 // Implementation of generation General Operation between a vector and a scalar of the same type
73 template <typename T, typename Operation>
74 std::vector<T> vectorScalarOperation(const std::vector<T>& vecA, const T& scalar, Operation op) {
75  std::vector<T> result;
76  result.reserve(vecA.size());
77  // Use std::ranges::transform with the passed operation
78  std::ranges::transform(vecA, std::back_inserter(result),
79  [&scalar, &op](const T& a) { return op(scalar, a); });
80  return result;
81 }
82 
83 // Implementation of generation General Operation between a scalar and a vector of the same type
84 template <typename T, typename Operation>
85 std::vector<T> scalarVectorOperation(const T& scalar, const std::vector<T>& vecA, Operation op) {
86  std::vector<T> result;
87  result.reserve(vecA.size());
88  // Use std::ranges::transform with the passed operation
89  std::ranges::transform(vecA, std::back_inserter(result),
90  [&scalar, &op](const T& a) { return op(a, scalar); });
91  return result;
92 }
93 
94 
95 template <typename T, typename Operation>
96 void scalarVectorOperation(const T& scalar, std::vector<T>& vecA, Operation op) {
97  std::ranges::transform(vecA, vecA.begin(),
98  [&scalar, &op](const T& a) { return op(a, scalar); });
99 }
100 
101 
102 std::tuple<std::array<double,4>, std::array<double,4>, std::array<double,4>>
103 appendNode(const std::array<double,3>&, const std::array<double,3>&,
104  const std::array<double,3>&, const double&, const double&,
105  const double&);
106 
107 template <typename T>
108 std::vector<T> filterArray(const std::vector<T>& X, const std::vector<int>& ind){
109  std::vector<T> filtered_vectorX(ind.size(),0);
110  for (std::size_t index = 0; index < ind.size(); index++) {
111  filtered_vectorX[index] = X[ind[index]];
112  }
113  return filtered_vectorX;
114 }
115 
116 template <typename T>
117 std::vector<T> filterArray(const std::vector<std::size_t>& X, const std::vector<int>& ind){
118  std::vector<T> filtered_vectorX(ind.size(),0);
119  for (std::size_t index = 0; index < ind.size(); index++) {
120  filtered_vectorX[index] = X[ind[index]];
121  }
122  return filtered_vectorX;
123 }
124 
125 // T type of the object
126 // Rout type of the object output
127 // Method type of method
128 template <typename T, typename Rout, typename Rin = std::size_t, typename Method, typename... Args>
129 std::vector<Rout> callMethodForEachInputOnObject(const T& obj, Method mtd, const std::vector<Rin>& input_vector, Args&&... args) {
130  std::vector<Rout> result;
131  // Reserve space for each vector in the tuple
132  result.reserve(input_vector.size());
133  // Iterate over the input_vector and fill the tuple's vectors
134  for (const auto& element : input_vector) {
135  Rout value = (obj.*mtd)(element, std::forward<Args>(args)...);
136  result.push_back(std::move(value));
137  }
138  return result;
139 }
140 
141 
142 
143 template <typename T>
144 std::tuple<std::vector<T>,std::vector<T>, std::vector<T>> splitXYZ(std::vector<std::array<T,3>>& input_vector ){
145 std::vector<T> X, Y, Z;
146  X.reserve(input_vector.size());
147  Y.reserve(input_vector.size());
148  Z.reserve(input_vector.size());
149  for (auto& element : input_vector) {
150  X.push_back(std::move(element[0])); // Add to first vector
151  Y.push_back(std::move(element[1])); // Add to second vector
152  Z.push_back(std::move(element[2])); // Add to third vector
153  }
154  return std::make_tuple(X,Y,Z);
155 }
156 
157 
158 template <typename T, typename Rout, typename Rin = std::size_t, typename Method, typename... Args>
159 auto callMethodForEachInputOnObjectXYZ(const T& obj, Method mtd, const std::vector<Rin>& input_vector, Args&&... args) {
160  using X = typename Rout::value_type;
161  auto result = callMethodForEachInputOnObject<T, Rout, Rin, Method, Args...>(obj, mtd, input_vector, std::forward<Args>(args)...);
162  return splitXYZ<X>(result);
163 }
164 
165 // Example for other utilities...
166 
167 } // namespace VectorUtil
168 
169 #endif // VECTORUTIL_H
Definition: VectorUtil.cpp:3