48inline auto VSlice(torch::Tensor index, int64_t start_offset,
49 int64_t stop_offset) {
50 if (stop_offset <= start_offset)
51 throw std::invalid_argument(
52 "VSlice requires stop_offset to be greater than start_offset");
54 if constexpr (transpose)
55 return index.repeat_interleave(stop_offset - start_offset) +
56 torch::linspace(start_offset, stop_offset - 1,
57 stop_offset - start_offset, index.options())
58 .repeat(index.numel());
60 return index.repeat(stop_offset - start_offset) +
61 torch::linspace(start_offset, stop_offset - 1,
62 stop_offset - start_offset, index.options())
63 .repeat_interleave(index.numel());
81 const std::array<int64_t, N> &start_offset,
82 const std::array<int64_t, N> &stop_offset,
83 const std::array<int64_t, N - 1> &leading_dim =
84 make_array<int64_t, N - 1>(1)) {
87 for (std::size_t i = 1; i < N; ++i)
88 if (index[i - 1].numel() != index[i].numel())
89 throw std::invalid_argument(
90 "VSlice requires index tensors with equal lengths");
92 for (std::size_t i = 0; i < N; ++i)
93 if (stop_offset[i] <= start_offset[i])
94 throw std::invalid_argument(
95 "VSlice requires every stop offset to exceed its start offset");
97 auto dist = stop_offset - start_offset;
99 if constexpr (transpose) {
102 auto vslice_summand_ = [&](std::size_t k) {
104 return (index[k].repeat_interleave(
utils::prod(dist, 0, k)) +
105 torch::linspace(start_offset[k], stop_offset[k] - 1, dist[k],
108 .repeat(index[0].numel())) *
111 if constexpr (N == 2) {
112 return index[0].repeat_interleave(dist[0]).repeat_interleave(
114 torch::linspace(start_offset[0], stop_offset[0] - 1, dist[0],
116 .repeat(index[1].numel())
119 return index[0].repeat_interleave(dist[0]).repeat_interleave(
121 torch::linspace(start_offset[0], stop_offset[0] - 1, dist[0],
123 .repeat(index[0].numel())
129 .repeat_interleave(
utils::prod(dist, k + 1, N - 1)) +
130 torch::linspace(start_offset[k], stop_offset[k] - 1, dist[k],
133 .repeat(index[0].numel())
140 auto vslice_ = [&]<std::size_t... Is>(std::index_sequence<Is...>) {
141 return (vslice_summand_(Is) + ...);
144 return vslice_(std::make_index_sequence<N>{});
148 auto vslice_summand_ = [&](std::size_t k) {
151 torch::linspace(start_offset[k], stop_offset[k] - 1, dist[k],
153 .repeat_interleave(index[0].numel() *
157 if constexpr (N == 2) {
158 return (index[0].repeat(dist[0]) +
159 torch::linspace(start_offset[0], stop_offset[0] - 1, dist[0],
161 .repeat_interleave(index[0].numel()))
164 return (index[0].repeat(dist[0]) +
165 torch::linspace(start_offset[0], stop_offset[0] - 1, dist[0],
167 .repeat_interleave(index[0].numel()))
172 torch::linspace(start_offset[k], stop_offset[k] - 1, dist[k],
174 .repeat_interleave(index[0].numel() *
182 auto vslice_ = [&]<std::size_t... Is>(std::index_sequence<Is...>) {
183 return (vslice_summand_(Is) + ...);
186 return vslice_(std::make_index_sequence<N>{});
T prod(std::array< T, N > array, std::size_t start_index=0, std::size_t stop_index=N - 1)
Computes the (partial) product of all std::array entries.
Definition linalg.hpp:239