Skip to content

Commit

Permalink
Merge branch 'u/mkoeppe/replace______is_sr__by_isinstance______sage_r…
Browse files Browse the repository at this point in the history
…ings_abc_symbolicring__to_handle_symbolic_subrings' of git://trac.sagemath.org/sage into t/32601/modularization_of_sagelib__break_out_a_separate_package_sagemath_standard_no_symbolics
  • Loading branch information
mkoeppe committed Nov 1, 2021
2 parents 7373f4f + ff83c4c commit 1c4c53c
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 40 deletions.
9 changes: 5 additions & 4 deletions src/sage/combinat/q_analogues.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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::
Expand Down Expand Up @@ -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'
Expand Down
5 changes: 2 additions & 3 deletions src/sage/dynamics/arithmetic_dynamics/projective_ds.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,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)
lazy_import("sage.symbolic.ring", "SR")
from itertools import count, product
from .endPN_automorphism_group import (
automorphism_group_QQ_CRT,
Expand Down Expand Up @@ -423,8 +422,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)
Expand Down
15 changes: 12 additions & 3 deletions src/sage/functions/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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.
Expand Down
10 changes: 9 additions & 1 deletion src/sage/geometry/polyhedron/parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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():
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 6 additions & 2 deletions src/sage/manifolds/differentiable/scalarfield_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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})
Expand All @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/sage/manifolds/scalarfield_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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})
Expand All @@ -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
Expand Down
38 changes: 29 additions & 9 deletions src/sage/matrix/matrix2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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-
Expand Down Expand Up @@ -16904,16 +16903,23 @@ 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:
K2 = K1
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)

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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::

Expand All @@ -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)

Expand Down
13 changes: 10 additions & 3 deletions src/sage/repl/ipython_kernel/interact.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
from .widgets import EvalText, SageColorPicker
from .widgets_sagenb import input_grid
from sage.structure.element import parent
from sage.misc.lazy_import import lazy_import
lazy_import("sage.symbolic.ring", "SR")
import sage.rings.abc
from sage.plot.colors import Color
from sage.structure.element import Matrix

Expand Down Expand Up @@ -210,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):
Expand All @@ -224,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
Expand Down
15 changes: 11 additions & 4 deletions src/sage/repl/ipython_kernel/widgets_sagenb.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@
from sage.structure.all import parent
from sage.arith.srange import srange
from sage.plot.colors import Color
from sage.misc.lazy_import import lazy_import
lazy_import("sage.symbolic.ring", "SR")
from sage.rings.all import RR
import sage.rings.abc


from .widgets import HTMLText as text_control
Expand Down Expand Up @@ -235,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:
Expand Down Expand Up @@ -272,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
Expand Down
14 changes: 10 additions & 4 deletions src/sage/rings/continued_fraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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))
Expand Down
Loading

0 comments on commit 1c4c53c

Please sign in to comment.