## 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.
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.
1.28402541668774148407342056806243645833628086528147