My Project
Loading...
Searching...
No Matches
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
12namespace VectorUtil {
13
14
15template<typename T = std::size_t>
16std::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
42template <typename T = double>
43std::tuple<std::array<T,4>, std::array<T,4>, std::array<T,4>>
44appendNode(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::copy(X.begin(), X.end(), tX.begin());
51 tX[3]= xc;
52 std::copy(Y.begin(), Y.end(), tY.begin());
53 tY[3]= yc;
54 std::copy(Z.begin(), Z.end(), 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
60template <typename T, typename Operation>
61std::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::transform with the passed operation
68 std::transform(vecA.begin(), vecA.end(), 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
73template <typename T, typename Operation>
74std::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::transform with the passed operation
78 std::transform(vecA.begin(), vecA.end(), 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
84template <typename T, typename Operation>
85std::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::transform with the passed operation
89 std::transform(vecA.begin(), vecA.end(), std::back_inserter(result),
90 [&scalar, &op](const T& a) { return op(a, scalar); });
91 return result;
92}
93
94std::tuple<std::array<double,4>, std::array<double,4>, std::array<double,4>>
95appendNode(const std::array<double,3>&, const std::array<double,3>&,
96 const std::array<double,3>&, const double&, const double&,
97 const double&);
98template <typename T>
99std::vector<T> filterArray(const std::vector<std::size_t>& X, const std::vector<int>& ind){
100 std::vector<T> filtered_vectorX(ind.size(),0);
101 for (std::size_t index = 0; index < ind.size(); index++) {
102 filtered_vectorX[index] = X[ind[index]];
103 }
104 return filtered_vectorX;
105}
106
107// T type of the object
108// Rout type of the object output
109// Method type of method
110template <typename T, typename Rout, typename Rin = std::size_t, typename Method, typename... Args>
111std::vector<Rout> callMethodForEachInputOnObject(const T& obj, Method mtd, const std::vector<Rin>& input_vector, Args&&... args) {
112 std::vector<Rout> result;
113 // Reserve space for each vector in the tuple
114 result.reserve(input_vector.size());
115 // Iterate over the input_vector and fill the tuple's vectors
116 for (const auto& element : input_vector) {
117 Rout value = (obj.*mtd)(element, std::forward<Args>(args)...);
118 result.push_back(std::move(value));
119 }
120 return result;
121}
122
123
124
125template <typename T>
126std::tuple<std::vector<T>,std::vector<T>, std::vector<T>> splitXYZ(std::vector<std::array<T,3>>& input_vector ){
127std::vector<T> X, Y, Z;
128 X.reserve(input_vector.size());
129 Y.reserve(input_vector.size());
130 Z.reserve(input_vector.size());
131 for (auto& element : input_vector) {
132 X.push_back(std::move(element[0])); // Add to first vector
133 Y.push_back(std::move(element[1])); // Add to second vector
134 Z.push_back(std::move(element[2])); // Add to third vector
135 }
136 return std::make_tuple(X,Y,Z);
137}
138
139
140template <typename T, typename Rout, typename Rin = std::size_t, typename Method, typename... Args>
141auto callMethodForEachInputOnObjectXYZ(const T& obj, Method mtd, const std::vector<Rin>& input_vector, Args&&... args) {
142 using X = typename Rout::value_type;
143 auto result = callMethodForEachInputOnObject<T, Rout, Rin, Method, Args...>(obj, mtd, input_vector, std::forward<Args>(args)...);
144 return splitXYZ<X>(result);
145}
146
147// Example for other utilities...
148
149} // namespace VectorUtil
150
151#endif // VECTORUTIL_H