Stratax
Scientific computing containers and operations
Loading...
Searching...
No Matches
Slice.hpp
Go to the documentation of this file.
1#pragma once
2
11
12#include <array>
13#include <cstddef>
14#include <type_traits>
15#include <utility>
16
18
28template<std::size_t N, std::size_t... Is>
30 const std::array<stratax::core::Slice, N>& ranges,
31 std::index_sequence<Is...>)
32{
33 return stratax::core::Shape{ranges[Is].size()...};
34}
35
44template<std::size_t N>
46 const std::array<stratax::core::Slice, N>& ranges)
47{
48 return shape_from_slices_impl(ranges, std::make_index_sequence<N>{});
49}
50
51}
52
53template<typename T>
70)
71{
73 slice.stop(),
74 vec.size(),
75 "Vector slice out of bounds.");
76
77 auto begin = slice.start();
78 auto end = slice.stop();
79
81
82 for (std::size_t i = begin; i < end; ++i)
83 {
84 result[i - begin] = vec[i];
85 }
86
87 return result;
88
89}
90
91template<typename T>
108 const stratax::core::Slice& rows,
109 const stratax::core::Slice& cols
110)
111{
113 rows.stop(),
114 mat.rows(),
115 "Matrix row slice out of bounds.");
117 cols.stop(),
118 mat.cols(),
119 "Matrix column slice out of bounds.");
120
121 auto begin_rows = rows.start();
122 auto begin_cols = cols.start();
123
124 auto end_rows = rows.stop();
125 auto end_cols = cols.stop();
126
127 stratax::container::Matrix<T> result(rows.size(), cols.size());
128
129 for (std::size_t i = begin_rows; i < end_rows; ++i)
130 {
131 for (std::size_t j = begin_cols; j < end_cols; ++j)
132 {
133 result(i - begin_rows, j - begin_cols) = mat(i, j);
134 }
135 }
136
137 return result;
138}
139
140template<typename T, typename... Slices>
156 const stratax::container::Tensor<T>& tensor,
157 Slices... slices
158)
159{
160 static_assert(
161 (std::is_same_v<Slices, stratax::core::Slice> && ...),
162 "All arguments must be Slice."
163 );
164
165 std::array<stratax::core::Slice, sizeof...(Slices)> ranges{ slices... };
166
168 ranges.size(),
169 tensor.rank(),
170 "Slice rank must match tensor rank.");
171
172 for (std::size_t dim = 0; dim < ranges.size(); ++dim)
173 {
175 ranges[dim].stop(),
176 tensor.shape()(dim),
177 "Tensor slice out of bounds.");
178 }
179
180 const auto result_shape = stratax::ops::detail::shape_from_slices(ranges);
181 stratax::container::Tensor<T> result(result_shape);
182 const stratax::core::Strides result_strides(result_shape);
183 const auto& tensor_strides = tensor.strides();
184
185 if (result.empty())
186 {
187 return result;
188 }
189
190 for (std::size_t flat = 0; flat < result.size(); ++flat)
191 {
192 std::size_t remainder = flat;
193 std::size_t source_offset = 0;
194
195 for (std::size_t dim = 0; dim < ranges.size(); ++dim)
196 {
197 const std::size_t index = remainder / result_strides(dim);
198 remainder %= result_strides(dim);
199 const std::size_t source_index =
201 ranges[dim].start(),
202 index,
203 "Tensor slice offset overflow.");
204 const std::size_t term =
206 source_index,
207 tensor_strides(dim),
208 "Tensor slice offset overflow.");
209 source_offset =
211 source_offset,
212 term,
213 "Tensor slice offset overflow.");
214 }
215
216 result[flat] = tensor[source_offset];
217 }
218
219 return result;
220}
Shared runtime validation helpers.
std::size_t rows() const noexcept
Returns the number of rows.
Definition Matrix.hpp:181
std::size_t cols() const noexcept
Returns the number of columns.
Definition Matrix.hpp:191
const core::Shape & shape() const noexcept
Returns the tensor shape.
Definition Tensor.hpp:144
std::size_t rank() const noexcept
Returns the tensor rank.
Definition Tensor.hpp:134
bool empty() const noexcept
Returns whether the tensor contains no elements.
Definition Tensor.hpp:124
std::size_t size() const noexcept
Returns the total number of elements in the tensor.
Definition Tensor.hpp:114
const core::Strides & strides() const noexcept
Returns the tensor strides.
Definition Tensor.hpp:154
std::size_t size() const noexcept
Returns the number of stored elements.
Definition Vector.hpp:261
Stores a list of dimension lengths for an array shape.
Definition Shape.hpp:20
Represents a half-open range of indices.
Definition Slice.hpp:16
std::size_t stop() const noexcept
Returns the index one past the end of the slice.
Definition Slice.hpp:56
std::size_t size() const noexcept
Returns the number of indices covered by the slice.
Definition Slice.hpp:66
std::size_t start() const noexcept
Returns the first index in the slice.
Definition Slice.hpp:46
Stores strides for a shape in contiguous memory.
Definition Strides.hpp:23
std::size_t checked_multiply(std::size_t lhs, std::size_t rhs, const char *message)
Multiplies two sizes while checking for overflow.
void require_at_most(std::size_t value, std::size_t upper, const char *message)
Requires a value to be less than or equal to an upper bound.
void require_rank(std::size_t actual, std::size_t expected, const char *message)
Requires a rank value to match an expected rank.
std::size_t checked_add(std::size_t lhs, std::size_t rhs, const char *message)
Adds two sizes while checking for overflow.
stratax::core::Shape shape_from_slices(const std::array< stratax::core::Slice, N > &ranges)
Builds a shape from a slice array.
Definition Slice.hpp:45
stratax::core::Shape shape_from_slices_impl(const std::array< stratax::core::Slice, N > &ranges, std::index_sequence< Is... >)
Builds a shape from a compile-time slice array.
Definition Slice.hpp:29
stratax::container::Vector< T > slice(const stratax::container::Vector< T > &vec, const stratax::core::Slice &slice)
Copies a half-open range from a vector.
Definition Slice.hpp:67