Uma função de modelo seno para Boost.MultiArray em C ++

Nov 02 2020

Esta é uma pergunta de acompanhamento para Uma função element_wise_add para Boost.MultiArray em C ++ . Além da operação de adição básica aplicada a cada elemento, estou tentando implementar uma função de modelo de seno que pode ser aplicada std::sin()a cada elemento. Um novo conceito with_std_siné criado a seguir.

template<typename T>
concept with_std_sin = requires(T x)
{
    std::sin(x);
};

O corpo principal desta sinfunção de modelo está aqui. A técnica recursiva semelhante também é usada para percorrer todos os elementos.

template<class T> requires (with_std_sin<T>)
auto sin(const T& input)
{
    return std::sin(input);
}

template<class T> requires (is_multi_array<T>)
auto sin(const T& input)
{
    boost::multi_array output(input);
    for (decltype(+input.shape()[0]) i = 0; i < input.shape()[0]; i++)
    {
        output[i] = sin(input[i]);
    }
    return output;
}

O teste desta sinfunção de modelo:

// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);

// Assign values to the elements
int values = 1;
for (index i = 0; i != 3; ++i)
    for (index j = 0; j != 4; ++j)
        for (index k = 0; k != 2; ++k)
            A[i][j][k] = values++;

for (index i = 0; i != 3; ++i)
    for (index j = 0; j != 4; ++j)
        for (index k = 0; k != 2; ++k)
            std::cout << A[i][j][k] << std::endl;

auto test_result = sin(A);

for (index i = 0; i != 3; ++i)
    for (index j = 0; j != 4; ++j)
        for (index k = 0; k != 2; ++k)
            std::cout << test_result[i][j][k] << std::endl;

Todas as sugestões são bem-vindas.

  • Para qual pergunta é um seguimento?

    Uma função element_wise_add para Boost.MultiArray em C ++

  • Que mudanças foram feitas no código desde a última pergunta?

    A questão anterior é a implementação da aplicação da operação de adição em cada elemento em Boost.MultiArray. A ideia principal nesta questão é implementar uma sinfunção de modelo para calcular o valor do seno trigonométrico de cada elemento.

  • Por que uma nova revisão está sendo solicitada?

    Na minha opinião, não tenho certeza se essa é uma boa ideia sobre a implementação e o uso do with_std_sinconceito aqui. Se houver alguma melhoria possível, por favor me avise.

Respostas

1 G.Sliepen Nov 02 2020 at 21:01

Parece muito simples e limpo. Eu mudaria o nome de with_std_sinembora. Existem algumas diretrizes para conceitos de nomenclatura que sugerem que ele deve ser nomeado sinable. Isso parece um pouco estranho, mas tudo o que consigo pensar para descrever "algo que std :: sin suporta" parece estranho de alguma forma, então é tão bom quanto qualquer nome.

No entanto, considere que você pode querer aplicar muitas outras funções ao conteúdo de a boost::multi_arraytambém, não apenas std::sin. Nesse caso, um recursive_transform()que lida com multi_arrays é o caminho a seguir, então você pode "apenas" escrever:

auto test_result = recursive_transform(A, [](auto &x){return std::sin(x);});

Ou pelo menos use isso para definir sin(), cos()e assim por diante em termos de recursive_transform()sem ter que duplicar o código.