C++23(或更高版本)使用索引向量提取数组元素的简洁方法?

C++23 (or later) succinct way to extract elements of an array using an index vector?

提问人:Astor 提问时间:9/28/2023 最后编辑:Astor 更新时间:9/29/2023 访问量:171

问:

我一直在研究使用最新标准对阵列进行切片的新方法,但这有点让人不知所措,我有一个问题。

有没有新的、简洁的方法,通过新的 C++23 添加到 、 、 甚至即将到来的 , ,使用带有要提取索引的向量将 an 的元素提取到另一个容器中?rangesviewsmdspansubmdspanmdarraymdspan

我必须事先知道它们的大小,但是,索引只有在运行时才能知道,因此我可以使用临时类型或其他容器。std::arraystd::vector

下面是一个 godbolt 示例,转载如下

#include <iostream>
#include <array>
#include <vector>
#include <https://raw.githubusercontent.com/kokkos/mdspan/single-header/mdspan.hpp>

int main()
{
    constexpr std::size_t pDeg = 16 ;
    std::array<std::size_t,pDeg*pDeg> arr;
    for (std::size_t i=0;i<arr.size();i++)
        arr[i] = i ;

    auto md = std::mdspan<std::size_t,std::extents<std::size_t,pDeg,pDeg>>(arr.data());

    std::vector<std::size_t> ind1 = {1,5,6,7,8,9,4,5};
    std::vector<std::size_t> ind2 = {14,11,12,13,11,1,5,6};

}

我实现了对矩阵进行操作的函数:、等multiply()add()

我想写矩阵代数表达式,比如

auto result = add(multiply(md[ind1,:],md[:,ind2]),md[ind1,ind2]);

其中 是包含第 1、5、6、7、8、9、4、5 行的子矩阵,包含第 14、11、12、13、11、1、5、6 列,并且是包含由 和 分别给出的行和列的所有组合的 8×8 子矩阵(请注意,索引可以重复)。md[ind1,:]mdmd[:,ind2]mdmd[ind1,ind2]mdind1ind2

或类似的东西

auto result = add(multiply(md.extract<0>(ind1),md.extract<1>(ind2)),md.extract<0,1>(ind1,ind2));

其中总是一个我知道编译时的大小。resultstd::array

这些方法不一定是我建议的方法,但它们需要采用一种简短的符号,因为会有许多矩阵代数运算。

C++ 数组矩阵 C++23 mdspan

评论

4赞 Barry 9/29/2023
你能在你的问题中解释一下你真正想做什么吗?我不知道这是什么意思。md[ind1, :]md.extract<0>(ind1)
0赞 Red.Wave 9/29/2023
mdarray必须等到 C++26,现在还远远不能使用。尝试避免它们,并且有范围适配器 + 算法。mdspanstd::viewstd::rangesranges::copy(ranges::fold_left_first(views::zip_transform(multiplies<size_t>{}, r1, r2), plus<size_t>{}), begin(arr));
0赞 Astor 9/29/2023
@Barry谢谢。md[ind1,:] 需要提取包含第 1、5、6、7、8、9、4、5 行的 md 子矩阵(请注意,行可以重复)。我需要一种简洁的方式来做到这一点,即使它与我建议的方法不同。
0赞 Ben Voigt 9/29/2023
:可能是“此维度上的所有元素”的 Matlab 表示法,但您将无法在 C++ 中以这种方式使用它。C++ 运算符重载不允许更改语法,只能更改行为。
0赞 Ben Voigt 9/29/2023
也只接受一个下标。您可以通过传递一个列表来解决这个问题: .operator[]md[{ind1, ind2}]

答: 暂无答案