Skip to content

Fix cast of vector-valued function to array of scalar-valued functions #12

@akoshakji

Description

@akoshakji

In commit 92c9615, the factory for a field where the gradient is a vector and the cast of a vector-valued function to an array of scalar-valued functions were removed. This is because the test in tests/fields was producing undefined behavior when a scalar field was instantiated by passing the gradient as a vector:

auto Df = mito::math::function([](const vector_t<2> & x) -> vector_t<2> {
    return { -sin(x[0] * x[1]) * x[1], -sin(x[0] * x[1]) * x[0] };
});

auto f_cosine = mito::math::field(f, Df);  // this generates undefined behavior

as opposed to

auto Dfx = mito::math::function([](const vector_t<2> & x) -> real { return -sin(x[0] * x[1]) * x[1]; });
auto Dfy = mito::math::function([](const vector_t<2> & x) -> real { return -sin(x[0] * x[1]) * x[0]; });

auto f_cosine = mito::math::field(f, { Dfx, Dfy });

which works as expected.

Most probably the issue resides in the cast of Function<X, Y> with Y a vector of dimension N to an std::array<function_t<X, scalar_t>, N>. The problematic cast is here below:

template <size_t N>
constexpr operator std::array<function_t<X, scalar_t>, N>() const requires(Y::size == N)
{
    auto _components = [this]<size_t... I>(std::index_sequence<I...>)
    {
        return std::array<function_t<X, scalar_t>, N>({ operator[](I)... });
    };
    return _components(std::make_index_sequence<N> {});
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions