From 4b4e548ab73f48cda36b83f3ee7d3eae8cafd220 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Thu, 29 Oct 2026 18:50:04 +0100 Subject: [PATCH] Fix xview::element when a newaxis precedes an integral slice make_index maps each dimension i of the underlying expression to its slice k, then to the position of that slice in the view index: k minus the number of integral slices before it. It counted the integral slices before i instead of before k. The two differ when a newaxis comes before an integral slice, so the wrong index was read: xt::xarray a = {{0, 1, 2}, {3, 4, 5}}; auto v = xt::view(a, xt::newaxis(), 1, xt::all()); v[{0, 2}]; // returned 3 instead of 5 operator() already used the slice position. element(), and the operator[] and at-style accesses built on it, now do too. --- include/xtensor/views/xview.hpp | 2 +- test/test_xview.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/xtensor/views/xview.hpp b/include/xtensor/views/xview.hpp index c647572de..951454063 100644 --- a/include/xtensor/views/xview.hpp +++ b/include/xtensor/views/xview.hpp @@ -1707,7 +1707,7 @@ namespace xt // need to advance captured `first` first = first_copy; - std::advance(first, static_cast(k - xt::integral_count_before(i))); + std::advance(first, static_cast(k - xt::integral_count_before(k))); if (first < last) { diff --git a/test/test_xview.cpp b/test/test_xview.cpp index 8069bb016..8e5f7d533 100644 --- a/test/test_xview.cpp +++ b/test/test_xview.cpp @@ -1736,6 +1736,28 @@ namespace xt EXPECT_EQ(res, 2); } + TEST(xview, element_newaxis_before_integral) + { + xarray a = xt::arange(24).reshape({2, 3, 4}); + + // The newaxis shifts the view dimensions that follow the integral slice. + auto v = view(a, newaxis(), 1, all()); + auto w = view(a, newaxis(), keep(1), 0, newaxis(), drop(0, 3)); + for (std::size_t j = 0; j < 3; ++j) + { + for (std::size_t k = 0; k < 4; ++k) + { + xindex idx = {0, j, k}; + EXPECT_EQ(v[idx], a(1, j, k)); + } + } + for (std::size_t k = 0; k < 2; ++k) + { + xindex idx = {0, 0, 0, k}; + EXPECT_EQ(w[idx], a(1, 0, k + 1)); + } + } + TEST(xview, view_reshape_view) { xtensor a = {0, 1, 2};