mockingbirdnest/Principia

Add functions for argument reduction

eggrobin opened this issue · 1 comments

Currently we have

  • A reduction to ]-π/2, π/2[,

// Argument reduction: angle = fractional_part + integer_part * π where
// fractional_part is in [-π/2, π/2].
void Reduce(Angle const& angle,
Angle& fractional_part,
std::int64_t& integer_part);

  • Many reductions to [0, 2π[,

? Mod(ω, 2 * π * Radian)

: Mod(offset_longitude, 2 * π * Radian);

some of them with preconditions,

// Maps [-π, π] to [0, 2π].
auto const positive_angle = [](Angle const& α) -> Angle {
return α > 0 * Radian ? α : α + 2 * π * Radian;
};

one slightly better one seemingly used only in tests,
inline DoublePrecision<Angle> Mod2π(DoublePrecision<Angle> const& θ) {
static DoublePrecision<Angle> const two_π = []() {
return QuickTwoSum(0x1.921FB54442D18p2 * Radian,
0x1.1A62633145C07p-52 * Radian);
}();
auto const θ_over_2π = θ / two_π;
return θ - two_π * DoublePrecision<double>(static_cast<int>(θ_over_2π.value));
}

None of those are correctly rounded, and we keep writing more of that kind of thing (most recently in #3761 (comment)), there reducing to ]-π, π[.

We should centralize the angle reduction functions somewhere in numerics (and make them correctly rounded someday, see #1760).

pleroy commented

A better implementation would be part of #1760.