diff options
Diffstat (limited to 'pl/math/tools/exp10.sollya')
-rw-r--r-- | pl/math/tools/exp10.sollya | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/pl/math/tools/exp10.sollya b/pl/math/tools/exp10.sollya new file mode 100644 index 000000000000..9f30b4018209 --- /dev/null +++ b/pl/math/tools/exp10.sollya @@ -0,0 +1,55 @@ +// polynomial for approximating 10^x +// +// Copyright (c) 2023, Arm Limited. +// SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + +// exp10f parameters +deg = 5; // poly degree +N = 1; // Neon 1, SVE 64 +b = log(2)/(2 * N * log(10)); // interval +a = -b; +wp = single; + +// exp10 parameters +//deg = 4; // poly degree - bump to 5 for ~1 ULP +//N = 128; // table size +//b = log(2)/(2 * N * log(10)); // interval +//a = -b; +//wp = D; + + +// find polynomial with minimal relative error + +f = 10^x; + +// return p that minimizes |f(x) - poly(x) - x^d*p(x)|/|f(x)| +approx = proc(poly,d) { + return remez(1 - poly(x)/f(x), deg-d, [a;b], x^d/f(x), 1e-10); +}; +// return p that minimizes |f(x) - poly(x) - x^d*p(x)| +approx_abs = proc(poly,d) { + return remez(f(x) - poly(x), deg-d, [a;b], x^d, 1e-10); +}; + +// first coeff is fixed, iteratively find optimal double prec coeffs +poly = 1; +for i from 1 to deg do { + p = roundcoefficients(approx(poly,i), [|wp ...|]); +// p = roundcoefficients(approx_abs(poly,i), [|wp ...|]); + poly = poly + x^i*coeff(p,0); +}; + +display = hexadecimal; +print("rel error:", accurateinfnorm(1-poly(x)/10^x, [a;b], 30)); +print("abs error:", accurateinfnorm(10^x-poly(x), [a;b], 30)); +print("in [",a,b,"]"); +print("coeffs:"); +for i from 0 to deg do coeff(poly,i); + +log10_2 = round(N * log(10) / log(2), wp, RN); +log2_10 = log(2) / (N * log(10)); +log2_10_hi = round(log2_10, wp, RN); +log2_10_lo = round(log2_10 - log2_10_hi, wp, RN); +print(log10_2); +print(log2_10_hi); +print(log2_10_lo); |