summaryrefslogtreecommitdiff
path: root/cesar/lib/fixed/eval.py
blob: 529dead834a07f6e58a423bfd0f320a88101814f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Evaluate precision or output C parameters."""
import fixed
import series
from sympy import sin, cos, pi

import matplotlib.pyplot as plt
import numpy

plot_error = 0

def prec (expr, order, poly, q, g, lo, hi):
    print expr
    n = 1000
    coeffs = series.series_coeffs (expr, order, poly.monoms (order))
    coeffs_fixed = series.poly_fixed (q, coeffs)
    if g:
        coeffs_fixed_guard = series.poly_fixed (fixed.guard (q, g), coeffs)
        def my_poly_eval_fixed_guard (q, coeffs, v):
            return poly.eval_fixed_guard (q, g, coeffs, v)
    print "precision (float):", series.precision (expr, coeffs,
            poly.eval, lo, hi)
    print "precision (fixed):", series.precision_fixed (q, expr, coeffs_fixed,
            poly.eval_fixed, lo, hi)
    if g:
        print "precision (fixed, guard):", series.precision_fixed (q, expr,
                coeffs_fixed_guard, my_poly_eval_fixed_guard, lo, hi)
    print "coeffs (float):", coeffs
    print "coeffs (fixed):", [ hex (i) for i in coeffs_fixed ]
    if g:
        print "coeffs (fixed, guard):", \
                [ hex (i) for i in coeffs_fixed_guard ]
    if plot_error:
        p = series.refine_precision (expr, coeffs, poly.eval, lo, hi, n)
        x = numpy.linspace (lo, hi, n)
        plt.plot (x, p)
    p = series.refine_precision_fixed (q, expr, coeffs_fixed,
            poly.eval_fixed, lo, hi, n)
    print "precision refined (fixed):", sum (p), "/", n, "max:", max (p)
    if g:
        p = series.refine_precision_fixed (q, expr, coeffs_fixed_guard,
                my_poly_eval_fixed_guard, lo, hi, n)
        print "precision refined (fixed, guard):", sum (p), "/", n, \
                "max:", max (p)
    print

def param (expr, order, poly, q, g, lo, hi):
    print "/*", expr, "approximation parameters."
    print " * format: q%d.%d, guard: %d. */" % (q[0], q[1], g)
    coeffs = series.series_coeffs (expr, order, poly.monoms (order))
    if not g:
        coeffs_fixed = series.poly_fixed (q, coeffs)
    if g:
        coeffs_fixed = series.poly_fixed (fixed.guard (q, g), coeffs)
    for c, p in zip (coeffs_fixed, poly.monoms (order)):
        print "    %+#011x,  /* x^%d */" % (c, p)

q = (7, 24)
# Would be better with g = 6, but registers are 32 bit wide.
g = 4

what = prec

what (sin (series.x * pi), 10, series.poly_odd, q, g, -1.0/4, 1.0/4)
what (cos (series.x * pi), 10, series.poly_even, q, g, -1.0/4, 1.0/4)

if plot_error:
    plt.show ()