sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.42k stars 477 forks source link

_evalf_ handling of backends #15200

Open eviatarbach opened 11 years ago

eviatarbach commented 11 years ago

As per Burcin, with the option of the algorithm keyword for _evalf_ in #12289,

ATM, if you implement different backends, you need to write a lot of
boilerplate code in _evalf_() to parse the algorithm argument, do the
right thing if it is not given etc. Can we have a default _evalf_
method, which dispatches to _evalf_<system>_ methods if they exist and
raise error if not? Perhaps we can also figure out how to annotate
these methods to indicate if they support arbitrary precision
evaluation or not.

CC: @burcin @kcrisman

Component: symbolics

Issue created by migration from https://trac.sagemath.org/ticket/15200

eviatarbach commented 11 years ago

Dependencies: #12289

eviatarbach commented 11 years ago
comment:2

I think "the right thing if it is not given" is resort to a method _evalf_default_. In cases where _evalf_ has already been defined, overwriting the _evalf_ which this patch would define, this will not change anything. The only problem is that for most functions the algorithm keyword won't do anything. I can't think of any good solution to this (such as raising a warning or error) that wouldn't involve modifying all the existing symbolic functions.

eviatarbach commented 11 years ago
comment:3

Attachment: trac15200.patch.gz

This patch works for BuiltinFunction. Unfortunately it breaks GinacFunction (since they often don't define an _evalf_ method, they don't overwrite the _evalf_ in the base class) and gives an error as in #14743 on startup:

Exception AttributeError: "'builtin_function_or_method' object has no attribute 'func_code'" in 'sage.symbolic.function.SymbolicFunction._hash_' ignored
jdemeyer commented 10 years ago
comment:7

I think the best solution would be to hardcode a set of common algorithm/parent choices like:

def _evalf_(self, *args, parent=None, algorithm=None):
    if hasattr(self, '_evalf_scipy_') and (some_condition_on_parent_and_algorithm):
        return parent(self._evalf_scipy_(*args))
    if hasattr(self, '_evalf_mpmath_') and (some_condition_on_parent_and_algorithm):
        return parent(self._evalf_mpmath_(*args))
    [...]
    return self._evalf_default_(*args, parent=parent, algorithm=algorithm)
jdemeyer commented 10 years ago

Changed dependencies from #12289 to #17130

rwst commented 9 years ago
comment:10

I had a look at Eviatar's patch and got some ideas. First,

Replying to @jdemeyer:

I think the best solution would be to hardcode a set of common algorithm/parent choices like:

@jdemeyer:

  1. Does this mean you would find any mechanism doing recognition of implemented algorithms or call dispatch that exists apart from your hardcoded solution dangerous/superfluous/..?
  2. What is your opinion regarding such a mechanism dealing with eval (i.e., non-fp) algorithms? This concerns #17489, with possible implementation in #17531. (This may be fast in __call__, with only a dictionary lookup.)
jdemeyer commented 9 years ago
comment:11

Replying to @rwst:

  1. Does this mean you would find any mechanism doing recognition of implemented algorithms or call dispatch that exists apart from your hardcoded solution dangerous/superfluous/..?

No, but I think the generic solution should work for most functions.

  1. What is your opinion regarding such a mechanism dealing with eval (i.e., non-fp) algorithms?

I would propose to use this only for _evalf_ but possibly extend _evalf_ to non-fp arguments. See also the discussion about NumberTheoreticFunction (whatever the name) in #17489.

jdemeyer commented 9 years ago

Changed dependencies from #17130 to none