Name:
annotatefunction
Annotates a Sollya function object with an approximation that is faster to evaluate
Library names:
sollya_obj_t sollya_lib_annotatefunction(sollya_obj_t, sollya_obj_t,
sollya_obj_t, sollya_obj_t, ...);
sollya_obj_t sollya_lib_v_annotatefunction(sollya_obj_t, sollya_obj_t,
sollya_obj_t, sollya_obj_t,
va_list);
Usage:
annotatefunction(f, g, I, d) : (function, function, range, range) -> function
annotatefunction(f, g, I, d, x0) : (function, function, range, range, constant) -> function
Parameters:
- f is a function.
- g is a function, in most cases a polynomial.
- I is an interval.
- d is an interval.
- x0 is a constant (default value is 0 when not provided).
Description:
- When a given function f is to be evaluated at several points of a given
interval I to a given precision, it might be useful to precompute a good
approximant g of f and further evaluate it instead of f when the
approximation is good enough to provide the desire precision. If f is a
complicated expression, whereas g is, e.g., a polynomial of low degree,
the cost of precomputing g can be well compensated by the gain of time in
each subsequent evaluation. The purpose of annotatefunction is to provide
such a mechanism to the user.
- When using annotatefunction(f, g, I, d, x0),
resp. annotatefunction(f, g, I, d) (where x0 is assumed to be
zero), it is assumed that
forall x in I, f(x) - g(x - x0) in d.
It is the user responsibility to ensure this property. Otherwise, any
subsequent use of f on points of I might lead to incorrect values.
- A call to annotatefunction(f, g, I, d, x0) annotates the given
Sollya function object f with the approximation g. In further use, when
asked to evaluate f on a point x of I, Sollya will first evaluate g
on x-x0 and check if the result is accurate enough in the given context
(accounting for the fact that the error of approximation between the true
value and g(x-x0) belongs to d). If not (and only in this case), an
evaluation of the expression of f on x is performed.
- The approximation g can be any Sollya function but particular
performance is expected when g is a polynomial. Upon annotation with a
polynomial, precomputations are performed to analyze certain properties of
the given approximation polynomial.
- annotatefunction updates the internal representation of f so as to
persistently keep this information attached with the Sollya object
representing f. In particular, the annotation is persistent through copy
or use of f as a subexpression to build up bigger expressions. Notice
however, that there is no way of deducing an annotation for the derivative
of f from an annotation of f. So, in general, it should not be expected
that diff(f) will be automatically annotated (notice, however that f
might be a subexpression of its derivative, e.g., for f=exp or f=tan, in
which case the corresponding subexpressions of the derivative could inherit
the annotations from f. It is currently not specified whether Sollya does
this automatically or not).
- annotatefunction really is an imperative statement that modifies the
internal representation of f. However, for convenience annotatefunction
returns f itself.
- Sollya function objects can be annotated more than once with different
approximations on different domains, that do not need to be disjoint. Upon
evaluation of the annotated function object, Sollya chooses an
approximation annotation (if any) that provides for sufficient accuracy at
the evaluation point. It is not specified in which order Sollya tries
different possible annotations when several are available for a given
point x.
Example 1:
> verbosity=1!;
> procedure EXP(X,n,p) {
var res, oldPrec;
oldPrec = prec;
prec = p!;
"Using procedure function exponential with X=" @ X @ ", n=" @ n @ ", and p=" @ p;
res = exp(X);
prec = oldPrec!;
return res;
};
> g = function(EXP);
> p = 46768052394588893382516870161332864698044514954899b-165 + x * (23384026197294446691258465802074096632225783601255b-164 + x * (5846006549323611672948426613035653821819225877423b-163 + x * (3897337699549074448627696490806815137319821946501b-164 + x * (7794675399098148717422744621371434831048848817417b-167 + x * (24942961277114075921122941174178849425809856036737b-171 + x * (8314320425704876115613838900105097456456371179471b-172 + x * (19004160973039701371579356991645932289422670402995b-176 + x * (19004160972669324148912122254449912156003926801563b-179 + x * (33785175062542597526738679493857229456702396042255b-183 + x * (6757035113643674378393625988264926886191860669891b-184 + x * (9828414707511252769908089206114262766633532289937b-188 + x * (26208861108003813314724515233584738706961162212965b-193 + x * (32257064253325954315953742396999456577223350602741b-197 + x * (578429089657689569703509185903214676926704485495b-195 + x * 2467888542176675658523627105540996778984959471957b-201))))))))))))));
> h = annotatefunction(g, p, [-1/2;1/2], [-475294848522543b-124;475294848522543b-124]);
> h == g;
true
> prec = 24;
The precision has been set to 24 bits.
> h(0.25);
Warning: rounding has happened. The value displayed is a faithful rounding to 24 bits of the true result.
Warning: For at least 1 of the constants displayed in decimal, rounding has happened.
1.2840254
> prec = 165;
The precision has been set to 165 bits.
> h(0.25);
Using procedure function exponential with X=[0.25;0.25], n=0, and p=185
Warning: rounding has happened. The value displayed is a faithful rounding to 165 bits of the true result.
Warning: For at least 1 of the constants displayed in decimal, rounding has happened.
1.28402541668774148407342056806243645833628086528147
Go back to the list of commands