Stratax 0.3.1
Loading...
Searching...
No Matches
Conversion.hpp
1#pragma once
2
3#include <algorithm>
4#include <cstddef>
5#include <vector>
6
7#include <stratax/containers/Matrix.hpp>
8#include <stratax/containers/Tensor.hpp>
9#include <stratax/containers/Vector.hpp>
10#include <stratax/core/ArrayTraits.hpp>
11#include <stratax/core/dtypes/Concepts.hpp>
12#include <stratax/core/Shape.hpp>
13#include <stratax/exceptions/Exceptions.hpp>
14
15namespace stratax::conversion {
16
17namespace detail {
18
31inline bool is_vector_shape(const stratax::core::Shape& shape)
32{
33 if (shape.rank() == 1)
34 {
35 return true;
36 }
37
38 std::size_t non_singleton = 0;
39
40 for (std::size_t dim : shape)
41 {
42 if (dim > 1)
43 {
44 ++non_singleton;
45 }
46 }
47
48 return non_singleton == 1;
49}
50
63inline bool is_matrix_shape(const stratax::core::Shape& shape)
64{
65 if (shape.rank() == 2)
66 {
67 return true;
68 }
69
70 std::size_t non_singleton = 0;
71
72 for (std::size_t dim : shape)
73 {
74 if (dim > 1)
75 {
76 ++non_singleton;
77 }
78 }
79
80 return non_singleton == 2;
81}
82
97inline stratax::core::Shape matrix_shape(const stratax::core::Shape& shape)
98{
99 if (shape.rank() == 2)
100 {
101 return shape;
102 }
103
104 std::vector<std::size_t> dims;
105 dims.reserve(2);
106
107 for (std::size_t dim : shape)
108 {
109 if (dim > 1)
110 {
111 dims.push_back(dim);
112 }
113 }
114
115 return stratax::core::Shape(dims);
116}
117
118} // namespace detail
119
134template<Array A>
135[[nodiscard]]
136stratax::container::Vector<typename A::value_type>
137to_vector(const A& arr)
138{
139 if (!detail::is_vector_shape(arr.shape()))
140 {
141 throw Exceptions::ShapeError(
142 "Array cannot be converted to a Vector.");
143 }
144
145 stratax::container::Vector<typename A::value_type> result(arr.size());
146
147 std::copy(
148 arr.begin(),
149 arr.end(),
150 result.begin());
151
152 return result;
153}
154
171template<Array A>
172[[nodiscard]]
173stratax::container::Matrix<typename A::value_type>
174to_matrix(const A& arr)
175{
176 if (!detail::is_matrix_shape(arr.shape()))
177 {
178 throw Exceptions::ShapeError(
179 "Array cannot be converted to a Matrix.");
180 }
181
182 const stratax::core::Shape shape =
183 detail::matrix_shape(arr.shape());
184
185 stratax::container::Matrix<typename A::value_type> result(shape);
186
187 std::copy(
188 arr.begin(),
189 arr.end(),
190 result.begin());
191
192 return result;
193}
194
208template<Array A>
209[[nodiscard]]
210stratax::container::Tensor<typename A::value_type>
211to_tensor(const A& arr)
212{
213 stratax::container::Tensor<typename A::value_type> result(arr.shape());
214
215 std::copy(
216 arr.begin(),
217 arr.end(),
218 result.begin());
219
220 return result;
221}
222
242template<DType To, Array A>
243[[nodiscard]]
244stratax::core::rebind_array_t<A, To>
245astype(const A& arr)
246{
247 using result_type =
248 stratax::core::rebind_array_t<A, To>;
249
250 result_type result(arr.shape());
251
252 std::transform(
253 arr.begin(),
254 arr.end(),
255 result.begin(),
256 [](const auto& value)
257 {
258 return static_cast<To>(value);
259 });
260
261 return result;
262}
263
264} // namespace stratax::conversion
size_type rank() const noexcept
Returns the number of dimensions.
Definition Shape.hpp:122