#1173: implement numerical evaluation of erf at complex arguments
----------------------------------------------------------------------+-----
Reporter: was |
Owner: was
Type: enhancement |
Status: needs_work
Priority: major |
Milestone: sage-4.7.2
Component: calculus |
Keywords:
Work_issues: add erf(sqrt(2)) and erf(45000).n(), formatting, speed |
Upstream: N/A
Reviewer: Burcin Erocal |
Author: D. S. McNeil
Merged: |
Dependencies: #11513
----------------------------------------------------------------------+-----
Comment(by burcin):
Replying to [comment:26 dsm]:
<snip>
> To wrap up:
>
> (1) Both this patch and #11143 suffer a significant slowdown relative to
PARI, and have major overheads relative to calling mpmath. Some of that's
unavoidable given the symbolic path, but ISTM we should be able to do
better. Ideally there would be a reasonably efficient general special
function implementation pattern, along the lines of what Benjamin used,
that intermittent developers like me could be pointed to as a reference.
I agree that we should do better. Note that the pattern you request is
being developed in #11143 and here. Even though pynac based symbolics was
merged in Sage quite a while ago, it hasn't been used properly yet.
The code path to call symbolic functions is rather convoluted. This is
inevitable since symbolic functions have to play well with many different
subsystems, such as fast float, numpy, etc. But it should still be
possible to reduce the overhead.
For `BuiltinFunction`s the code path for evaluation goes through
`Function.__call__()` in `sage/symbolic/function.pyx`, then into pynac,
then to the python method you define for `_eval_()`, if numeric evaluation
is needed to `_evalf_()` later. Here, between the python and C++ code,
conversion functions are called to wrap pynac objects in Expression
instances or to remove these wrappers.
I believe most of the overhead comes from the `__call__()` method, then
having to decide if the arguments are numeric in `_eval_()`, and checking
if an argument is zero (#11513).
> (2) In the case of erf and erfc, mpfr offers a very fast evaluation for
real numbers, fast enough that it might be worth using as the default in
those cases (although Python-level branching is slow in my experience,
maybe slow enough to wash away the benefits). Once we settle on an
approach for erf I'll do the same for erfc.
MPFR should be the default numeric evaluation method if it is available.
In general, it's better to let the types choose the numeric evaluation
method. Most special functions in Sage first see if an object implements a
method with the same name first and calls that. For instance `erf()`
should call `.erf()` for element of `RR`.
I see that for subclasses of `GinacFunction` the `__call__()` method does
this automatically. This is not used for other `BuiltinFunction`s though.
It might make sense to move this method to `BuiltinFunction`. This would
speed up most of the timings for real numbers above.
Unfortunately, floats would still go through the long path. Since these
are used quite often in plotting, perhaps we should add a special case in
`__call__()` to go directly to `_evalf_()` as well.
I made this change in attachment:trac_1173-move_call.patch. Now I get:
{{{
sage: t = RR(2.0)
sage: %timeit z = t.erf()
625 loops, best of 3: 16.9 µs per loop
sage: %timeit z = erf(t)
625 loops, best of 3: 18.2 µs per loop
}}}
Performance for `float` is still pretty bad.
{{{
sage: u = 2.0r
sage: %timeit z = erf(u)
625 loops, best of 3: 156 µs per loop
}}}
I didn't check if this patch breaks anything.
> (3) Should I move this out of other.py to special.py, where the
complementary error_fcn function lives now? It would seem a more natural
location for it. We also have some unfortunate naming (erf and error_fcn)
it might be worth addressing.
I don't think there is a need to move this to `special.py`. That file is
also overcrowded and needs serious cleanup. You could create a new file
names `error_fn.py` if you think that's necessary.
What names do other systems use for these functions? AFAIK, `erf()` and
`erfc()` are pretty much standard. I wonder where `error_fcn()` came from.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/1173#comment:27>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.