Opened 7 years ago

Last modified 4 weeks ago

#12577 new enhancement

Make Expression._convert a visible method

Reported by: mjo Owned by: burcin
Priority: minor Milestone: sage-wishlist
Component: symbolics Keywords: beginner
Cc: Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description

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:

Change History (11)

comment:1 Changed 6 years ago by jdemeyer

  • Milestone changed from sage-5.11 to sage-5.12

comment:2 Changed 5 years ago by vbraun_spam

  • Milestone changed from sage-6.1 to sage-6.2

comment:3 Changed 5 years ago by vbraun_spam

  • Milestone changed from sage-6.2 to sage-6.3

comment:4 Changed 5 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4

comment:5 Changed 3 years ago by mjo

  • Keywords beginner added

comment:6 Changed 4 weeks ago by embray

  • Milestone changed from sage-6.4 to sage-wishlist

comment:7 Changed 4 weeks ago by embray

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.

comment:8 Changed 4 weeks ago by mjo

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.

comment:9 Changed 4 weeks ago by embray

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.

comment:10 Changed 4 weeks ago by embray

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)?

comment:11 Changed 4 weeks ago by mjo

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.

Note: See TracTickets for help on using tickets.