sagemath / sage

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

Make Expression._convert a visible method #12577

Open orlitzky opened 12 years ago

orlitzky commented 12 years ago

It would be nice if the _convert() method of symbolic expressions were made visible (and possibly renamed, if "convert" is too general). This has come up in two or three times before, and I needed it long before I bothered to ask for help:

Component: symbolics

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

embray commented 5 years ago
comment:7

I wonder if, rather than just directly expose _convert, there could either be a flag for numerical_approx, or some sister-method to numerical_approx which is similar but only converts already numerical terms in the expression (as _convert itself does). But the API should be more user-friendly, more along the lines of numerical_approx.

The problem with numerical_approx is it ends with some checks like:

        # we have to consider constants as well, since infinity is a constant
        # in pynac
        if is_a_numeric(x._gobj):
            res = py_object_from_numeric(x._gobj)
        elif  is_a_constant(x._gobj):
            res = x.pyobject()
        else:
            raise TypeError("cannot evaluate symbolic expression numerically")

where the last case is what you get if you tried to convert some arbitrary expression (like a polynomial, or solution to a DE) to "numerical".

So yes, what we probably want here is something more like _convert, but still a wrapper around it that specifies the allowed keyword arguments, and is maybe specifically geared toward arbitrary-precision numerical results.

orlitzky commented 5 years ago
comment:8

I think it's useful in general to be able to change "back" from an approximate ring to an exact one. A trivial example:

sage: f = RR(1)*x
sage: f
1.00000000000000*x
sage: f._convert(QQ)
x

But I agree that the user interface is key. The name "convert" is no good -- it's too general anyway but doesn't tell you what's being converted. Partially as a result of those two things, it's also not discoverable via tab-completion.

The best altername name that I've been able to come up with so far is change_ring_of_constants. It mirrors the change_ring method for e.g. vectors and matrices, and will be obviously what you want if you see it in the tab-completion list.

embray commented 5 years ago
comment:9

change_ring_of_constants is not a terrible name--it's pretty accurate. Maybe we could do a bit better but I think long an clear is better than short and vague.

embray commented 5 years ago
comment:10

The problem with "change" also kind of problematic since it implies (to me anyways) an in-place modification, when really you're returning a new expression. Maybe convert_constants_to_ring(RR)?

orlitzky commented 5 years ago
comment:11

The benefit of change_ring... is that it's name is "obvious" if you're familiar with the same functionality for lattices, matrices, vectors, modules, etc. It's been years, but I'd like to think that when I was looking for this method, I tried expr.change<tab> first. And for better or worse, the ring-changing methods already return a copy rather than switching the ring in-place:

sage: A = identity_matrix(QQ,3)
sage: A.change_ring(ZZ)
[1 0 0]
[0 1 0]
[0 0 1]
sage: A.base_ring()
Rational Field

So, returning a copy is at least consistent. But aside from the nominal similarity to change_ring, I don't have a strong preference for the name. Something like expr.with_constants_in_ring(R) could also work.

DaveWitteMorris commented 4 years ago
comment:12

Removing the "beginner" tag from old tickets. Some could be returned to beginner-friendly status by adding a comment about what needs to be done. Some others might be easy for an experienced developer to finish.

Related ticket: #24850.