Release Notes for 1.13 - sympy/sympy GitHub Wiki

These are the release notes for SymPy 1.13. You can also find release notes for previous versions.

SymPy 1.13 has not been released yet.

This version of SymPy has been tested on Python 3.8, 3.9, 3.10, 3.11, and PyPy. See our Python version support policy for more information on when we plan to drop support for older Python versions.

Install SymPy with

pip install -U sympy

or if you use Anaconda

conda install sympy

Highlights

There are many changes in 1.13 (see below).

Backwards compatibility breaks and deprecations

Changes

  • algebras

  • assumptions

    • Linear inequalities and equalities with real variables and rational coefficients are now understood by ask. For example, queries like ask(x > 1, x> 0) will no longer return None. However, x needs to be initialized as a real variable like this: x = symbols("x", real=True). (#25544 by @smichr, @TiloRC, and @Upabjojr)

    • Make ask(Q.transcendental(x), Q.algebraic(x) | (0 > y)) give None, not False (#25246 by @TiloRC)

  • calculus

    • Added support for trigonometric and hyperbolic functions and their inverses in continuous_domain() and singularities(). (#25948 by @gschintgen)

    • Improve handling of powers in continuous_domain(). (#25948 by @gschintgen)

  • codegen

  • combinatorics

    • Changed the behavior of PermutationGroup.elements to output a list of all elements rather than a set. It now caches the result in the self._elements attribute. Note that PermutationGroup._elements is no longer a property but has been changed to an attribute (which is set to an empty list on initialization). (#26455 by @AlexisSchotte)

    • PermutationGroup.center() now caches its result in self._center . (#26455 by @AlexisSchotte)

    • Fixed a bug with the simplification of group presentations. (#26185 by @AlexisSchotte)

    • Removed _simplification_technique_1 function and moved its content to _simplify_relators (#26185 by @AlexisSchotte)

    • Added groups_count function to count the number of groups of order n (#25947 by @haru-44)

  • core

    • expand will now accept the hint exact which may be useful when trying to expand the numerator of a fraction having a power like x**-y which is to be kept in the numerator instead of defaulting to the denominator (#26347 by @smichr)

    • Conversion from numpy types like float64 has been changed for compatibility with numpy 2.0. (#26112 by @oscarbenjamin)

    • minor changes in mod as mentioned in commnet (#26031 by @harshkasat)

    • Float.is_integer is now None except for 0.0 and Floats with a non-zero fraction. Previously, only Float(0) was True (#25875 by @smichr)

    • Fixed Eq incorrectly evaluating to False in some cases with floats. (#25875 by @smichr)

    • a condition that would lead to an infinite loop while flattening a product has been corrected (#25844 by @smichr)

    • expand_log now detects the ratio log(a)/log(b) and will simplify if a == c*b**m (#25751 by @smichr)

    • BREAKING CHANGE: The sympify function previously would fall back to converting an object to a string with str(obj) and then parsing that string with parse_expr. This behaviour was already deprecated and had been giving a SymPyDeprecationWarning since SymPy 1.6. As of SymPy 1.13 this string parsing fallback is now removed and in the situations where it might have previously been used SympifyError will be raised instead. Keeping this behaviour even in deprecated form is problematic because it leads to warnings in situations that should just give TypeError so the behaviour is now fully removed. (#25761 by @oscarbenjamin)

    • BREAKING CHANGE eq.rewrite(Add) should be replaced with eq.lhs - eq.rhs (#25706 by @smichr)

    • fixed off-by-one error when calculating int(n) when n is a numerical expression that almost evaluates to an integer (#25704 by @platypus999 and @smichr)

    • BREAKING CHANGE: Float and Integer/Rational no longer compare equal with a == b. From now on Float(2.0) != Integer(2). Previously expressions involving Float would compare unequal e.g. x*2.0 != x*2 but an individual Float would compare equal to an Integer. In SymPy 1.7 a Float will always compare unequal to an Integer even if they have the same "value". Use sympy.numbers.int_valued(number) to test if a number is a concrete number with no decimal part. (#25614 by @smichr)

    • BREAKING CHANGE: Floats with different prevision no longer compare equal with a == b. From now on Float(2.0, 10) != Float(2.0, 5). Previously expressions involving Float with different precision would compare equal although they would have different hashes. Now expressions compared with a == b involving Floats respect structural equality since Floats of differing precision are not interchangeable. (#25614 by @smichr)

    • The hash function for Floats and expressions involving Float now respects the hash invariant that if a == b then hash(a) == hash(b). This ensures that it is possible to use such expressions in a guaranteed deterministic way in Python's core set and dict data structures. It is however not recommended to mix up sympy Basic objects with non-sympy number types such as core Python's float or int in the same set/dict. (#25614 by @smichr)

    • It is now possible to replace Float with Integer in an expression using the Basic.replace method. (#25614 by @smichr)

    • Basic.is_same(a, b) returns True only if all classes are exactly the same; has option to test numbers with custom rule (#25614 by @smichr)

    • divmod(a,b) now gives i, r with abs(r) < abs(b) when a*b is a negative float, e.g. divmod(S(4), S(-2.0)) -> (-2, 0.0) (#25648 by @smichr)

    • added int_valued function to sympy/core/numbers.py for testing whether an expression is a literal number with no decimal portion (#25640 by @smichr)

    • Some fixes were made for compatibility with recent changes in mpmath (since mpmath's 1.3 release). SymPy versions <=1.12 may be incompatible with mpmath versions >1.3. (#25290 by @oscarbenjamin and @smichr)

    • Float is more strict about the use of underscore when parsing numbers: an underscore must be surrounded by one or more digits. (#25290 by @oscarbenjamin and @smichr)

    • Fixed issue of Basic not subclassable with Generic by multiple inheritance. (#25557 by @sylee957)
    • new file intfunc.py was added and is not the place to import new function num_digits: returns number of digits in a number in a given base (e.g. ndigits(100,10) == 3) (#25534 by @smichr)

    • files moved to intfunc from power (isqrt, integer_log and integer_nthroot) and from numbers (igcd, igcd2, igcd_lehmer, ilcm, igcdex, and mod_inverse) (#25534 by @smichr)

    • ilcm now returns an int, not an Integer (#25096 by @haru-44 and @smichr)

    • The evaluate context manager is now reentrant and reusable. (#25000 by @asmeurer)
    • A bug preventing the use of the old assumptions under evaluate(False) was fixed. (#23693 by @oscarbenjamin)

    • A rare bug from using Symbol in multithreaded code was fixed. Previously an exception might be raised when comparing two symbols while querying an assumption in a parallel thread. (#24882 by @oscarbenjamin)

    • Symbols with assumptions are now encoded more efficiently in pickles reducing the number of bytes needed for each symbol. (#24882 by @oscarbenjamin)

    • Multiplication of large expressions was made faster by reducing unnecessary assumptions queries. (#24884 by @oscarbenjamin)

    • Fix as_coeff_Mul to return (0.0, 1) for Float(0.0) (#24772 by @meganly)

  • discrete

  • functions

    • Fixed a bug with log of integers. Formerly, log(-x) incorrectly gave -log(x). (#26444 by @samuelard7)

    • DEPRECATION : moved is_carmichael from functions to ntheory. The code from sympy import carmichael; carmichael.is_carmichael(1) or from sympy.functions import carmichael; carmichael.is_carmichael(1) needs to be modified to from sympy import is_carmichael; is_carmichael(1). (#26050 by @haru-44)

    • DEPRECATION : moved find_carmichael_numbers_in_range, find_first_n_carmichaels from functions to ntheory. The code from sympy import carmichael; carmichael.find_carmichael_numbers_in_range(1, 2) or from sympy.functions import carmichael; carmichael.find_carmichael_numbers_in_range(1, 2) needs to be modified to from sympy.ntheory.factor_ import find_carmichael_numbers_in_range; find_carmichael_numbers_in_range(1, 2). (#26050 by @haru-44)

    • Add new function kronecker_symbol (#26050 by @haru-44)

    • Fixes for order and missing terms in trigonometric integrals in error functions (#26290 by @arnabnandikgp)

    • A bug in series involving hypergeometric functions of functions has been fixed. Previously incorrect series forms were returned in some cases leading to wrong results also for some limits involving hypergeometric functions. (#26264 by @oscarbenjamin)

    • Added tests for assoc_legendre to verify its numerical evaluation with non-integer arguments (#26247 by @mohakmalviya)

    • Implemented the asymptotic series expansion of Ci(x) at -oo, including the I*pi term (#26233 by @mohakmalviya)

    • Fixed usage of visually same variable when converting to integral in error functions. (#26165 by @abhiphile)

    • Corrected the code for unique visibility of variable of integration. (#26147 by @abhiphile)

    • Fixed usage of visually same variable when converting to integral in beta functions. (#26159 by @abhiphile)

    • Fixed usage of visually same variable when converting to integral in elliptical functions. (#26152 by @shishir-11)

    • _eval_rewrite_as_Integral method was added for error functions like Si, Ci, FresnelS, FresnelC and Ei (#26148 by @arnabnandikgp)

    • support expint rewrite as integral. (#26135 by @Ravindu-Hirimuthugoda)

    • .doit method of limit now better handles expressions that have exponents in their leading term. (#26075 by @arnabnandikgp)

    • I made a change in the ceiling as mentioned in the issue (#26033 by @harshkasat)

    • Fixed incorrect limit of Fibonacci ratio to properly converge to the Golden Ratio (#26027 by @saicharan2804)
    • Expanding sin and cos no longer rewrites using radical formulae. (#25994 by @oscarbenjamin)

    • Trig functions can now rewrite to besselj e.g. sin(x).rewrite(besselj). (#25950 by @harshkasat)

    • Added conditions for correct handling of imaginary exponents for different bases in _eval_nseries method of Exponential class (#25943 by @arnabnandikgp)

    • Improved automatic evaluation of arg(exp()). (#25953 by @gschintgen)

    • fixed the eval_aseries method for atan and acot in order to ensure their correct working at the branch cuts. (#25852 by @arnabnandikgp)

    • added extra condition to recognize infinite exponent in mrv when base tends to 1 (#25862 by @arnabnandikgp)

    • ceiling and floor recognize Float that are integers so ceiling(x + 1.0) as 1 + ceiling(x) as the exact symbolic answer (#25872 by @smichr)

    • Improved the _eval_as_leading_term method for inverse trigonometric and hyperbolic functions, ensuring correct behavior when dealing with NaN and infinite values. (#25850 by @saicharan2804)
    • Solved bug with atan when solving a left inf limit (#25763 by @borgesaugusto)

    • Updated pow function in the Quaternion class for improved efficiency and handling of negative powers. (#25385 by @mohammedouahman and @smichr)

    • a logical error in Piecewise simplification was corrected (#25649 by @geetHonve and @smichr)

    • hyper and meijerg function now return canonically ordered tuples; hyper will automatically remove redundant args (#25641 by @smichr)

    • Implemented reality checks for Inverse Hyperbolic functions (#25608 by @HarryMountain)

    • Fixed a bug in RkGate function of qft.py which coused wrong result of inverse quantum Fourier transformation with a decomposition (#25585 by @maremnev and @oscarbenjamin)

    • SingularityFunction(x,0,n) now returns x**n*Heaviside(x, 1) instead of x**n*Heaviside(x) (#25570 by @smichr)

    • SingularityFunction(x, a, n).rewrite(Piecewise) will now evaluate to 1 if x = a and n = 0 (#25570 by @smichr)

    • Fixed noncommutative exponents being incorrectly put in denominators of expressions. (#25110 by @akhmerov)

    • Hyperbolic function rewrites now correctly disable evaluation in cases where they would just rewrite back to another expression. (#25000 by @asmeurer)
    • Use Lucas' Theorem Generalization to calculate binomial coefficients modulo n. (#24891 by @LaurenceWarne)
  • geometry

    • segments and rays touching an ellipse, contained in a line tangent to the ellipse are now considered as being tangents (#26365 by @smichr)

    • Computes the correct intersection result when using floats. (#25425 by @codecruisedor and @smichr)

    • Added a distance method to Line3D that supports Plane, Line3D and Point3D. (#25156 by @manns)

    • Fixed a bug with Polygon.angles. Formerly, incorrectly gave conjugates of interior angles for edge cases. (#24960 by @smichr and @TiloRC)

  • integrals

    • Fix missing special case in manualintegrate quadratic denom rule (#26496 by @ehren and @smichr)

    • fixed the handling of mappings in heurisch to avoid returning false solutions (e.g. for integrate(exp(-I*r**2/2), (r, 0, 1))) (#26358 by @smichr)

    • Added tests that could close the related issues. (#26195 by @abhiphile)

    • Fixed a bug with integrating over negative real numbers using meijerint algorithm. Formerly, integrate(exp(-x**2), (x,-5,0), meijerg=True) incorrectly gave -sqrt(pi)/2 * erf(5) instead of sqrt(pi)/2 * erf(5). (#26173 by @maliesen)

    • several small changes and error corrections in laplace_transform (#25755 by @hanspi42)
    • fixed bug in log_to_real which caused only the log part to be returned (#25900 by @smichr)
    • The Laplace transform can now parse and directly transform the functions Piecewise and SingularityFunction. (#25647 by @hanspi42)

    • The Laplace transform can now deal better with expressions that contain products of sin(t)/t and DiracDelta(t) with arbitrary time shifts. (#25633 by @hanspi42)

    • Rules for the inverse Laplace transform of differentiation, frequency shift, and irrational algebraic functions have been added (#24847 by @hanspi42)

    • Fixed bug with sqrt(a) factors in Erf/Fresnel rules to give correct result for negative a (#25098 by @sebtiburzio)

    • A keyword fdict is added to laplace_transform and inverse_laplace_transform that makes it possible to simplify unevaluated transforms. (#24799 by @hanspi42)

  • logic

    • Fixed a bug which shows wrong result in computing anf. (#26183 by @abhiphile)

    • The dpll2 algorithm now has the option to use an LRA theory solver. (#25544 by @smichr, @TiloRC, and @Upabjojr)

    • Added Z3 Theorem Prover as an optional algorithm for satisfiable. Can be used to handle linear and nonlinear inequalities. (#25436 by @TiloRC)

    • Improved handling of logical simplification involving binary symbols like Eq (#25528 by @sahinfalcon)

  • matrices

    • A DomainMatrix.clear_denoms_rowwise() method was added. (#25996 by @oscarbenjamin)

    • DEPRECATION: The superclasses of Matrix are mostly merged together into a single class MatrixBase. The classes MatrixRequired, MatrixShaping, MatrixSpecial, MatrixOperations, MatrixArithmetic, MatrixCommon, MatrixDeterminant, MatrixReductions, MatrixSuspaces, MatrixEigen, MatrixCalculus and MatrixDeprecated are all now deprecated. These classes will be removed in a future release. For now they remain in case downstream code is subclassing them to make different matrix types. However these types are not superclasses of Matrix anymore so e.g. isinstance(Matrix([[1]]]), MatrixCommon) will now return False. The modules sympy.matrices.common and sympy.matrices.matrices are now deprecated and anything imported from there should either not be used or should be imported from somewhere else. All matrix exception types like ShapeError etc have been moved from sympy.matrices.common to a new sympy.matrices.exceptions module and should now be imported from there instead, (#25911 by @oscarbenjamin)

    • The Matrix.inv_mod method was made significantly faster by using DomainMatrix and the GF(p) domain. (#25902 by @oscarbenjamin)

    • A Matrix.lll method was added for the LLL algorithm. (#25880 by @oscarbenjamin)

    • The Matrix.inv() method now uses DomainMatrix by default when a suitable domain can be found for the elements of a matrix. This makes computing matrix inverses enormously faster for common cases like a matrix with polynomial or rational function entries or Gaussian integers etc. Many matrix inverses that would previously take effectively forever to compute can now be computed in a reasonable amount of time. (#25452 by @oscarbenjamin)

    • A.rref_rhs(b) will return rref of A and resulting form of b without reducing b; pivots are returned as 3rd arg (#25687 by @smichr)

    • Fixed Matrix.diff ignoring the evaluate=False option. (#25619 by @sylee957)
    • Fixed block_collapse giving wrong result for Inverse (#24738 by @sylee957)

    • Fixed an issue of adjoint, transpose, conjugate not commuting with inverse for matrix expressions. For example, A.transpose().inverse() and A.inverse().transpose() will give same result. (#24738 by @sylee957)

    • Matrix.charpoly() now uses DomainMatrix to compute the characteristic polynomial of a matrix making it a lot faster. For dense integer matrices charpoly is now about 10x faster. For more complicated symbolic matrices (e.g. with polynomial entries) it is much, much faster so some calculations that would have effectively taken forever can now be completed in reasonable time. (#25458 by @oscarbenjamin)

    • The dense implementation of DomainMatrix will now use python-flint matrices for matrices over ZZ and QQ if SYMPY_GROUND_TYPES=flint and python-flint is installed. A new low-level matrix type DFM is added to be a wrapper for dense flint matrices. DomainMatrix will use this internally by default for dense matrices when the ground types are flint. This makes many operations with dense DomainMatrix much faster although for now to test this you need to explicitly choose to use the dense implementation by doing e.g. M = Matrix([[1, 2], [3, 4]]).to_DM().to_dense() to get a matrix that has a flint matrix as its internal representation. (#25495 by @oscarbenjamin)

    • The DomainMatrix.rref and rref_den methods have been optimised for the ZZ and QQ domains. The new methods for ZZ select between using division or fraction-free Gauss-Jordan elimination depending on sparseness, bit counts, and matrix dimensions. For QQ the denominators are checked to consider whether to clear denominators and use ZZ or otherwise use division over QQ. (#25443 by @oscarbenjamin)

    • Matrix.rref now uses DomainMatrix.rref when the matrix consists only of integers or rational numbers. This makes the rref operation a lot faster and speeds up many other matrix operations that use rref such as computing a matrix inverse, nullspace or solving a matrix equation. The exact timing difference depends on a number of factors and is larger for larger matrices. As an example computing the inverse of a dense 19x19 matrix of integers values between 0 and 100 is about 10000x faster. The speed difference is bigger if gmpy2 is installed since that speeds up elementary integer and rational arithmetic and will now be used by Matrix.rref when possible. (#25443 by @oscarbenjamin)

    • A fraction-free sparse RREF method was added to DomainMatrix. This makes it possible to use fraction-free methods with rref_den to solve equations and compute nullspaces efficiently with large sparse matrices. (#25395 by @oscarbenjamin)

    • The DomainMatrix.nullspace() method is now extended to non field rings so that the nullspace can be computed for e.g. a matrix of polynomials without using division. (#25395 by @oscarbenjamin)

    • DomainMatrix methods charpoly_factor_list and charpoly_factor_blocks are add in addition to the existing charpoly method. These are used to compute factorisation of the characteristic polynomial more efficiently if the matrix can be permuted into block triangular form. Also the DomainMatrix charpoly method was made faster in the case of such matrices. (#25369 by @oscarbenjamin)

    • decompositions: fixed svd. (#25389 by @DarkNisa)

    • DomainMatrix methods are added for extracting gcd and cancelling factors between a matrix and a denominator. These are useful for simplifying the output of fraction free solvers like solve_den as a step towards converting the output back to ordinary sympy expressions. A method cancel_denom is added to cancel common factors between a matrix and a scalar denominator. A method cancel_denom_elementwise is added for fully reducing all elements of a matrix over a denominator. Methods content and primitive are added to compute and factor out the gcd of a matrix. (#25367 by @oscarbenjamin)

    • A number of fraction-free and division free methods for matrix inverse, RREF and solving matrix equations are added to DomainMatrix. These methods are much faster than approaches based on field division for e.g. solving a system of linear equations where the coefficients are polynomial expressions. Also documentation was added for many DomainMatrix methods and for related classes and functions. (#25346 by @oscarbenjamin)

    • DomainMatrix.rref_den: A fraction-free method for computing the reduced row echelon form (RREF) with denominator was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.adj_det: A division-free method for computing the adjugate and determinant of a square matrix was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.adjugate: A division-free method for computing the adjugate of a square matrix was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.inv_den: Fraction-free or division-free method for computing the inverse of a matrix with denominator was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.solve_den: Fraction-free or division-free method for solving a matrix equation A*x = b was added (#25346 by @oscarbenjamin)

    • DomainMatrix.adj_poly_det: A method for computing the polynomial p such that p(A) = adjugate(A) was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.eval_poly: A method for evaluating a polynomial function of a matrix p(A) was added. (#25346 by @oscarbenjamin)

    • DomainMatrix.eval_poly_mul: A method for effciently evaluating a polynomial matrix product p(A)*b was added. (#25346 by @oscarbenjamin)

    • Matrix now has a to_DM() method for converting a Matrix into the lower-level DomainMatrix type which can be faster for many operations and can also do things like working over finite fields. (#25336 by @oscarbenjamin)

    • A method clear_denoms is added to DomainMatrix which can factor out a common denominator from a matrix like the Poly.clear_denoms method. (#25336 by @oscarbenjamin)

    • Various conversion methods from_dok, from_flat_list etc have been added to DomainMatrix and related classes for a more complete set of conversions. (#25336 by @oscarbenjamin)

    • A DomainMatrix.choose_domain method was added to choose a domain based in the expressions in a matrix. This is analogous to the Poly.retract method. (#25336 by @oscarbenjamin)

    • Fixed some corner cases when Matrix.eigenvals gives wrong result when multiplicity=False. (#25283 by @sylee957)
  • ntheory

    • Fixed outputs for floating point number for isprime (#26516 by @shishir-11)

    • .discrete_log now computes the order and its factorization in one pass (#26487 by @teschlg)

    • DEPRECATION : moved primenu, primeomega, totient, reduce_totient, divisor_sigma, primepi, npartitions, legendre_symbol, jacobi_symbol from ntheory to functions. Code that imports these functions from top-level like from sympy import mobius will continue to work fine. However code that imports these from the fully qualified module like from sympy.ntheory import mobius or from sympy.ntheory.residue_ntheory import mobius will now see a deprecation warning. The new location for these functions is in sympy.functions but the intended way to import them is still from top-level like from sympy import mobius. (#26050 by @haru-44)

    • DEPRECATION : moved udivisor_sigma from ntheory to functions. The code from sympy.ntheory.factor_ import udivisor_sigma needs to be modified to from sympy.functions import udivisor_sigma. (#26050 by @haru-44)

    • BREAKING CHANGE : moved mobius from nthoey to functions (#26042 by @haru-44)

    • Made cycle_length docs and behaviour consistent with each other and with cited Wikipedia description of Brent's method (#25923 by @coreycerovsek)

    • Moved is_mersenne_prime from factor_ to primetest (#25905 by @haru-44)

    • Added primetest.proth_test (#25898 by @haru-44)

    • Removed _ismersenneprime and _isperfect. (#25881 by @haru-44 and @smichr)

    • fixes the numerical evaluation of npartitions. (#24293 by @maciejskorski and @smichr)

    • Moved _lucas_sequence from ntheory.primetest to external.ntheory. And removed primetest._lucas_selfridge_params. (#25826 by @haru-44)

    • Changed quadratic_congruence argument name from p to n (#25689 by @haru-44)

    • Add is_fermat_pseudoprime and is_euler_jacobi_pseudoprime functions (#25671 by @haru-44)

    • The behavior of is_euler_pseudoprime has changed. Composite numbers that used to return False may now also return True. (#25629 by @haru-44 and @smichr)

    • Speed up totientrange. (#25631 by @yuanyelele)

    • removed _product (#25598 by @haru-44)

    • files moved to intfunc from factor_ (trailing) (#25534 by @smichr)

    • Arguments of factorint can now be added to the arguments of primefactors. (#25284 by @haru-44)

    • nthroot_mod output when all_roots=False is not an int or None (#25269 by @haru-44)

    • Add new function kronecker_symbol (#25299 by @haru-44)

    • Added sieve_interval option to Sieve (#25204 by @haru-44)

    • Corrected modular arithmetic for elliptic curves. (#25141 by @DarkNisa and @oscarbenjamin)

    • Let continued_fraction_convergents accept standard representation of periodic continued fractions as such might be returned by continued_fraction and continued_fraction_periodic. (#25063 by @cai-lw)

    • Added smallest option to primitive_root (#24883 by @haru-44 and @smichr)

    • removed _is_nthpow_residue_bign (#25045 by @haru-44)

    • removed _polynomial_congruence_prime, _diff_poly, _val_poly (#25039 by @haru-44)

    • removed _nthroot_mod2 (#25036 by @haru-44)

    • Created functions binomial_mod and _binomial_mod_prime_power which can be used to calculate large binomial coefficients modulo arbitrary numbers (#24891 by @LaurenceWarne)

  • parsing

    • Python 3.13 compatibility (#26386 by @jamesjer)

    • Fixed a bug in the Mathematica parser parsing rational objects Rational[p,q]. (#25717 by @jcwhitehead)

    • The Lark-based parser now allows customizability by allowing the user to specify their own LaTeX grammar file. (#25634 by @wermos)

    • The Lark-based LaTeX parser now supports parsing derivative-related expressions. (#25626 by @wermos)

    • parse_latex_lark is now visible from sympy.parsing.latex. (#25535 by @wermos)

    • The Lark-based parser now supports Min, Max, and Bra and Ket. (#25552 by @wermos)

    • The Lark-based LaTeX parser now evaluates the input string and returns the result. For example, "\sqrt{\frac{12}{6}}" will re turn \sqrt(2) now. The previous behavior can achieved by using the evaluate(False) context manager. (#25515 by @wermos)

    • Added a Lark-based LaTeX parser. (#25324 by @Upabjojr and @wermos)

    • The 'strict' parameter is introduced as an additional option in the parse_latex. When set to true, it throws exceptions for invalid formulas. (#25168 by @zzc0430)

  • physics.biomechanics

    • Added biomechanical modeling introduction and model example tutorials. (#25525 by @brocksam and @moorepants)

    • Created a new module that acts to extend physics.mechanics with biomechanical modelling functionality. (#25772 by @brocksam)

    • Implemented musculotendon characteristic curves for tendon and muscle fiber force-length and force-velocity relationships based on De Groote et al., 2016. (#25772 by @brocksam)

    • Implemented classes for modeling activation dynamics, including first-order activation dynamics based on De Groote et al., 2016. (#25772 by @brocksam)

    • Implemented classes for modeling musculotendons with both rigid and elastic tendon musculotendon dynamics. (#25772 by @brocksam)

    • Symengine backend support removed. (#25617 by @moorepants)

  • physics.continuum_mechanics

  • physics.control

  • physics.mechanics

    • implemented DuffingSpring to model the force exerted by a nonlinear spring, based on the Duffing equation (#26438 by @eh111eh)

    • Implemented System.velocity_constraints to allow overwriting the automatically computed velocity constraints. (#26374 by @tjstienstra)

    • BREAKING CHANGE: Deprecate Body class (#26179 by @tjstienstra)

    • BREAKING CHANGE: Deprecate JointsMethod (#26179 by @tjstienstra)

    • Improve Point.vel warning message. (#25708 by @TJStienstra)

    • Symengine backend support removed. (#25617 by @moorepants)

    • Adds an actuator module that provides an actuator base class and four specific implementations: ForceActuator, LinearSpring, LinearDamper, TorqueAcutator. (#25518 by @brocksam and @moorepants)

    • Adds module for constructing force pathways to physics.mechanics. Includes a linear pathway and wrapping pathway. (#25511 by @brocksam and @moorepants)

    • Wrapping geometry module with a Sphere and Cylinder added for facilitating eventual force actuator wrapping needs. (#25510 by @brocksam and @moorepants)

    • Added a linear_solver kwarg to Linearizer and then KanesMethod and LagrangesMethod allowing users to supply alternative linear equation solvers. This is necessary to avoid divide-by-zero in more complicated symbolic expressions. (#24896 by @moorepants)

    • Fixed test_kane3.py (bicycle example) and re-enabled in the test suite. (#24896 by @moorepants)

    • Implemented a new System object to do the book-keeping of all your mechanics objects. (#24962 by @TJStienstra)

    • Implemented Force and Torque objects to store the location and vector of the load. (#24924 by @smichr and @TJStienstra)

    • BREAKING: moved the gravity function from physics.mechanics.functions.py to physics.mechanics.loads.py (#24924 by @smichr and @TJStienstra)

    • Implemented Inertia, an object to store the quantity and reference of an inertia. (#24889 by @TJStienstra)

    • BREAKING: moved the inertia functions from physics.mechanics.functions.py to physics.mechanics.inertia.py (#24889 by @TJStienstra)

    • Added the option to specify the linear solvers used in KanesMethod (#24905 by @TJStienstra)

    • Fixed a bug with KanesMethod.forcing, which could formerly contain derivatives of the generalized coordinates. (#24890 by @TJStienstra)

    • Make Particle and RigidBody compatible with the joints framework. (#24830 by @TJStienstra)

  • physics.quantum

    • Change the baseclass of IdentityOperator from Operator to HermitianOperator and UnitaryOperator (#24910 by @vtomole)

    • Allowed Dagger to treat unrecognized inputs and stay unevaluated. (#24850 by @akhmerov)

    • Implemented fermion exponentiation. (#25072 by @iarayad)

    • Fix normal_ordered_form of multiple fermions (#25074 by @iarayad)

    • TensorProduct now processes immutable matrices and mutable matrices alike. Fixed a bug that TensorProduct didn't compute the result matrix if the argument matrices were immutable. (#24993 by @Costor)

  • physics.units

    • Fixed a bug with convert_to function. (#26423 by @Henrique-S123)

    • Added kilonewtons and meganewtons to the physics submodule (#25976 by @PascalGitz)

    • Fix incorrect cancellation of dimensions when performing substitutions with negative coefficients (#25382 by @mgreminger)

    • Corrected the bug in multiplication between prefix and quantity, e.g. milli * W = 1 which should be W/1000. (#24909 by @HieuLCM)

  • physics.vector

  • physics.wigner

  • plotting

    • Fixed an issue which caused plotting using backend='text' to error. (#26484 by @SamLubelsky)

    • Add 'sign' sympy-to-numpy same function (#25729 by @satels)

    • Improved support for custom labels and rendering options in plotting functions (#25531 by @Davide-sd)

    • Refactoring of *Series classes of the plotting module in order to enable interactive-widgets plots. (#25469 by @Davide-sd)

    • Moved plotting *Backend classes from sympy.plotting.plot to new submodule sympy.plotting.backends. (#25462 by @Davide-sd)

    • Moved all plotting *Series classes from sympy.plotting.plot to sympy.plotting.series. (#25427 by @Davide-sd)

    • Implementing the get_data method for plotting series. (#25414 by @Davide-sd and @smichr)

    • BREAKING CHANGE: Changed relationship between Plot and *Backend classes. Moving from composition to inheritance. (#25132 by @Davide-sd)

    • DEPRECATION: Deprecating markers, annotations, fill, rectangles properties of the Plot class. These can still be provided as keyword arguments to the plot function but setting the attributes on the returned Plot object is now deprecated. (#25117 by @Davide-sd)

    • Replacing nb_of_points_* keyword arguments of plotting module (#25120 by @Davide-sd)

  • polys

    • A bug in sqf was fixed. Previously incorrect results were returned in some cases when computing the square free factorisation of multivariate polynomials. (#26514 by @oscarbenjamin)

    • Improved dup_clear_denoms function's efficiency in symbolic computations. (#26180 by @mohakmalviya and @sylee957)

    • Fixed a bug which gives incorrect results in finding sqf_list for polynomials. (#26182 by @abhiphile)

    • The domain is_Exact and get_exact methods now correctly handle composite domains like polynomial rings and CC.get_exact() now gives QQ_I. (#25982 by @gschintgen and @oscarbenjamin)

    • Missing conversion methods were added for the EX domain. This fixes a bug when integrating expressions involving complex numbers and floats. (#25889 by @oscarbenjamin)

    • The GF(p) domains will now use python-flint's nmod or fmpz_mod implementation with GROUND_TYPES=flint. This makes calculations with GF(p) significantly faster. (#25663 by @oscarbenjamin)

    • DEPRECATION: Ordered comparisons like a < b with elements of GF(p) are now deprecated. When the ground types are flint a comparison such as a < b will give TypeError but if the ground types are not flint then a deprecation warning will be emitted. Also elements of GF(p) do not have a .val attribute when the ground types are flint. (#25663 by @oscarbenjamin)

    • The low-level polynomial implementations such as the polynomial domains and types like DMP now return float('-inf') rather than SymPy's symbolic -oo for degree(0). This is because using -oo was making many operations slow e.g. this change made factorisation over the ZZ_I or QQ_I domains 4x faster for one case. (#25784 by @oscarbenjamin)

    • The ANP class which is used to represent elements of an algebraic field is now built on top of the DMP class which is used to represent dense polynomials. This means that algebraic number fields like QQ<sqrt(2)> can benefit from the speed improvements of python-flint when the ground types are set to flint. (#25764 by @oscarbenjamin)

    • When the ground types are set to flint, python-flint's univariate integer and rational polynomials will be used which can speed up most operations with Poly as well as high-level functions like factor that use Poly internally. (#25722 by @oscarbenjamin)

    • fixed bug in dup_zz_heu_gcd and dmp_zz_heu_gcd (#25725 by @smichr)

    • BREAKING CHANGE: Unification of domains like GF(p) with ZZ or other domains would previously result in ZZ (or any other domain). This now results in a UnificationFailed error. Previously unification like e.g. GF(2).unify(GF(3)) would unify to the large characteristic but this now results in UnificationFailed. (#25666 by @oscarbenjamin)

    • DEPRECATED: The .to_int() method of GF(p) elements is moved to the domain rather than being a method of the elements and element method is deprecated. Previously you could do K = GF(3); a = K(2); ai = a.to_int(). Now a.to_int() is deprecated and it should be ai = K.to_int(a). The purpose of this change is that limiting the behaviour that is expected directly from the elements of GF(p) makes it possible to swap in the more efficient implementation provided by python-flint's nmod. See the deprecation docs for more explanation. (#25652 by @oscarbenjamin)

    • BREAKING CHANGE: The __int__ method of GF(p) elements is now changed so that int(a) always returns the value of a as an integer mod p rather than the symmetric version that sometimes returns negative numbers. Use K.to_int(a) for the symmetric version. The purpose of this change is that limiting the behaviour that is expected directly from the elements of GF(p) makes it possible to swap in the more efficient implementation provided by python-flint's nmod. See the deprecation docs for more explanation. (#25652 by @oscarbenjamin)

    • A new ground type option is added to use python-flint for the ground types rather than Python or gmpy2. For now this is experimental and is not used by default but can be enabled by installing python-flint and setting the environment variable SYMPY_GROUND_TYPES=flint before importing SymPy. With GROUND_TYPES=flint the ZZ and QQ poly domains will use flint.fmpz and flint.fmpq rather than gmpy2.mpz and gmpy2.mpq. This should not lead to any noticeable difference in behaviour for ordinary usage of SymPy but might have an effect on performance in some cases. Both gmpy2 and python-flint use GMP internally so for pure integer/rational arithmetic they should mostly have comparable performance. Adding GROUND_TYPES=flint lays the ground work for adding other flint types that gmpy2 does not have such as polynomials and matrices in future which will bring significant future speedups for SymPy. (#25474 by @oscarbenjamin)

    • A top-level function all_roots is added as a shorthand for calling the Poly.all_roots method. (#25330 by @oscarbenjamin)

    • Added is_square and exsqrt methods for abstract Domain and ZZ, QQ, RR, CC, FF. (#25095 by @cai-lw)

    • Fixed a bug where CRootOf raised KeyError on irreducibles with negative lead coeff. (#24979 by @skieffer)

    • A bug in factor_list was fixed. Previously factor_list might fail with an exception when factoring over EX e.g. an expression involving radicals like sqrt(2). This was causing some integral computations to fail with the same exception. (#24958 by @oscarbenjamin)

  • printing

    • fixed a bug in printing the boolean operators with the maple printer (#26426 by @voffch)

    • Raise ValueError if Symbol does not print to valid C variable name. (#26360 by @moorepants)

    • Added options for printing adjoint symbol in latex. (#26339 by @mohamedrezk122)

    • Fixed LaTeX printing of matrix elements of subscripted matrix symbol giving LaTeX with parsing errors. For example, X_a[0, 0] will print as {X_{a}}_{0,0} (#26201 by @sylee957)
    • Fix issues of Min and Max generating wrong code for jax. (#26149 by @virajvekaria)

    • Code printers for numpy no longer use np.PINF or np.NINF which will be removed in numpy 2.0. (#26112 by @oscarbenjamin)

    • CodePrinter got a new option "strict" (default is generally "True") to raise an exception, instead of generating comments, upon encountering unsupported constructs in a target language. (#25913 by @bjodah)

    • The parse_latex function now supports backend as a keyword argument. The two backends that are currently available are ANTLR and Lark. (#25733 by @smichr and @wermos)

    • Added a rule in CodePrinter to rewrite SingularityFunction as Piecewise (#25677 by @Davide-sd and @smichr)

    • pretty: use combining mark aware centering for equalLengths and stack (#25673 by @smichr)

    • pretty: use combining mark aware wrapping (#25673 by @smichr)

    • Fixed a bug with printing of expint and polylog. (#25599 by @bsach64)

    • smtlib_code(Float(0)) now gives '0.0' instead of '' and smtlib_code(.00003) gives '(* 3.0 (^ 10 -5))' instead of '3.00000000000000e-5'. (#25524 by @TiloRC)

    • Fix cases where NumPyPrinter CodePrinter generates code with incorrect precedence when rewriting functions. (#25514 by @mgreminger)

    • Fixed a bug that prohibited users from defining custom JAX printing for custom classes, which can now be done by defining a _jaxcode method. (#25439 by @brocksam)

    • make SMT-Lib printer handle some predicates from the new assumptions (#25245 by @TiloRC)

    • Fixed a bug with printing Lambdas. Formerly, the signature was printed incorrectly as <tuple>. (#25062 by @dweindl)

  • series

    • Implemented _eval_as_leading_term function for Si function and added tests for the same. (#26209 by @anutosh491)

    • Added leading term and nseries methods for Mod Class. (#25279 by @anutosh491)

  • sets

    • interval intersection will keep Float boundaries in preference to Rational if the underlying values are the same (#25662 by @smichr)

    • Intersection.__new__ now accepts only an explicit keyword-only argument evaluate rather than **kwargs. (#24794 by @Jay-Patankar and @oscarbenjamin)

  • simplify

    • TR3 and TR4 of fu will now work with unevaluated numbers in trig functions; previously such numbers were unchanged (#26390 by @smichr)
    • Fixed an issue where noncommutative symbols with trigonometric functions would give incorrect simplification results. For example, simplify(2*cos(x)*sin(x)*B*A + cos(x)**2) (#25595 by @sylee957)
  • solvers

    • Added a new solver for logarithmic equations. (#26444 by @samuelard7)

    • The internal function cornacchia in the sympy.solvers.diophantine.diophantine, which returned None when no solution exists, has been changed to return set(). (#26314 by @haru-44)

    • The function gaussian_reduce which is an internal helper used by diophantine was refactored and its own internal helper functions dot and norm were removed from the sympy.solvers.diophantine.diophantine module. (#26282 by @haru-44)

    • A bug in solveset due to incorrect handling of Dummy symbols was fixed. Previously the stationary_points function might return incorrect results or raise an error due to this bug. (#26089 by @Ravindu-Hirimuthugoda)

    • Implemented inverting of complex-valued trigonometric or hyperbolic functions. (#26004 by @gschintgen)

    • Improved solveset by using the inverter more often for trigonometric or hyperbolic equations. (#26004 by @gschintgen)

    • Added domain checking to the real-valued trigonometric inverter used by solveset. (#26004 by @gschintgen)

    • nonlinsolve: Fix two bugs related to solving systems involving trigonometric functions. (Wrong results fixed.) (#26004 by @gschintgen)

    • Correct the erroneous result generated by reduce_inequalities and make the necessary adjustments. (#25989 by @Ravindu-Hirimuthugoda)

    • Implemented solving by inverting of hyperbolic equations over the reals in solveset. (#25977 by @gschintgen)

    • sum_of_squares(n,k) will exit more quickly when there are many factors of 4 in n and k is 3 (#25967 by @haru-44 and @smichr)

    • other special cases (when k==3 or k==4) will more also return None more quickly (#25967 by @haru-44 and @smichr)

    • Fix some incorrect results from solveset solving equations with Mod. (#25884 by @asmeurer)
    • DiophantineSolutionSet now makes solution tuples canonical wrt sign (#25830 by @smichr)

    • linear_eq_to_matrix now raises TypeError when passing unordered symbols (#25814 by @haileyHaii and @smichr)

    • solution no longer dropped for equations involving x**a = x**b when a and b have term or factor in common (#25803 by @smichr)

    • reduce_inequalities bug fixed so inequalities with non-Rational numbers are handled correctly (#25766 by @smichr)

    • solve_univariate_inequality is less likely to get hung up on expressions because of inability to verify a solution (#25758 by @smichr)

    • improve recognition of sytems involving algebraic trigonometric relationships so algebraic solutions are returned (#25686 by @smichr)

    • fewer periodic solutions are returned as solutions to equations like cos(300*x) - cos(600*x) (#25686 by @smichr)

    • when an expression in Piecewise is 0, solve will attempt to simplify it away before raising an error (#25570 by @smichr)

    • linear_programming function added. (#21687 by @orielmalihi and @smichr)

    • simplex module added with public functions lpmin, lpmax and linprog for dealing with linear optimization (#25440 by @orielmalihi, @smichr, and @TiloRC)

    • Fix a recursion error when solving some modular equations. (#24999 by @asmeurer)
  • stats

    • The compute_density function adheres to the Abel-Ruffini theorem, raising a ValueError. (#26095 by @hacquees)
    • Corrected minor errors in error messages of hypergeometric (#25823 by @PabloRuizCuevas)

    • Adds the Davis distribution to the pre-built continuous random variables, incuding documentation and tests. (#24976 by @jremes-foss)

    • The (internal) for_rewrite flag has been renamed to evaluate. (#25000 by @asmeurer)
  • tensor

    • Fixed wrong results of IndexedBase with assumptions commutative=False and commutative=True multiplied together. For example, u = IndexedBase('u', commutative=False) and v = IndexedBase('v') should work as t[0]*v[0] == v[0]*t[0]. (#26192 by @shishir-11)

    • Fixed the issue that commutative=False assumption is not working with IndexedBase. For example, if t and u are IndexedBase with commutative=False, u[0]*t[0] should not simplify to u[0]*t[0]. (#26051 by @harshkasat, and @sylee957)

    • Substituting a Tensor into a Mul now produces a TensMul as expected. (#25056 by @Kishore96in)

    • fix bug in array_derivatives dispatch logic that prevented simplification of array exprs. (#24854 by @Skylion007)

  • utilities

    • Fix bug that caused lambdify to crash on empty tuples. (#26125 by @mohakmalviya)

    • return values are now unique for signed_permutations when elements are identical in passed arg (#25966 by @smichr)

    • DEPRECATION: The sympy.utilities.pkgdata module is deprecated and will be removed. This module was never really useful and is no longer used in SymPy itself. The stdlib importlib.resources module should be used instead. (#25753 by @oscarbenjamin)

    • Fixed XXE security vulnerability for mathml parsers mathml.apply_xsl, mathml.c2p. (#25007 by @sylee957)
  • other

Authors

⚠️ **GitHub.com Fallback** ⚠️