Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2ac69da
Excluded Unnecessary module imports from slotscheck
shishir-11 Feb 13, 2024
427ea63
maint(ci): add more tests for python-flint in CI
oscarbenjamin Mar 5, 2024
058e898
Use yaml multline syntax
oscarbenjamin Mar 5, 2024
0488164
Fix yaml syntax for python-flint CI job
oscarbenjamin Mar 5, 2024
a73c83d
Fix yaml syntax in python-flint job
oscarbenjamin Mar 5, 2024
ce035a0
polys: add modulus() method to ModularInteger for flint compat
oscarbenjamin Mar 5, 2024
3c28294
fix(polys): strip leading zeros in dup_slice
oscarbenjamin Mar 5, 2024
5ad0fe8
fix(integrals): fix as_poly_1t coefficient manipulation
oscarbenjamin Mar 6, 2024
ba8360b
remove unneeded imports
oscarbenjamin Mar 6, 2024
702ff6b
fix(polys): dup_zz_factor: sort factors from Flint
oscarbenjamin Mar 6, 2024
c263804
test: skip some doctests under Flint because printing differs
oscarbenjamin Mar 6, 2024
5051d11
fix(polys): fix pexquo with Flint polys
oscarbenjamin Mar 6, 2024
e6a9f62
fix(polys): fix sign of DMP.cancel with flint
oscarbenjamin Mar 6, 2024
c083409
fix(polys): don't use Flint for div in ZZ[x]
oscarbenjamin Mar 6, 2024
6b8c856
fix(polys): fix lcm for QQ[x] with flint
oscarbenjamin Mar 6, 2024
26cb274
test(polys): skip some doctests under flint
oscarbenjamin Mar 6, 2024
bd806eb
Merge pull request #26312 from oscarbenjamin/pr_flint_more_tests
smichr Mar 7, 2024
adbc50b
Use raw python type in wigner_3j
shishir-11 Mar 8, 2024
1773ddf
put expected types first
smichr Mar 8, 2024
9311d64
remove negation of m_3
smichr Mar 8, 2024
cf5cc4d
Merge pull request #26327 from shishir-11/fix-wigner-type
smichr Mar 8, 2024
14a6e27
Merge pull request #26225 from shishir-11/Fix-Slotcheck-Issue
oscarbenjamin Mar 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions .github/workflows/runtests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,23 +239,32 @@ jobs:
- run: pip install -r requirements-dev.txt
- run: pip install python-flint
# Test the modules that most directly use python-flint
- run: pytest sympy/polys sympy/ntheory sympy/matrices
- run: >-
pytest
sympy/crypto
sympy/integrals
sympy/holonomic
sympy/matrices
sympy/ntheory
sympy/polys
sympy/solvers
env:
SYMPY_GROUND_TYPES: flint
- run: bin/doctest \
sympy/integrals \
sympy/holonomic \
sympy/matrices \
sympy/ntheory \
sympy/polys \
sympy/printing \
doc/src/modules/integrals \
doc/src/modules/holonomic \
doc/src/modules/matrices \
doc/src/modules/ntheory.rst \
doc/src/modules/polys \
doc/src/modules/printing.rst \
doc/src/tutorials/intro-tutorial/ \
- run: >-
bin/doctest
sympy/integrals
sympy/holonomic
sympy/matrices
sympy/ntheory
sympy/polys
sympy/printing
doc/src/modules/integrals
doc/src/modules/holonomic
doc/src/modules/matrices
doc/src/modules/ntheory.rst
doc/src/modules/polys
doc/src/modules/printing.rst
doc/src/tutorials/intro-tutorial/
env:
SYMPY_GROUND_TYPES: flint

Expand Down
10 changes: 5 additions & 5 deletions doc/src/modules/polys/domainsintro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ might give a ``float`` which is not an element of :ref:`ZZ`::

The behaviour of ``/`` for non-fields can also differ for different
implementations of the ground types of the domain. For example with
`SYMPY_GROUND_TYPES=flint` dividing two elements of :ref:`ZZ` will raise an
``SYMPY_GROUND_TYPES=flint`` dividing two elements of :ref:`ZZ` will raise an
error rather than return a float::

