xref: /freebsd-src/contrib/arm-optimized-routines/math/tools/atan.sollya (revision f3087bef11543b42e0d69b708f367097a4118d24)
1*f3087befSAndrew Turner// polynomial for approximating atan(x) and atan2(y, x)
2*f3087befSAndrew Turner//
3*f3087befSAndrew Turner// Copyright (c) 2022-2024, Arm Limited.
4*f3087befSAndrew Turner// SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
5*f3087befSAndrew Turner
6*f3087befSAndrew Turner// atan is odd, so approximate with an odd polynomial:
7*f3087befSAndrew Turner// x + ax^3 + bx^5 + cx^7 + ...
8*f3087befSAndrew Turner// We generate a, b, c, ... such that we can approximate atan(x) by:
9*f3087befSAndrew Turner// x + x^3 * (a + bx^2 + cx^4 + ...)
10*f3087befSAndrew Turner
11*f3087befSAndrew Turner// Assemble monomials
12*f3087befSAndrew Turnerdeg = 20;
13*f3087befSAndrew Turnermons = [|1,...,deg|];
14*f3087befSAndrew Turnerfor i from 0 to deg-1 do mons[i] = mons[i] * 2 + 1;
15*f3087befSAndrew Turner
16*f3087befSAndrew Turnera = 0x1.0p-1022;
17*f3087befSAndrew Turnerb = 1;
18*f3087befSAndrew Turner
19*f3087befSAndrew Turnerpoly = fpminimax(atan(x)-x, mons, [|double ...|], [a;b]);
20*f3087befSAndrew Turner
21*f3087befSAndrew Turnerdisplay = hexadecimal;
22*f3087befSAndrew Turnerprint("coeffs:");
23*f3087befSAndrew Turnerfor i from 0 to deg-1 do coeff(poly,mons[i]);
24