Skip to content

Improve numerical accuracy of circular axis #380

Description

@HDembinski

The if (options_type::test(option::circular)) inside index_type index(value_type x) and value_type value(real_index_type i) reminds me of when I was dealing with periodic argument reduction in a simulator+monitor program (every ms PC sends sin(A*t+B) and receives actual value to&from a chip through UDP, t can be as large as several days). There should be some high precision functions in boost.core/utility/utilities/tool/tools/toolbox/... and we just need to find them.
https://en.cppreference.com/w/cpp/numeric/lerp
https://stackoverflow.com/questions/64058564/single-precision-argument-reduction-for-trigonometric-functions-in-c

{
    // using A = axis::variable<double, axis::null_type, op::circular_t>; // using double solves the errors
    using A = axis::variable<float, axis::null_type, op::circular_t>;
    auto a = A({
      1.,
      1e+8,
      2e+8,
    });
    BOOST_TEST_EQ(a.index(1e8), 1);
    BOOST_TEST_EQ(a.index(2e8), 0); // test 'a.index(2e8) == 0' ('-1' == '0') failed
    BOOST_TEST_EQ(a.index(4e8), 0); // test 'a.index(4e8) == 0' ('-1' == '0') failed
}
{
    // using A = axis::variable<double, axis::null_type, op::circular_t>; // using double solves the errors
    using A = axis::variable<float, axis::null_type, op::circular_t>;
    auto a = A({
      -2e+8,
      -1e+8,
      -1.,
    });
    BOOST_TEST_EQ(a.index(-1e8), 1);
    BOOST_TEST_EQ(a.index(-2e8), 0);
    BOOST_TEST_EQ(a.index(-4e8), 1); // test 'a.index(-4e8) == 1' ('0' == '1') failed
}
return boost::report_errors();

Originally posted by @jhcarl0814 in #372 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions