2
\$\begingroup\$

This is a follow-up question for An element_wise_add Function For Boost.MultiArray in C++. Besides the basic add operation applying onto each element, I am trying to implement a sine template function which can apply std::sin() on each element. A new concept with_std_sin is created as below.

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

The main body of this sin template function is here. The similar recursive technique is also used in order to go through all elements.

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;
}

The test of this sin template function:

// 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;

All suggestions are welcome.

  • Which question it is a follow-up to?

    An element_wise_add Function For Boost.MultiArray in C++

  • What changes has been made in the code since last question?

    The previous question is the implementation of applying add operation onto each element in Boost.MultiArray. The main idea in this question is to implement a sin template function for calculating trigonometric sine value of each element.

  • Why a new review is being asked for?

    In my opinion, I am not sure is this a good idea about the implementation and the usage of the with_std_sin concept here. If there is any possible improvement, please let me know.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

It looks very simple and clean. I would change the name of with_std_sin though. There are some guidelines for naming concepts that suggest that it should be named sinable. That looks a bit weird, but everything I can think of to describe "something that std::sin supports" looks weird in some way, so it is as good as any name.

However, consider that you might want to apply many other functions to the contents of a boost::multi_array as well, not just std::sin. In that case, a recursive_transform() that handles multi_arrays is the way to go, so you could "just" write:

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

Or at least use that to define sin(), cos() and so on in therms of recursive_transform() without having to duplicate code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.