>>> z1 / z1 # doctest: +SKIP
Expand Down Expand Up @@ -573,11 +573,11 @@ finite field of prime order `p` can be constructed with :ref:`GF(p)`::
>>> from sympy import GF
>>> K = GF(5)
>>> two = K(2)
>>> two
>>> two #doctest: +SKIP
2 mod 5
>>> two ** 2
>>> two ** 2A #doctest: +SKIP
4 mod 5
>>> two ** 3
>>> two ** 3 #doctest: +SKIP
3 mod 5

There is also ``FF`` as an alias for ``GF`` (standing for "finite field" and
Expand All @@ -593,7 +593,7 @@ a field. It is just the integers modulo ``6`` or ``9`` and therefore has zero
divisors and non-invertible elements::

>>> K = GF(6)
>>> K(3) * K(2)
>>> K(3) * K(2) #doctest: +SKIP
0 mod 6

It would be good to have a proper implementation of prime-power order finite
Expand Down
19 changes: 15 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ markers = [

[tool.ruff]
# Enable Pyflakes `E` and `F` codes by default.
select = [
lint.select = [
"C40",
"C416",
"C419",
Expand All @@ -40,7 +40,7 @@ select = [
]

# Ignore rules that currently fail on the SymPy codebase
ignore = [
lint.ignore = [
"E401", # Multiple imports on one line
"E402", # Module level import not at top of file
"E501", # Line too long (<LENGTH> > 88 characters)
Expand Down Expand Up @@ -81,10 +81,10 @@ exclude = [
line-length = 88

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Per-file ignores currently specified in the flake8 configuration
[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"sympy/interactive/session.py" = ["F821"]

# Global mypy settings:
Expand Down Expand Up @@ -137,3 +137,14 @@ module = [
"pysat.*",
]
ignore_missing_imports = true

[tool.slotscheck]
strict-imports = true
exclude-modules = '''
(
sympy.parsing.latex._antlr
|sympy.parsing.autolev._antlr
|sympy.galgebra
|sympy.plotting.pygletplot
)
'''
6 changes: 4 additions & 2 deletions sympy/crypto/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from sympy.polys.polytools import Poly
from sympy.utilities.misc import as_int, filldedent, translate
from sympy.utilities.iterables import uniq, multiset
from sympy.utilities.decorator import doctest_depends_on


class NonInvertibleCipherWarning(RuntimeWarning):
Expand Down Expand Up @@ -2284,6 +2285,7 @@ def decode_morse(msg, sep='|', mapping=None):
#################### LFSRs ##########################################


@doctest_depends_on(ground_types=['python', 'gmpy'])
def lfsr_sequence(key, fill, n):
r"""
This function creates an LFSR sequence.
Expand Down Expand Up @@ -2373,7 +2375,7 @@ def lfsr_sequence(key, fill, n):
raise TypeError("key must be a list")
if not isinstance(fill, list):
raise TypeError("fill must be a list")
p = key[0].mod
p = key[0].modulus()
F = FF(p)
s = fill
k = len(fill)
Expand Down Expand Up @@ -2494,7 +2496,7 @@ def lfsr_connection_polynomial(s):

"""
# Initialization:
p = s[0].mod
p = s[0].modulus()
x = Symbol("x")
C = 1*x**0
B = 1*x**0
Expand Down
36 changes: 14 additions & 22 deletions sympy/integrals/risch.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from sympy.core.function import Lambda
from sympy.core.mul import Mul
from sympy.core.intfunc import ilcm
from sympy.core.numbers import I, oo
from sympy.core.numbers import I
from sympy.core.power import Pow
from sympy.core.relational import Ne
from sympy.core.singleton import S
Expand All @@ -43,7 +43,7 @@
tan, acot, cot, asin, acos)
from .integrals import integrate, Integral
from .heurisch import _symbols
from sympy.polys.polyerrors import DomainError, PolynomialError
from sympy.polys.polyerrors import PolynomialError
from sympy.polys.polytools import (real_roots, cancel, Poly, gcd,
reduced)
from sympy.polys.rootoftools import RootSum
Expand Down Expand Up @@ -860,26 +860,18 @@ def as_poly_1t(p, t, z):
# Either way, if you see this (from the Risch Algorithm) it indicates
# a bug.
raise PolynomialError("%s is not an element of K[%s, 1/%s]." % (p, t, t))
d = pd.degree(t)
one_t_part = pa.slice(0, d + 1)
r = pd.degree() - pa.degree()
t_part = pa - one_t_part
try:
t_part = t_part.to_field().exquo(pd)
except DomainError as e:
# issue 4950
raise NotImplementedError(e)
# Compute the negative degree parts.
one_t_part = Poly.from_list(reversed(one_t_part.rep.to_list()), *one_t_part.gens,
domain=one_t_part.domain)
if 0 < r < oo:
one_t_part *= Poly(t**r, t)

one_t_part = one_t_part.replace(t, z) # z will be 1/t
if pd.nth(d):
one_t_part *= Poly(1/pd.nth(d), z, expand=False)
ans = t_part.as_poly(t, z, expand=False) + one_t_part.as_poly(t, z,
expand=False)

t_part, remainder = pa.div(pd)

ans = t_part.as_poly(t, z, expand=False)

if remainder:
one = remainder.one
tp = t*one
r = pd.degree() - remainder.degree()
z_part = remainder.transform(one, tp) * tp**r
z_part = z_part.replace(t, z).to_field().quo_ground(pd.LC())
ans += z_part.as_poly(t, z, expand=False)

return ans

Expand Down
31 changes: 17 additions & 14 deletions sympy/physics/wigner.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
from sympy.core.add import Add
from sympy.core.numbers import int_valued
from sympy.core.function import Function
from sympy.core.numbers import (Float, I, Integer, pi, Rational, equal_valued)
from sympy.core.numbers import (Float, I, Integer, pi, Rational)
from sympy.core.singleton import S
from sympy.core.symbol import Dummy
from sympy.core.sympify import sympify
Expand Down Expand Up @@ -108,18 +108,22 @@ def _calc_factlist(nn):
return _Factlist[:int(nn) + 1]


def _Integer_or_halfInteger(value):
def _int_or_halfint(value):
"""return Python int unless value is half-int (then return float)"""
if isinstance(value, int):
return Integer(value)
elif isinstance(value, (float, Float)):
if isinstance(value, float) and value.is_integer():
return Integer(int(value))
elif (equal_valued((v:=2*value), (i:=int(v)))):
return Rational(i, 2)
elif isinstance(value, Integer):
return value
elif isinstance(value, Rational) and value.q == 2:
return value
elif type(value) is float:
if value.is_integer():
return int(value) # an int
if (2*value).is_integer():
return value # a float
elif isinstance(value, Rational):
if value.q == 2:
return value.p/value.q # a float
elif value.q == 1:
return value.p # an int
elif isinstance(value, Float):
return _int_or_halfint(float(value))
raise ValueError("expecting integer or half-integer, got %s" % value)


Expand Down Expand Up @@ -210,7 +214,7 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
- Jens Rasch (2009-03-24): initial version
"""

j_1, j_2, j_3, m_1, m_2, m_3 = map(_Integer_or_halfInteger,
j_1, j_2, j_3, m_1, m_2, m_3 = map(_int_or_halfint,
[j_1, j_2, j_3, m_1, m_2, m_3])

if m_1 + m_2 + m_3 != 0:
Expand All @@ -227,8 +231,6 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
if (abs(m_1) > j_1) or (abs(m_2) > j_2) or (abs(m_3) > j_3):
return S.Zero

prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
m_3 = -m_3
maxfact = max(j_1 + j_2 + j_3 + 1, j_1 + abs(m_1), j_2 + abs(m_2),
j_3 + abs(m_3))
_calc_factlist(int(maxfact))
Expand Down Expand Up @@ -260,6 +262,7 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
_Factlist[int(j_1 + j_2 - j_3 - ii)]
sumres = sumres + Integer((-1) ** ii) / den

prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
res = ressqrt * sumres * prefid
return res

Expand Down
3 changes: 3 additions & 0 deletions sympy/polys/densebasic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,9 @@ def dup_slice(f, m, n, K):

f = f[N:M]

while f and f[0] == K.zero:
f.pop(0)

if not f:
return []
else:
Expand Down
2 changes: 2 additions & 0 deletions sympy/polys/domains/finitefield.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Implementation of :class:`FiniteField` class. """

from sympy.external.gmpy import GROUND_TYPES
from sympy.utilities.decorator import doctest_depends_on

from sympy.core.numbers import int_valued
from sympy.polys.domains.field import Field
Expand Down Expand Up @@ -50,6 +51,7 @@ def _modular_int_factory(mod, dom, symmetric, self):


@public
@doctest_depends_on(modules=['python', 'gmpy'])
class FiniteField(Field, SimpleDomain):
r"""Finite field of prime order :ref:`GF(p)`

Expand Down
3 changes: 3 additions & 0 deletions sympy/polys/domains/modularinteger.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def __init__(self, val):
else:
self.val = self.dom.convert(val) % self.mod

def modulus(self):
return self.mod

def __hash__(self):
return hash((self.val, self.mod))

Expand Down
2 changes: 1 addition & 1 deletion sympy/polys/factortools.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ def dup_zz_factor(f, K):
f_flint = fmpz_poly(f[::-1])
cont, factors = f_flint.factor()
factors = [(fac.coeffs()[::-1], exp) for fac, exp in factors]
return cont, factors
return cont, _sort_factors(factors)

cont, g = dup_primitive(f, K)

Expand Down
1 change: 1 addition & 0 deletions sympy/polys/matrices/domainmatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ def from_rep(cls, rep):
return self

@classmethod
@doctest_depends_on(ground_types=['python', 'gmpy'])
def from_list(cls, rows, domain):
r"""
Convert a list of lists into a DomainMatrix
Expand Down
19 changes: 13 additions & 6 deletions sympy/polys/polyclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1949,14 +1949,19 @@ def _pexquo(f, g):
"""Polynomial exact pseudo-quotient of ``f`` and ``g``. """
d = f.degree() - g.degree() + 1
q, r = divmod(g.LC()**d * f._rep, g._rep)
if not r:
if r:
raise ExactQuotientFailed(f, g)
return q
return f.from_rep(q, f.dom)

def _div(f, g):
"""Polynomial division with remainder of ``f`` and ``g``. """
q, r = divmod(f._rep, g._rep)
return f.from_rep(q, f.dom), f.from_rep(r, f.dom)
if f.dom.is_Field:
q, r = divmod(f._rep, g._rep)
return f.from_rep(q, f.dom), f.from_rep(r, f.dom)
else:
# XXX: python-flint defines division in ZZ[x] differently
q, r = f.to_DMP_Python()._div(g.to_DMP_Python())
return q.to_DUP_Flint(), r.to_DUP_Flint()

def _rem(f, g):
"""Computes polynomial remainder of ``f`` and ``g``. """
Expand Down Expand Up @@ -2104,7 +2109,9 @@ def _lcm(f, g):

l = f._mul(g)._exquo(f._gcd(g))

if l.LC() < 0:
if l.dom.is_Field:
l = l.monic()
elif l.LC() < 0:
l = l.neg()

return l
Expand Down Expand Up @@ -2136,7 +2143,7 @@ def _cancel(f, g):
elif f_neg:
cF, F = -cF, F.neg()
elif g_neg:
cG, G = -cG, G.neg()
cF, G = -cF, G.neg()

return cF, cG, F, G

Expand Down
4 changes: 4 additions & 0 deletions sympy/polys/tests/test_densebasic.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,10 @@ def test_dup_slice():

assert dup_slice([1, 2], 0, 3, ZZ) == [1, 2]

g = [1, 0, 0, 2]

assert dup_slice(g, 0, 3, ZZ) == [2]


def test_dup_random():
f = dup_random(0, -10, 10, ZZ)
Expand Down
Loading