From da82ac511f3671401108b2fc7ea7ac3ed6564664 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Oct 2021 09:40:37 -0700 Subject: [PATCH 01/10] src/sage/rings/polynomial/polynomial_element.pyx: Use isinstance(..., sage.rings.abc.SymbolicRing) instead of ... is SR --- src/sage/rings/polynomial/polynomial_element.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 26fdab5cbca..05401515069 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -7630,9 +7630,9 @@ cdef class Polynomial(CommutativeAlgebraElement): back to pari (numpy will fail if some coefficient is infinite, for instance). - If L is SR, then the roots will be radical expressions, - computed as the solutions of a symbolic polynomial expression. - At the moment this delegates to + If L is SR (or one of its subrings), then the roots will be radical + expressions, computed as the solutions of a symbolic polynomial + expression. At the moment this delegates to :meth:`sage.symbolic.expression.Expression.solve` which in turn uses Maxima to find radical solutions. Some solutions may be lost in this approach. @@ -7904,8 +7904,7 @@ cdef class Polynomial(CommutativeAlgebraElement): else: return [rt for (rt, mult) in rts_mult] - from sage.symbolic.ring import SR - if L is SR: + if isinstance(L, sage.rings.abc.SymbolicRing): if self.degree() == 2: from sage.misc.functional import sqrt from sage.symbolic.expression import I @@ -7925,6 +7924,7 @@ cdef class Polynomial(CommutativeAlgebraElement): return l else: return [val for val,m in l] + from sage.symbolic.ring import SR vname = 'do_not_use_this_name_in_a_polynomial_coefficient' var = SR(vname) expr = self(var) From 3c821bdc9ef306f59bd5809b93935b03eb9e8781 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:09:51 -0700 Subject: [PATCH 02/10] sage.functions.other._eval_floor_ceil: Handle elements of symbolic subrings like elements of SR --- src/sage/functions/other.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index cd2adbb1bfb..3fd9048ea87 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -20,7 +20,7 @@ from sage.symbolic.function import GinacFunction, BuiltinFunction from sage.symbolic.expression import Expression, register_symbol, symbol_table -from sage.symbolic.ring import SR +from sage.symbolic.ring import SR, SymbolicRing from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.rational import Rational @@ -179,6 +179,15 @@ def _eval_floor_ceil(self, x, method, bits=0, **kwds): Traceback (most recent call last): ... ValueError: Calling ceil() on infinity or NaN + + Test that elements of symbolic subrings work in the same way as + elements of ``SR``, :trac:`32724`:: + + sage: SCR = SR.subring(no_variables=True) + sage: floor(log(2^(3/2)) / log(2) + 1/2) + 2 + sage: floor(SCR(log(2^(-3/2)) / log(2) + 1/2)) + -1 """ # First, some obvious things... try: @@ -215,8 +224,8 @@ def _eval_floor_ceil(self, x, method, bits=0, **kwds): from sage.rings.all import RealIntervalField # Might it be needed to simplify x? This only applies for - # elements of SR. - need_to_simplify = (s_parent(x) is SR) + # elements of SR (or its subrings) + need_to_simplify = isinstance(s_parent(x), SymbolicRing) # An integer which is close to x. We use this to increase precision # by subtracting this guess before converting to an interval field. From f1c9258889ae9e45b6d82c1ae9421890e2de569c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:18:48 -0700 Subject: [PATCH 03/10] src/sage/combinat/q_analogues.py: Handle symbolic subrings like SR --- src/sage/combinat/q_analogues.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 10333aaa455..bf5f5c985bc 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -172,7 +172,8 @@ def q_binomial(n, k, q=None, algorithm='auto'): uses the naive algorithm. When both ``n`` and ``k`` are big, one uses the cyclotomic algorithm. - - If ``q`` is in the symbolic ring, one uses the cyclotomic algorithm. + - If ``q`` is in the symbolic ring (or a symbolic subring), one uses + the cyclotomic algorithm. - Otherwise one uses the naive algorithm, unless ``q`` is a root of unity, then one uses the cyclotomic algorithm. @@ -248,7 +249,7 @@ def q_binomial(n, k, q=None, algorithm='auto'): This also works for variables in the symbolic ring:: sage: z = var('z') - sage: factor(q_binomial(4,2,z)) + sage: factor(q_binomial(4, 2, z)) (z^2 + z + 1)*(z^2 + 1) This also works for complex roots of unity:: @@ -346,8 +347,8 @@ def q_binomial(n, k, q=None, algorithm='auto'): elif is_polynomial: algorithm = 'cyclotomic' else: - from sage.symbolic.ring import SR - if R is SR: + import sage.rings.abc + if isinstance(R, sage.rings.abc.SymbolicRing): algorithm = 'cyclotomic' else: algorithm = 'naive' From f98855b9633090e728d197202a9a9fc4dfcfd446 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:44:33 -0700 Subject: [PATCH 04/10] src/sage/dynamics/arithmetic_dynamics/projective_ds.py: Use sage.rings.abc.SymbolicRing instead of 'is SR' --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index d4cb66af782..7033a64bbef 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -105,7 +105,6 @@ class initialization directly. from sage.parallel.ncpus import ncpus from sage.parallel.use_fork import p_iter_fork from sage.dynamics.arithmetic_dynamics.projective_ds_helper import (_fast_possible_periods,_all_periodic_points) -from sage.symbolic.ring import SR from itertools import count, product from .endPN_automorphism_group import ( automorphism_group_QQ_CRT, @@ -422,8 +421,8 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): if len(polys) != domain.ambient_space().coordinate_ring().ngens(): raise ValueError('Number of polys does not match dimension of {}'.format(domain)) R = domain.base_ring() - if R is SR: - raise TypeError("Symbolic Ring cannot be the base ring") + if isinstance(R, sage.rings.abc.SymbolicRing): + raise TypeError("the base ring cannot be the Symbolic Ring or a symbolic subring") if is_ProductProjectiveSpaces(domain): splitpolys = domain._factors(polys) From 7f1500e4cdebfd8ee87f61749a11e0e23e4c65b9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:59:17 -0700 Subject: [PATCH 05/10] src/sage/geometry/polyhedron/parent.py: For backend='normaliz', accept subrings of SR --- src/sage/geometry/polyhedron/parent.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/parent.py b/src/sage/geometry/polyhedron/parent.py index 48bed4a9553..8ac51827d61 100644 --- a/src/sage/geometry/polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/parent.py @@ -15,6 +15,7 @@ from sage.modules.free_module import FreeModule, is_FreeModule from sage.misc.cachefunc import cached_method, cached_function from sage.misc.lazy_import import lazy_import +import sage.rings.abc from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF @@ -113,6 +114,13 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * ... ValueError: the 'polymake' backend for polyhedron cannot be used with Algebraic Real Field + sage: Polyhedra(QQ, 2, backend='normaliz') # optional - pynormaliz + Polyhedra in QQ^2 + sage: Polyhedra(SR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + Polyhedra in (Symbolic Ring)^2 + sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic + sage: Polyhedra(SCR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + Polyhedra in (Symbolic Constants Subring)^2 """ if ambient_space_or_base_ring is not None: if ambient_space_or_base_ring in Rings(): @@ -161,7 +169,7 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * return Polyhedra_QQ_normaliz(base_ring, ambient_dim, backend) elif backend == 'normaliz' and base_ring is ZZ: return Polyhedra_ZZ_normaliz(base_ring, ambient_dim, backend) - elif backend == 'normaliz' and (base_ring is SR or base_ring.is_exact()): + elif backend == 'normaliz' and (isinstance(base_ring, sage.rings.abc.SymbolicRing) or base_ring.is_exact()): return Polyhedra_normaliz(base_ring, ambient_dim, backend) elif backend == 'cdd' and base_ring in (ZZ, QQ): return Polyhedra_QQ_cdd(QQ, ambient_dim, backend) From 76e09622cf24f5137eb8b611e349e3bb4988d61b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 21:06:13 -0700 Subject: [PATCH 06/10] [Diff]ScalarFieldAlgebra._coerce_map_from_: Also coerce from subrings of SR --- src/sage/manifolds/differentiable/scalarfield_algebra.py | 8 ++++++-- src/sage/manifolds/scalarfield_algebra.py | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/manifolds/differentiable/scalarfield_algebra.py b/src/sage/manifolds/differentiable/scalarfield_algebra.py index be5d9176cd3..7bbf5a39146 100644 --- a/src/sage/manifolds/differentiable/scalarfield_algebra.py +++ b/src/sage/manifolds/differentiable/scalarfield_algebra.py @@ -32,7 +32,7 @@ class `C^k` over a topological field `K` (in #****************************************************************************** from sage.rings.infinity import infinity -from sage.symbolic.ring import SR +from sage.symbolic.ring import SymbolicRing from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra from sage.manifolds.differentiable.scalarfield import DiffScalarField @@ -406,6 +406,10 @@ def _coerce_map_from_(self, other): sage: CM = M.scalar_field_algebra() sage: CM._coerce_map_from_(SR) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: CM._coerce_map_from_(SCR) + True sage: CM._coerce_map_from_(X.function_ring()) True sage: U = M.open_subset('U', coord_def={X: x>0}) @@ -418,7 +422,7 @@ def _coerce_map_from_(self, other): """ from sage.manifolds.chart_func import ChartFunctionRing - if other is SR: + if isinstance(other, SymbolicRing): return True # coercion from the base ring (multiplication by the # algebra unit, i.e. self.one()) # cf. ScalarField._lmul_() for the implementation of diff --git a/src/sage/manifolds/scalarfield_algebra.py b/src/sage/manifolds/scalarfield_algebra.py index 6d6ba2f88ca..52c89fd9959 100644 --- a/src/sage/manifolds/scalarfield_algebra.py +++ b/src/sage/manifolds/scalarfield_algebra.py @@ -36,7 +36,7 @@ from sage.misc.cachefunc import cached_method from sage.categories.commutative_algebras import CommutativeAlgebras from sage.categories.topological_spaces import TopologicalSpaces -from sage.symbolic.ring import SR +from sage.symbolic.ring import SymbolicRing, SR from sage.manifolds.scalarfield import ScalarField class ScalarFieldAlgebra(UniqueRepresentation, Parent): @@ -509,6 +509,10 @@ def _coerce_map_from_(self, other): sage: CM = M.scalar_field_algebra() sage: CM._coerce_map_from_(SR) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: CM._coerce_map_from_(SCR) + True sage: CM._coerce_map_from_(X.function_ring()) True sage: U = M.open_subset('U', coord_def={X: x>0}) @@ -520,7 +524,7 @@ def _coerce_map_from_(self, other): """ from .chart_func import ChartFunctionRing - if other is SR: + if isinstance(other, SymbolicRing): return True # coercion from the base ring (multiplication by the # algebra unit, i.e. self.one()) # cf. ScalarField._lmul_() for the implementation of From b7470d1784904f04607fbc537ee8995f90c499b1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:14:14 -0700 Subject: [PATCH 07/10] Matrix.is_{positive_operator,cross_positive,lyapunov_like}_on: Handle symbolic subrings like SR --- src/sage/matrix/matrix2.pyx | 38 ++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2f2f1cee854..3a9fc7d802a 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -14288,7 +14288,6 @@ cdef class Matrix(Matrix1): code. The boolean ``semi`` argument exists only to change "greater than zero" into "greater than or equal to zero." """ - from sage.symbolic.ring import SR from sage.rings.real_lazy import RLF,CLF R = self.base_ring() @@ -14297,7 +14296,7 @@ cdef class Matrix(Matrix1): R.has_coerce_map_from(RLF) or CLF.has_coerce_map_from(R) or R.has_coerce_map_from(CLF) or - R is SR): + isinstance(R, sage.rings.abc.SymbolicRing)): # This is necessary to avoid "going through the motions" # with e.g. a one-by-one identity matrix over the finite # field of order 5^2, which might otherwise look positive- @@ -16904,8 +16903,15 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_positive_operator_on(K) + True """ - from sage.symbolic.ring import SR import sage.geometry.abc if K2 is None: @@ -16913,7 +16919,7 @@ cdef class Matrix(Matrix1): if not (isinstance(K1, sage.geometry.abc.ConvexRationalPolyhedralCone) and isinstance(K2, sage.geometry.abc.ConvexRationalPolyhedralCone)): raise TypeError('K1 and K2 must be cones.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) @@ -17048,13 +17054,20 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_cross_positive_on(K) + True """ - from sage.symbolic.ring import SR import sage.geometry.abc if not isinstance(K, sage.geometry.abc.ConvexRationalPolyhedralCone): raise TypeError('K must be a cone.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) @@ -17302,6 +17315,15 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_lyapunov_like_on(K) + True + A matrix is Lyapunov-like on a cone if and only if both the matrix and its negation are cross-positive on the cone:: @@ -17314,14 +17336,12 @@ cdef class Matrix(Matrix1): ....: (-L).is_cross_positive_on(K)) # long time sage: actual == expected # long time True - """ - from sage.symbolic.ring import SR import sage.geometry.abc if not isinstance(K, sage.geometry.abc.ConvexRationalPolyhedralCone): raise TypeError('K must be a cone.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) From 5fca7fcdbc9370b47bfdeb7883a4c3bce602283d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:33:14 -0700 Subject: [PATCH 08/10] continued_fraction: Handle symbolic subrings like SR --- src/sage/rings/continued_fraction.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index cf5f8b1f9eb..d7d77afb8a7 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -207,6 +207,7 @@ from sage.structure.sage_object import SageObject from sage.structure.richcmp import richcmp_method, rich_to_bool +import sage.rings.abc from .integer import Integer from .integer_ring import ZZ from .infinity import Infinity @@ -2601,6 +2602,12 @@ def continued_fraction(x, value=None): sage: continued_fraction(1.575709393346379) [1; 1, 1, 2, 1, 4, 18, 1, 5, 2, 25037802, 7, 1, 3, 1, 28, 1, 8, 2] + + Constants in symbolic subrings work like constants in ``SR``:: + + sage: SCR = SR.subring(no_variables=True) + sage: continued_fraction(SCR(pi)) + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] """ if isinstance(x, ContinuedFraction_base): @@ -2675,10 +2682,9 @@ def continued_fraction(x, value=None): if x.parent().is_exact(): return ContinuedFraction_real(x) - # we treat separately the symbolic ring that holds all constants and - # which is not exact - from sage.symbolic.ring import SR - if x.parent() == SR: + # We treat the Symbolic Ring and its subrings separately. They hold all constants and + # are not exact. + if isinstance(x.parent(), sage.rings.abc.SymbolicRing): return ContinuedFraction_real(x) return continued_fraction(continued_fraction_list(x)) From 038eb9f5b13f606f29935b70c47a20ba1cb506a7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:46:11 -0700 Subject: [PATCH 09/10] src/sage/symbolic/pynac_impl.pxi (py_is_integer, py_is_exact): Handle symbolic subrings like SR --- src/sage/symbolic/pynac_impl.pxi | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index 4b46fc69133..482593b2ef4 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -307,7 +307,6 @@ cdef subs_args_to_PyTuple(const GExMap& map, unsigned options, const GExVector& ] x """ - from sage.symbolic.ring import SR res = [] res.append(new_SubstitutionMap_from_GExMap(map)) res.append(options) @@ -1118,6 +1117,10 @@ cdef bint py_is_integer(x): True sage: py_is_integer(SR(5)) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: py_is_integer(SCR(5)) + True sage: py_is_integer(4/2) True sage: py_is_integer(QQbar(sqrt(2))^2) @@ -1132,8 +1135,8 @@ cdef bint py_is_integer(x): if not isinstance(x, Element): return False P = (x)._parent - from .ring import SR - return (P is SR or P.is_exact()) and x in ZZ + from .ring import SymbolicRing + return (isinstance(P, SymbolicRing) or P.is_exact()) and x in ZZ def py_is_integer_for_doctests(x): @@ -1221,8 +1224,8 @@ cdef bint py_is_exact(x): if not isinstance(x, Element): return False P = (x)._parent - from .ring import SR - return P is SR or P.is_exact() + from .ring import SymbolicRing + return isinstance(P, SymbolicRing) or P.is_exact() cdef py_numer(n): From ff83c4cbca77c709021afb00a5632b80f02e0683 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:54:10 -0700 Subject: [PATCH 10/10] sage.repl.ipython_kernel (widget_from_tuple, slider): Handle symbolic subrings like SR --- src/sage/repl/ipython_kernel/interact.py | 12 ++++++++++-- src/sage/repl/ipython_kernel/widgets_sagenb.py | 14 +++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 1e344d8373f..b9970f551a7 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -41,7 +41,7 @@ from .widgets import EvalText, SageColorPicker from .widgets_sagenb import input_grid from sage.structure.element import parent -from sage.symbolic.ring import SR +import sage.rings.abc from sage.plot.colors import Color from sage.structure.element import Matrix @@ -209,6 +209,14 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): Dropdown(index=1, options={'one': 1, 'two': 2, 'three': 3}, value=2) sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) + + TESTS: + + Symbolic subrings:: + + sage: SCR = SR.subring(no_variables=True) + sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) ) + FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) """ # Support (description, abbrev) if len(abbrev) == 2 and isinstance(abbrev[0], str): @@ -223,7 +231,7 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): # Numerically evaluate symbolic expressions def n(x): - if parent(x) is SR: + if isinstance(parent(x), sage.rings.abc.SymbolicRing): return x.numerical_approx() else: return x diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 33ce4898ca7..45c2d9350ce 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -42,8 +42,7 @@ from sage.structure.all import parent from sage.arith.srange import srange from sage.plot.colors import Color -from sage.symbolic.ring import SR -from sage.rings.all import RR +import sage.rings.abc from .widgets import HTMLText as text_control @@ -234,6 +233,14 @@ def slider(vmin, vmax=None, step_size=None, default=None, label=None, display_va True sage: slider(5, display_value=False).readout False + + Symbolic subrings work like ``SR``:: + + sage: SCR = SR.subring(no_variables=True) + sage: w = slider(SCR(e), SCR(pi)); w + TransformFloatSlider(value=2.718281828459045, max=3.141592653589793, min=2.718281828459045) + sage: parent(w.get_interact_value()) + Real Field with 53 bits of precision """ kwds = {"readout": display_value} if label: @@ -271,7 +278,8 @@ def err(v): p = parent(sum(x for x in (vmin, vmax, step_size) if x is not None)) # Change SR to RR - if p is SR: + if isinstance(p, sage.rings.abc.SymbolicRing): + from sage.rings.real_mpfr import RR p = RR # Convert all inputs to the common parent