/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #include "xtensor/containers/xarray.hpp" #include "xtensor/containers/xtensor.hpp" #include "xtensor/core/xnoalias.hpp" #include "xtensor/generators/xbuilder.hpp" #include "xtensor/generators/xrandom.hpp" #include "xtensor/io/xio.hpp" #include "xtensor/views/xdynamic_view.hpp" #include "xtensor/views/xindex_view.hpp" #include "xtensor/views/xview.hpp" #include "test_common_macros.hpp" namespace xt { using shape_t = std::vector; using view_shape_type = dynamic_shape; TEST(xdynamic_view, keep) { xarray a = { {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}, {{12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23}} }; auto view0 = dynamic_view(a, xdynamic_slice_vector({1, keep(0, 2), range(1, 4)})); EXPECT_EQ(view0.dimension(), size_t(2)); EXPECT_EQ(view0.shape()[0], size_t(2)); EXPECT_EQ(view0.shape()[1], size_t(3)); EXPECT_EQ(view0(0, 0), a(1, 0, 1)); EXPECT_EQ(view0(0, 1), a(1, 0, 2)); EXPECT_EQ(view0(0, 2), a(1, 0, 3)); EXPECT_EQ(view0(1, 0), a(1, 2, 1)); EXPECT_EQ(view0(1, 1), a(1, 2, 2)); EXPECT_EQ(view0(1, 2), a(1, 2, 3)); auto view1 = dynamic_view(a, xdynamic_slice_vector({all(), 1, keep(0, 2, 3)})); EXPECT_EQ(view1.dimension(), size_t(2)); EXPECT_EQ(view1.shape()[0], size_t(2)); EXPECT_EQ(view1.shape()[1], size_t(3)); EXPECT_EQ(view1(0, 0), a(0, 1, 0)); EXPECT_EQ(view1(0, 1), a(0, 1, 2)); EXPECT_EQ(view1(0, 2), a(0, 1, 3)); EXPECT_EQ(view1(1, 0), a(1, 1, 0)); EXPECT_EQ(view1(1, 1), a(1, 1, 2)); EXPECT_EQ(view1(1, 2), a(1, 1, 3)); auto view2 = dynamic_view(a, {all(), 1, keep(0, 2, 3)}); EXPECT_EQ(view1, view2); auto view3 = dynamic_view(a, {all(), 1, newaxis(), keep(0, 2, 3)}); EXPECT_EQ(view3.dimension(), size_t(3)); EXPECT_EQ(view3.shape()[0], size_t(2)); EXPECT_EQ(view3.shape()[1], size_t(1)); EXPECT_EQ(view3.shape()[2], size_t(3)); EXPECT_EQ(view3(0, 0, 0), a(0, 1, 0)); EXPECT_EQ(view3(0, 0, 1), a(0, 1, 2)); EXPECT_EQ(view3(0, 0, 2), a(0, 1, 3)); EXPECT_EQ(view3(1, 0, 0), a(1, 1, 0)); EXPECT_EQ(view3(1, 0, 1), a(1, 1, 2)); EXPECT_EQ(view3(1, 0, 2), a(1, 1, 3)); auto view4 = dynamic_view(a, {1, keep(0, 2), xrange(1, 4)}); EXPECT_EQ(view0, view4); auto view5 = dynamic_view(a, {1, keep(0, 2), xstepped_range(1, 4, 1)}); EXPECT_EQ(view0, view5); } TEST(xdynamic_view, keep_iterator) { xarray a = { {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}, {{12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23}} }; auto view0 = dynamic_view(a, xdynamic_slice_vector({1, keep(0, 2), range(1, 4)})); auto iter = view0.template begin(); auto iter_end = view0.template end(); EXPECT_EQ(*iter, a(1, 0, 1)); ++iter; EXPECT_EQ(*iter, a(1, 0, 2)); ++iter; EXPECT_EQ(*iter, a(1, 0, 3)); ++iter; EXPECT_EQ(*iter, a(1, 2, 1)); ++iter; EXPECT_EQ(*iter, a(1, 2, 2)); ++iter; EXPECT_EQ(*iter, a(1, 2, 3)); ++iter; EXPECT_EQ(iter, iter_end); } TEST(xdynamic_view, drop) { xarray a = { {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}, {{12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23}} }; auto view0 = dynamic_view(a, xdynamic_slice_vector({1, drop(1), range(1, 4)})); EXPECT_EQ(view0.dimension(), size_t(2)); EXPECT_EQ(view0.shape()[0], size_t(2)); EXPECT_EQ(view0.shape()[1], size_t(3)); EXPECT_EQ(view0(0, 0), a(1, 0, 1)); EXPECT_EQ(view0(0, 1), a(1, 0, 2)); EXPECT_EQ(view0(0, 2), a(1, 0, 3)); EXPECT_EQ(view0(1, 0), a(1, 2, 1)); EXPECT_EQ(view0(1, 1), a(1, 2, 2)); EXPECT_EQ(view0(1, 2), a(1, 2, 3)); auto view1 = dynamic_view(a, xdynamic_slice_vector({all(), 1, drop(1, 2)})); EXPECT_EQ(view1.dimension(), size_t(2)); EXPECT_EQ(view1.shape()[0], size_t(2)); EXPECT_EQ(view1.shape()[1], size_t(2)); EXPECT_EQ(view1(0, 0), a(0, 1, 0)); EXPECT_EQ(view1(0, 1), a(0, 1, 3)); EXPECT_EQ(view1(1, 0), a(1, 1, 0)); EXPECT_EQ(view1(1, 1), a(1, 1, 3)); auto view3 = dynamic_view(a, {all(), 1, newaxis(), drop(1, 2)}); EXPECT_EQ(view3.dimension(), size_t(3)); EXPECT_EQ(view3.shape()[0], size_t(2)); EXPECT_EQ(view3.shape()[1], size_t(1)); EXPECT_EQ(view3.shape()[2], size_t(2)); EXPECT_EQ(view3(0, 0, 0), a(0, 1, 0)); EXPECT_EQ(view3(0, 0, 1), a(0, 1, 3)); EXPECT_EQ(view3(1, 0, 0), a(1, 1, 0)); EXPECT_EQ(view3(1, 0, 1), a(1, 1, 3)); } TEST(xdynamic_view, drop_iterator) { xarray a = { {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}, {{12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23}} }; auto view0 = dynamic_view(a, xdynamic_slice_vector({1, drop(1), range(1, 4)})); auto iter = view0.template begin(); auto iter_end = view0.template end(); EXPECT_EQ(*iter, a(1, 0, 1)); ++iter; EXPECT_EQ(*iter, a(1, 0, 2)); ++iter; EXPECT_EQ(*iter, a(1, 0, 3)); ++iter; EXPECT_EQ(*iter, a(1, 2, 1)); ++iter; EXPECT_EQ(*iter, a(1, 2, 2)); ++iter; EXPECT_EQ(*iter, a(1, 2, 3)); ++iter; EXPECT_EQ(iter, iter_end); } TEST(xdynamic_view, semantic) { xarray a = { {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}, {{12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23}} }; xarray b1 = {{13, 14, 15}, {21, 22, 23}}; xarray b2 = {{0, 1, 2}, {3, 4, 5}}; xarray exp = b1 + b2; auto view0 = dynamic_view(a, {1, keep(0, 2), range(1, 4)}); view0 += b2; EXPECT_EQ(view0, exp); } TEST(xdynamic_view, slice_conversion) { xrange ru(std::size_t(1), std::size_t(12)); xrange rs = ru; EXPECT_EQ(rs.size(), 11); EXPECT_EQ(rs(0), 1); auto rs2 = ru.convert(); EXPECT_EQ(rs2, rs); xstepped_range sru(std::size_t(1), std::size_t(5), std::size_t(2)); xstepped_range srs = sru; EXPECT_EQ(srs.size(), 2); EXPECT_EQ(srs(0), 1); EXPECT_EQ(srs.step_size(), 2); auto srs2 = sru.convert(); EXPECT_EQ(srs2, srs); xall au(std::size_t(11)); xall as(au); EXPECT_EQ(as.size(), 11); EXPECT_EQ(as(0), 0); auto as2 = au.convert(); EXPECT_EQ(as2, as); xnewaxis nau; xnewaxis nas(nau); EXPECT_EQ(nas.size(), 1); EXPECT_EQ(nas(0), 0); auto nas2 = nau.convert(); EXPECT_EQ(nas2, nas); xkeep_slice ks({2, 3, -1}); ks.normalize(6); xkeep_slice ku(ks); EXPECT_EQ(ku.size(), std::size_t(3)); EXPECT_FALSE(ku.contains(0)); EXPECT_FALSE(ku.contains(1)); EXPECT_TRUE(ku.contains(2)); EXPECT_TRUE(ku.contains(3)); EXPECT_FALSE(ku.contains(4)); EXPECT_TRUE(ku.contains(5)); auto ks2 = ku.convert(); EXPECT_EQ(ks2, ks); xdrop_slice ds({2, 3, -1}); ds.normalize(6); xdrop_slice du(ds); EXPECT_EQ(du.size(), std::size_t(3)); EXPECT_TRUE(du.contains(0)); EXPECT_TRUE(du.contains(1)); EXPECT_FALSE(du.contains(2)); EXPECT_FALSE(du.contains(3)); EXPECT_TRUE(du.contains(4)); EXPECT_FALSE(du.contains(5)); auto ds2 = du.convert(); EXPECT_EQ(ds2, ds); } TEST(xdynamic_view, compilation_linux_issue_1349) { xt::xarray array(xt::random::rand({5, 4})); auto v = xt::view(array, xt::keep(2), xt::all()); auto res = xt::xarray(xt::dynamic_view(v, {xt::keep(0)})); EXPECT_EQ(res(1), array(2, 1)); } TEST(xdynamic_view, assignment) { xt::xarray x = {{1, 4}, {2, 5}, {3, 6}}; xt::xdynamic_slice_vector sv({}); sv.push_back(xt::all()); sv.push_back(xt::all()); auto res = xt::dynamic_view(x, sv); xt::xarray xrs = res; EXPECT_EQ(x, res); } }