Release Notes for 1.5 - sympy/sympy GitHub Wiki

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

SymPy 1.5 was released on 13th December 2019.

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

Important: SymPy 1.5 will be the last version of SymPy to support Python 2 (with the exception of a possible 1.5.1 release if it is required). Python 2 itself is no longer supported by the core Python developers as of January 1, 2020. If you are still using Python 2, we recommend switching to Python 3. See our Python version support policy.

Install SymPy with

pip install -U sympy

or if you use Anaconda

conda install sympy

Highlights

There are many changes in 1.5 (see below). Some of the highlights are

Please feel free to manually add any major changes for this release here, in addition to the automatic change listed below.

Backwards compatibility breaks and deprecations

Please manually add any backwards compatibility breaks or deprecations here, in addition to the automatic listing below.

  • Deprecate is_EmptySet in favor of is_empty #16946.

  • Lambda now requires a tuple rather than a list for the signature argument (non-tuple iterables are deprecated) (#17474 by @oscarbenjamin)

  • Eq(expr) now raises ValueError. Eq(expr, 0) should be used instead. (#16567 by @FrackeR011)

  • Refactory of the units module. Scale factors and dimensions are now both global and relative to single unit systems. (#17766 by @Upabjojr)

  • get_dixon_matrix() now computes only the necessary monomials for the Dixon matrix. (#17749 by @ctsiagkalis)

  • The ProductSet of no sets is no longer the empty set. Instead is the set consisting of the empty tuple. (#17557 by @oscarbenjamin)

  • Deprecated tensorhead() and tensorsymmetry() static methods. (#17124 by @drybalka)

  • Rational, irrational, transcendental and algebraic now imply finite in the assumptions system. This means that all symbols declared as rational, integer, odd etc are now automatically assumed finite. (#16597 by @oscarbenjamin)

  • In the (old) assumptions, complex=True now implies finite=True. Note that the default assumption for Symbol is complex=None, which allows for the possibility for it to be infinite. (#17699 by @oscarbenjamin and @ShubhamKJha)

  • The assumptions system is changed so that only finite numbers can be considered real, positive, negative, nonnegative, nonpositive or nonzero (since nonzero implies real). This means that any symbol declared with e.g. real=True is now automatically considered finite. It also means that infinities can not be considered positive or negative since they are not real (e.g. oo.is_positive is now False). (#16666 by @oscarbenjamin and @smichr)

  • New assumptions extended_real, extended_positive etc are added that allow for positive and negative infinity. The equivalent of Symbol('x', real=True) in version 1.4 is now Symbol('x', extended_real=True). The equivalent of Symbol('x', negative=False) is now Symbol('x', extended_negative=False) although it is usually better to use Symbol('x', nonnegative=True) (which implies both real=True and finite=True as well). Code that previously checked if x.is_positive should now be written as if x.is_extended_positive if it is intended that infinities should be allowed. (#16666 by @oscarbenjamin and @smichr)

  • Numbers still compare the same as they do in Python (Float(1) == 1) except when they appear in an Expression, e.g. x**2.0 != x**2 (#16924 by @smichr)

Changes

  • abc

    • document the _clash variables in the sympy.abc docstring (#17548 by @asmeurer)
  • algebras

    • Corrected documentation for Quaternion.rotate_point(). (#17691 by @supreet11agrawal)

    • Implement division for quaternions and more flexible operations with other expressions. (#17554 by @maxencemayrand)

    • Fix a bug where multiplication of a complex number by a quaternion is performed in the wrong order. (#17551 by @maxencemayrand)

  • assumptions

    • refine supports sign function. (#17696 by @kmm555 and @sylee957)

    • Fixed refine(re(x), Q.imaginary(x)) giving python zero instead of sympy zero. (#17700 by @sylee957)

    • Fixed refine(im(x), Q.real(x)) giving python zero instead of sympy zero. (#17700 by @sylee957)

    • Improved the code in sathandlers to speed up satask. (#17379 by @ShubhamKJha)

    • Queries for properties of matrices have been fixed, like. Q.hermitian, etc. (#17336 by @czgdp1807)

    • Performance of ask and satask is now improved. (#17144 by @rlamy and @ShubhamKJha)

    • Implemented new cnf.py to handle logical computations using low-level Python built-ins. (#17144 by @rlamy and @ShubhamKJha)

    • add refine_re() , refine_im() (#17019 by @vighneshq)

    • Rational, irrational, transcendental and algebraic now imply finite in the assumptions system. This means that all symbols declared as rational, integer, odd etc are now automatically assumed finite. (#16597 by @oscarbenjamin)

    • Matrix diagonal assumption now matches the identity matrix and diagonalized vectors. (#16586 by @Upabjojr)

  • calculus

    • Improved finite difference approximation for non-equidistant discretization steps. (#17248 by @vezeli)

    • Added a function stationary_points to find stationary points of an expression in a given domain (#16473 by @supreet11agrawal)

    • Added functions minimum and maximum to find minimum and maximum values of an expression in a given domain (#16473 by @supreet11agrawal)

  • codegen

    • Fortran code generation now supports complex variables by default (COMPLEX*16) (#15885 by @oscargus)

    • create_expand_pow_optimization is now more robust (#16654 by @bjodah and @smichr)

    • some fixes useful for future usages of matrix derivatives. (#16586 by @Upabjojr)

    • support for recognizing diagonalized vectors. (#16549 by @Upabjojr)

  • combinatorics

    • Defined Eq for Permutation of same degree. (#17793 by @sylee957)

    • Fixed PermutationGroup.is_cyclic giving wrong result for the cyclic groups created with explicitly specified generators. (#17781 by @sylee957)

    • PermutationGroup.is_cyclic automatically updates the cache for is_abelian. (#17781 by @sylee957)

    • Improved the algorithm of PermutationGroup.is_cyclic to detect some trivial cases like the group order of 15, 35, etc. (#17781 by @sylee957)

    • Added a new predicate is_symmetric to test out if a permutation group is a symmetric group. (#17677 by @sylee957)

    • Added a new predicate is_alternating to test out if a permutation group is a alternating group. (#17677 by @sylee957)

    • Fixed PermutationGroup.is_primitive() giving an error for a group that is not transitive, instead of giving False. (#17680 by @sylee957)

    • Permutation will be an instance of Atom instead of Basic. (#17340 by @sylee957)

    • Fixed Permutation raising error when used as an element of FiniteSet. (#17340 by @sylee957)

    • Fixed Partition raising error when sets or FiniteSets are given as arguments. (#16887 by @smichr and @sylee957)
  • concrete

    • Fixed Sum casting dense matrix into sparse matrix. (#17241 by @sylee957)

    • Sum will cast mutable matrices into immutable variant after computation (#17241 by @sylee957)

  • core

    • In the (old) assumptions, complex=True now implies finite=True. Note that the default assumption for Symbol is complex=None, which allows for the possibility for it to be infinite. (#17699 by @oscarbenjamin and @ShubhamKJha)
    • Some bugs when running without the cache have been fixed. (#17704 by @oscarbenjamin)

    • test_var is using exec instead of calling var directly (#17705 by @sachin-4099)

    • sympy.core.function.nfloat() now handles ExprCondPair expressions, Boolean expressions and expressions that are subclasses of MatrixBase. (#17706 by @molysgaard and @sylee957)

    • Fix get_integer_part for the case expr=S(0), return_ints=True (should return 0,0 instead of None, None, None, None) (#17682 by @theHamsta)

    • Fixed Mod(Pow(a, b, evaluate=False), c) returning non-sympified integer output if a, b, c are numeric integers. (#17637 by @sylee957)

    • Extended modular exponentiation computation for nested integer powers, so it can efficiently compute the modulus of a tetration. (#17637 by @sylee957)

    • removed match bug (#17582 by @RituRajSingh878)

    • Fixed Eq.canonical and Ne.canonical giving error when there are sets. (#17574 by @sylee957)

    • Fixes TypeError: _xreplace error while differentiating function of function (#17503 by @sachin-4099)

    • Improved simplification of relations (#15905 by @oscargus)

    • is_constant (correctly) returns None for cases where it earlier (incorrectly) returned True. (#17448 by @oscargus)

    • Fixed issue when doing xreplace on an expression with Range. (#17259 by @oscargus)

    • improvements to non-commutative matching (#17223 by @anpandey)

    • More cases of relations with frac, ceiling, and floor leads to automatic evaluation. (#17271 by @oscargus)

    • frac(zoo) no longer leads to an error. (#17271 by @oscargus)

    • recusion error involving as_real_imag was removed (#17253 by @smichr)

    • negation of expressions has been optimized (#17253 by @smichr)

    • extract_multiplicatively returns a canonical expression (#17253 by @smichr)

    • powers with a base that is an Add that contains any Float coefficients are automatically factored to make the largest coefficient 1. (#16762 by @smichr)
    • sympify will now convert all dict-types input to Dict (#16963 by @smichr)

    • N now uses rational=True which gives the desired precision when evaluating string expressions, treating floats as exact (#16963 by @smichr)

    • numbers still compare the same as they do in Python (Float(1) == 1) except when they appear in an Expression, e.g. x**2.0 != x**2 (#16924 by @smichr)

    • bugfix to disambiguate was made (#16924 by @smichr)

    • The assumptions system is changed so that only finite numbers can be considered real, positive, negative, nonnegative, nonpositive or nonzero (since nonzero implies real). This means that any symbol declared with e.g. real=True is now automatically considered finite. It also means that infinities can not be considered positive or negative since they are not real (e.g. oo.is_positive is now False). (#16666 by @oscarbenjamin and @smichr)

    • New assumptions extended_real, extended_positive etc are added that allow for positive and negative infinity. The equivalent of Symbol('x', real=True) in version 1.4 is now Symbol('x', extended_real=True). The equivalent of Symbol('x', negative=False) is now Symbol('x', extended_negative=False) although it is usually better to use Symbol('x', nonnegative=True) (which implies both real=True and finite=True as well). Code that previously checked if x.is_positive should now be written as if x.is_extended_positive if it is intended that infinities should be allowed. (#16666 by @oscarbenjamin and @smichr)

    • A number of corner cases in assumptions (e.g. for Pow.is_zero, Mul.is_positive etc) have been fixed to properly take account of the possibility of infinities. (#16666 by @oscarbenjamin and @smichr)

    • Mul._combine_inverse acts when either lhs or rhs are a Mul or Pow and will keep any I from combining with powers of -1 (#16891 by @ritesh99rakesh and @smichr)

    • (-oo).as_powers_dict now returns {-1:1, oo:1} (#16891 by @ritesh99rakesh and @smichr)

    • Mod(a, b).rewrite(floor) is now defined to give a - b*floor(a/b) (#16864 by @smichr)

    • comparison of Rational and Floats is more accurate (#16770 by @smichr)

    • subs involving Float exponents will now retain the float as in (x**(4.*y)).subs(x**(2.0*y), z) -> z**2.0 instead of z**2. (#16770 by @smichr)

    • equals corrected to not make decisions based on numbers that evaluate without precision; self consistency based on solving for surds and an attempt to find minpoly are now attempted for all numberical expressions (#16770 by @smichr)

    • Number can be used to instantiate oo and nan from strings (#16770 by @smichr)

    • more stringent checks on the use of underscores in numbers passed as strings to Float are now made (#16770 by @smichr)

    • checks for malformed mpf values passed to Float are now made (#16770 by @smichr)

    • 1/S(0) now returns zoo (#16770 by @smichr)

    • numbers: Integer//d corrected for case when d is not an integer (#16840 by @smichr)

    • divmod(a, b) behavior matches Python's when arguments involve oo or nan (#16840 by @smichr)

    • exprtools - factor_terms now factors constants out of Integrals (#16088 by @RituRajSingh878 and @smichr)

    • Rational no longer accepts nan, oo or -oo as input (#16744 by @smichr)

    • numbers - Float(oo) now gives oo; inf can be created with float(oo), if needed (#16727 by @smichr)

    • round added to compatibility (#16608 by @smichr)

    • under Python 3, Number.round == round(Number) (#16608 by @smichr)

    • Number.round rounds to even on tie and does so in cases that Python misses, e.g. round(12.345,2) -> 12.35 in Python but 12.34 in SymPy whereas round(4.5) -> 4 in both. (#16608 by @smichr)

    • Integer input is now returned as Integer (#16608 by @smichr)

    • added new clause complex -> finite | infinite in _assume_rules in assumptions.py. (#16592 by @ShubhamKJha)
  • crypto

  • external

    • Use LooseVersion instead of StrictVersion for checking external module dependencies (#16570 by @mgeier)
  • functions

    • Lambda function signatures are generalised to allow unpacking of tuple arguments. Lambda functions have a new property signature to represent the "shape" of the arguments. The variables property is now a flattened form of the signature. (#17474 by @oscarbenjamin)

    • Lambda now requires a tuple rather than a list for the signature argument (non-tuple iterables are deprecated) (#17474 by @oscarbenjamin)

    • Fixed H0=Heaviside(0) making the function to have Heaviside(0) as a second argument. (#16612 by @Sc0rpi0n101 and @sylee957)

    • Rewriting Heaviside to sign will respect the definition of Heaviside(0). Users should manually set H0=1/2 or substitute the Heaviside(0) into a definition to yield previous result. (#16612 by @Sc0rpi0n101 and @sylee957)

    • Rewriting sign to Heaviside will automatically set H0=1/2 for Heaviside (#16612 by @Sc0rpi0n101 and @sylee957)

    • Added Marcum Q-function. (#17078 by @ethankward)

    • atanh(tanh(x)), acosh(cosh(x)) and asinh(sinh(x)) are automatically evaluated (#17429 by @ethankward)

    • floor and ceiling can be evaluated automatically as positive or negative (#17313 by @ethankward)

    • Inequalities with floor and ceiling and integers are automatically simplified (#17313 by @ethankward)

    • Added series expansion for LambertW. (#17390 by @oscargus)

    • Piecewise with identical conditions bug fixed. (#17432 by @oscargus)

    • Added range assumption for the indices of KroneckerDelta. (#17433 by @Upabjojr)

    • exp and log now expand Product and Sum objects. (#17412 by @Upabjojr)

    • beta can be rewritten as gamma. (#17394 by @oscargus)

    • Negative index Laguerre, Legrande, and Chebyshev U polynomials are handled better. (#17010 by @oscargus)

    • Abs will now separate numeric numerator or denominator in a fraction so Abs(2/x) -> 2/Abs(x) (#17307 by @oscargus and @smichr)

    • Added automatic evaluation for log(exp()). (#17301 by @gschintgen)

    • log() now recognizes algebraic values having a complex argument of I*n*pi/3, I*n*pi/4, I*n*pi/5, I*n*pi/6, I*n*pi/8, I*n*pi/10 or I*n*pi/12 (#17201 by @gschintgen and @smichr)

    • KroneckerDelta can be rewritten as Piecewise. (#17215 by @ethankward)

    • Piecewise can be rewritten as KroneckerDelta (#17215 by @ethankward)

    • exp() now reduces its argument mod 2*pi*I. (#17251 by @gschintgen)

    • Improve presentation of some tan, cot values for n * pi/5, n * pi/8, n * pi/10. (#17196 by @gschintgen)

    • Make asec, acsc recognize exact values resulting in a rational multiple of pi. (#17196 by @gschintgen)

    • Make asin, acos, atan, acot recognize some additional exact values. (#17196 by @gschintgen)

    • RisingFactorial(x, k) where k is a noninteger, x is a negative integer automatically evaluates to 0. (#17173 by @ethankward)

    • Changed Piecewise.doit() to avoid recursively evaluating itself. (#17188 by @Pristine-Cat and @smichr)

    • acos with purely imaginary input is automatically rewritten to asin. (#17154 by @oscargus)

    • Added multigamma function in sympy/functions/special/gamma_functions.py (#16843 by @ritesh99rakesh)

    • log bug fixed which generated zoo when a Rational arg contained a power of the Integer base (#17150 by @smichr and @sympy)

  • geometry

    • added methods in the polygon class to calculate section modulus, polar second moment of area and first moment of area of a two-dimensional polygon (#17153 by @ishanaj)

    • added methods in the ellipse class to calculate section modulus and polar second moment of area of a two-dimensional ellipse (#17153 by @ishanaj)

    • Added a method cut_section() for the Polygon class which returns a segment of the polygon that lies above the given intersecting line. (#17001 by @ishanaj)

    • ellipse.is_tangent is more careful about deciding if a line that intersects at two points is not tangent -- it is possible to calculate an intersection as two point that are symbolically different but actually represent the same point in which case the line is tangent (#16770 by @smichr)

    • Point.affine_rank now uses an iszerofunc that assumes numbers less than 1e-12 are zero during rank calculation. (#16770 by @smichr)

    • Added Director Circle Feature For Ellipse (#16560 by @iamrajiv)

    • improved response time of 2D Line/Segement interactions and Segment containment of Point (#16668 by @smichr)
  • integrals

    • Added some documentation on the integration internals to the integration documentation in Sphinx. (#17698 by @asmeurer)

    • Added an improvement to gather more information to enhance debugging functionality of the integration module. (#17670 by @kenluck2001)

    • Refactory of RUBI in order to allow generating a decision tree. (#17614 by @Upabjojr)

    • Fixed integrate bug which raised an error instead of returning an unevaluated Integral (#17489 by @sachin-4099)

    • Integrals with abs, conjugate, re, im, DiracDelta, or sign will not use the heurisch step by default. (#17272 by @oscargus)

    • added rules in manualintegrate to cover all cases of rational functions with quadratic denominator (#17359 by @miguelmarco)

    • Integration with complex constants works better in some cases. (#17045 by @oscargus)

    • assumptions based upon definite integration limits are automatically applied to integration variables (#17093 by @smichr)
  • interactive

    • Guess the best foreground color for LaTeX rendering if None (new default) is given in init_printing. (#17244 by @oscargus)

    • init_printing(use_latex='svg') renders an svg which can be useful for some shells. (#17290 by @oscargus)

    • The LaTeX output can be scaled by using scale in init_printing. (#17277 by @oscargus)

  • logic

    • bool_map detects different between Xor(*a) and ~Xor(*a) when len(a) > 2 (#17176 by @smichr and @sympy)
  • matrices

    • fix the problem that Matrix.elementary_row_op() could judge whether col/row is within the valid range wrongly. (#17831 by @Hou-Rui)
    • Fixed Matrix.gauss_jordan_solve raising ShapeError for immutable matrices. (#17769 by @sylee957)

    • Fixed Add(ZeroMatrix(2, 2), ZeroMatrix(2, 2)) or other similar expressions giving S.Zero instead of ZeroMatrix. (#17630 by @sylee957)

    • Fixed Matrix.orthogonalize and Matrix.QRdecomposition giving wrong result for complex vectors because of using dot without conjugation. (#17589 by @sylee957)

    • more fixes to matrix derivatives and related modules. (#17583 by @Upabjojr)
    • HadamardProduct.as_explicit now supports matrix to matrix power. (#16508 by @sylee957)

    • Added missing doc for HadamardProduct and HadamardPower. (#16508 by @sylee957)

    • Make it clear in the FunctionMatrix docstring that it works with symbolic shapes (#17468 by @asmeurer)

    • ZeroMatrix, OneMatrix, Identity, DFT, FuncMatrix will give ValueError when invalid dimensions (non-integers or negative or non-real) are given. (#17314 by @sylee957)

    • FuncMatrix will only accept SymPy Lambda or a string form of python lambda (#17314 by @sylee957)

    • Added Matrix.log for computing matrix logarithm. (#17221 by @sylee957)

    • Fixed a missing import when calculating smith normal form. (#17436 by @isuruf)

    • Fixing problems related to derivation of matrix expressions by scalars. (#17413 by @Upabjojr)

    • Fixing bug preventing the simplification of ElementwiseApplyFunc. (#17417 by @Upabjojr)

    • added tests for current matmul failure and inoptimal cases (#17353 by @Pristine-Cat)

    • Fixed SparseMatrix.diagonal_solve only solving the first column of the RHS matrix. (#17254 by @sylee957)

    • Fixed SparseMatrix.upper_triangular_solve and SparseMatrix.lower_triangular_solve only solving the first column of the RHS matrix. (#17254 by @sylee957)

    • Fixed SparseMatrix.upper_triangular_solve and SparseMatrix.lower_triangular_solve not working if RHS is an immutable matrix. (#17254 by @sylee957)

    • Transposing BlockDiagMatrix will return BlockDiagMatrix instead of BlockMatrix (#17297 by @sylee957)

    • Fixed block_collapse casting BlockDiagMatrix to BlockMatrix unnecessarily when matrix-scalar multiplication is distributed, inside an Inverse or Transpose (#17297 by @sylee957)

    • Fixed block_collapse giving AttributeError with sparse matrices. (#17296 by @sylee957)

    • Fixed symbolic DotProduct multiplied with matrices giving error. (#17275 by @sylee957)

    • DotProduct is properly considered a scalar. (#17275 by @sylee957)

    • Fixed MatrixArithmetic.pow() to handle neg/num cases correctly. (#17206 by @Pristine-Cat)

    • Added usage of _matrix_pow_by_jordan_blocks() in MatPow.doit() where aplicable. (#17179 by @Pristine-Cat)

    • Added properties is_positive_definite, is_positive_semidefinite, is_negative_definite, is_negative_semidefinite, is_indefinite for testing out definitiveness of matrix (#16819 by @sylee957)

    • Mutable attributes zero and one added to replace hardcoded S.Zero and S.One (#16898 by @jksuom)

    • Matrix.pinv will use rank decomposition by default. (#16305 by @smichr and @sylee957)

    • Added method option for Matrix.pinv (#16305 by @smichr and @sylee957)

    • MatAdd and MatMul will use GenericZeroMatrix and GenericIdentity for identity (#16853 by @sylee957)

    • Fix AttributeError raised while Transpose is applied for matrix-scalar multiplication containing symbolic scalar. (#16812 by @sylee957)

    • Improved canonicalization for HadamardProduct (#16685 by @sylee957 and @Upabjojr)

    • Deleted rules from matrices.expressions.hadamard (#16685 by @sylee957 and @Upabjojr)

    • Allow matrix expressions to be derived by a scalar. (#16693 by @Upabjojr)

    • remove duplicated test. (#16683 by @Upabjojr)

    • Added LaTeX and Pretty printers for elementwise function applications. (#16675 by @sylee957 and @Upabjojr)

    • Introduction of OneMatrix, a matrix symbol representing matrices of only 1 entries. (#16676 by @Upabjojr)

    • Add support for derivatives of Hadamard products and powers. (#16673 by @Upabjojr)

    • added support for derivative of matrix scalar raised to non-integer powers. (#16659 by @Sc0rpi0n101 and @Upabjojr)

    • Matrix expressions expressed as summations will now have differently named dummy variables. (#16647 by @Upabjojr)

    • use objects in sympy/codegen/array_utils.py for matrix expression derivatives. (#16630 by @Upabjojr)

    • banded added to sparsetools.py as a helper to create a banded matrices (#16452 by @smichr)

    • matrices comprised of blocks that are not size-symmetry are detected in BlockMatrix and can be handled with Matrix (#16462 by @smichr)

    • Matrix creation involving matrices expands the matrices unless evaluate is False (#16462 by @smichr)

    • improvements to matrix derivatives, some refactory of the matrix derivative algorithm. (#16544 by @Upabjojr)
    • Derivatives of elementwise function applications on matrices are now supported. (#16442 by @Upabjojr)
    • Matrix.__mod__ is now defined so ones(2) % 2 -> ones(2) (#16454 by @smichr)

    • method diagonal extracts the kth diagonal like row and col extract the kth row or column. (#16454 by @smichr)

    • added support for Hadamard (i.e. elementwise) power of matrices. (#16443 by @Upabjojr)
    • matrix creation detects singleton lists in matrices so Matrix([1, [2]]) now raises an error (#16341 by @smichr)

    • diag matrix shape defaults to square if only rows or cols is given (#16341 by @smichr)

    • diag unpacking of lists (conversion of single lists to matrices) can be controlled with keyword unpack; dense.diag defaults to True while Matrix.diag (common.diag) defaults to False; Matrix.diag(*[1, 2, 3]) == Matrix.diag([1, 2, 3], unpack=True)) (#16341 by @smichr)

    • diag accepts variable-length rows if keyword strict is set to False (#16341 by @smichr)

    • SparseMatrix will accept a list of lists with or without size specified (#16343 by @smichr)

    • SparseMatrix values in the instantiation dictionary can now be matrices (or lists that are interpreted like matrices but do not need to contain row x col elements, i.e. a list of ragged lists is acceptable) (#16343 by @smichr)

    • fixing bug when deriving a single vector. (#16401 by @Upabjojr)

    • fixing bug with derivative in case of scalar multiplying trace. (#16397 by @Upabjojr)

    • additions to derivatives of expressions to handle the derivative of the trace of a matrix. (#15723 by @Upabjojr)

  • ntheory

    • Fixed a bug in factorint() causing wrong answers for certain integers. (#17720 by @PengningChao)
    • clarify perfect_power behavior in docstring and make it strict when candidates are given: return False if exponent of power not in candidates (#17095 by @smichr)

    • continued_fraction now imports as a function instead of a module; the new function is a high-level interface to continued_fraction_periodic that allows the input of valid expressions like (2 - 3*sqrt(5))/7 -> [-1, 3, [18, 2, 1, 1, 4, 10, 4, 1, 1, 2]] (#16923 by @smichr)

    • continued_fraction_periodic no longer returns continued fractions with more than negative number (#16923 by @smichr)

  • parsing

    • Fixed parse_expr not correctly parsing numeric strings to numbers if split_symbols is configured in transformations (#16632 by @smichr and @sylee957)

    • more user-friendly errors are raised when bad input is given to parse_expr (#16632 by @smichr and @sylee957)

    • split_symbols transformation will recognize multi-digit integers (#16632 by @smichr and @sylee957)

  • physics.continuum_mechanics

    • a new method draw() has been added in the beam module which gives functionality to draw the beam diagrams using matplotlib (#17345 by @ishanaj)

    • Beam class now accepts Geometry object representing the shape of the cross-section (#17055 by @ishanaj)

    • plot_loading_results() now uses sympy's PlotGrid class to obtain subplots related to the beam. (#16636 by @ishanaj)
  • physics.mechanics

  • physics.optics

    • added module polarization. (#17818 by @oscarlazoarjona)

    • modified two functions in physics.optics.utils, namely: refraction_angle() and deviation() so they now also accept an angle of incidence. This is useful if the user wants to work the angles instead of inputting ray-like objects. (#16512 by @Trave11er)

  • physics.quantum

  • physics.secondquant

    • Added FockStateFermionBra and FockStateFermionKet to sympy.physics.secondquant.__all__. (#17698 by @asmeurer)

    • Fixed bug in NO.get_subNO. (#17475 by @oscargus)

  • physics.units

    • Added Gaussian CGS units to the Units module. (#17842 by @Upabjojr)

    • Refactory of the units module. Scale factors and dimensions are now both global and relative to single unit systems. (#17766 by @Upabjojr)

    • Updated the values of physical constants (such as Planck's constant) to reflect the current 2018 CODATA values. (#17273 by @CameronKing)

    • More physical constant are derived from their fundamental definitions. (#17273 by @CameronKing)

  • physics.vector

  • physics.wigner

  • plotting

    • Fixed plot_implicit for composite boolean regions like (y > 2) & (y > x) (#17711 by @sylee957)

    • textplot correctly handles the singularities and imaginary values encountered in plot (#17727 by @sylee957)

    • Fixed misaligned x-axes labeling in textplot (#17727 by @sylee957)

    • functionalities of adding markers, annotations, rectangles, filling color in a plot have been added to the matplotlib backend of the plotting module (#17345 by @ishanaj)

    • Plotting of Piecewise with Eq or Ne works. (#17460 by @oscargus)

    • Plots with fractional exponents and negative base values works again. (#17409 by @oscargus)

    • Fixed ValueError raising when using Plot.show() with Matplotlib backend. (#17352 by @oscargus)

    • Fixed error for plot, plot3d, plot_parametric, plot3d_parametric_line, plot3d_parametric_surface when showing empty plot using Matplotlib backend. (#17352 by @oscargus)

    • Fixed issue with x-axis log scale range. (#16796 by @oscargus)

    • plotting module can now create subplots i.e can plot more than one plot in a single figure using PlotGrid (#16276 by @ishanaj)
  • polys

    • get_dixon_matrix() now computes only the necessary monomials for the Dixon matrix. (#17749 by @ctsiagkalis)

    • Poly(domain='RR[x, y]') now works (#14396 by @3nr1c)

    • The zero roots are added after non-trivial roots have been translated (#17200 by @aaditkamat)

    • itermonomials is now a generator. (#16561 by @ctsiagkalis)

    • itermonomials now accepts (besides the list of variables) either a list of degrees (one degree for each variable) or an integer (same degree for all the variables) for either the min_degrees and max_degrees parameters. min_degrees can also be omitted, in which case it corresponds to a 0 (single int) or a list of 0's. (#16561 by @ctsiagkalis)

    • corrects itermonomials by replacing max with sum (#16657 by @czgdp1807)

    • Remove leading term created by rounding error in long division (#16596 by @jksuom)

    • Define is_Exact and get_exact methods for FractionField (#16596 by @jksuom)

  • printing

    • Added constants S.Exp1, S.GoldenRatio, S.EulerGamma, S.Catalan, S.Nan, S.Infinity and S.NegativeInfinity for mpmath printer. (#17815 by @sylee957)

    • Added constants S.Exp1, S.Pi, S.EulerGamma, S.Nan, S.Infinity and S.NegativeInfinity for numpy printer. (#17815 by @sylee957)

    • Added constants S.GoldenRatio, S.Pi for scipy printer. (#17815 by @sylee957)

    • Fixed scipy printer printing the wrong constant for S.Exp1. (#17815 by @sylee957)

    • Added tensorflow_version option for tensorflow code printers. (#17103 by @czgdp1807 and @sylee957)

    • Fixed lambdify for tensorflow version >= 2. (#17103 by @czgdp1807 and @sylee957)

    • Added symbol for printing ProductSet. (#17561 by @sylee957)

    • Fixed parenthesis for set operators Union, Intersection, SymmetricDifference, Complement, and ProductSet for mathml presentation printer. (#17561 by @sylee957)

    • Fixed missing parenthesis for set operators Union, Intersection, Complement, SymmetricDifference, ProductSet (#17538 by @sylee957)

    • Setting allow_unknown_functions=True will not attempt to print in the unsupported form if the rewriting scheme exists. (#17501 by @sylee957)

    • Fixed pycode(beta(x, y), allow_unknown_functions=True) printing unsupported function in python math module even if the rewriting scheme exists. (#17501 by @sylee957)

    • str now gives more copy-paste-friendly code. (#17295 by @oscargus and @Upabjojr)

    • Pretty printing of HadamardPower. (#17295 by @oscargus and @Upabjojr)

    • Printer for ElementwiseApplyFunc now uses circle before parenthesis (#17416 by @Upabjojr)

    • Add parenthesis before circ in LaTeX printer for Hadamard powers when the precedence of the exponent is lower than the precedence of multiplication. (#17423 by @Upabjojr)

    • Added SciPy lambdify support for fresnelc, fresnels, lowergamma and uppergamma. (#17394 by @oscargus)

    • Added Python code generation support for beta (with automatic rewrite to gamma if required). (#17394 by @oscargus)

    • Fixed LaTeX printer not printing the second argument of LambertW. (#17398 by @sylee957)

    • Fixed Mathematica printer giving error when printing LambertW with 2 arguments. (#17398 by @sylee957)

    • Pretty printing of Sum and Product no longer depends on variable assumptions. (#17386 by @oscargus)
    • Added flag assumptions to control verbosity for print_tree (#17361 by @sylee957)
    • Mathematica code printer will put an additional parenthesis to the printed result of TribonacciConstant to fix the precedence control. (#17291 by @sylee957)
    • Added LaTeX printing for frac. (#17271 by @oscargus)

    • Fixed LaTeX printing of Derivativewhen the derivation variable has a superscript. (#17288 by @oscargus)

    • Added LaTeX, pretty and MathML presentation printing of stieltjes and Mathieu functions. (#17074 by @oscargus)

    • Improved printing of integer polynomials (bell(n, x) etc) for pretty and MathML presentation printers. (#17074 by @oscargus)

    • Added MathML presentation printing of euler. (#17074 by @oscargus)

    • NumPy printer now handles identity matrices (#17022 by @anpandey)

    • Added support for a number of functions and constants to the MathML content printer. (#17194 by @oscargus)

    • erf2 and Li are printed using erfand li, respectively, if the latter is supported, but not the former for all code printers. (#17080 by @oscargus)

    • Better LambertW printing for LaTeX, pretty, and MathML presentation. (#17080 by @oscargus)

    • Mathematica printing for many special functions added. (#17080 by @oscargus)

    • Some functions added to Octave printer. (#17080 by @oscargus)

    • Some functions added to pretty printer. (#17080 by @oscargus)

    • New option decimal_separator added to LaTeX printer which applies to floats and also affects lists, tuples, and sets. (#16711 by @rimibis and @rimibiswas)

    • Added a new argument for latex in latex.py for decimal separator and list, set, and tuple element separator (#16711 by @rimibis and @rimibiswas)

    • print_float in latex.py now has a check to determine what type of decimal separator to print out (#16711 by @rimibis and @rimibiswas)

    • _print in printer.py now has a check to determine what type of decimal separator to print out (#16711 by @rimibis and @rimibiswas)

    • Add support for optimizations to numpy printer. (#17041 by @anpandey)

    • The numpy and octave printers print matrix expressions like A**-1*x using a solve. (#17041 by @anpandey)

    • Added an option standard for python code printers to print rational numbers or print statement with python2 semantics. (May be removed after dropping python 2 compatibility) (#16901 by @sylee957)

    • MpmathPrinter will print rational numbers like mpf(1)/mpf(2) (#16901 by @sylee957)

    • python code printer will print sqrt as math.sqrt (#16901 by @sylee957)

    • NumPyPrinter will print negative integer powers as negative floating point powers, like x**(-1.0) which had caused ValueError. And may also resolve some relevant issues in lambdify (#16901 by @sylee957)

    • Added MathML presentation printing of some constants and spaces. (#17075 by @oscargus)

    • Added MathML presentation printing of Contains and Dagger. (#17075 by @oscargus)

    • Mathematica printing of special polynomials. (#17023 by @oscargus)

    • Mathematica printing of missing trigonometric functions. (#17023 by @oscargus)

    • Corrected LaTeX printing of Bell, Bernoulli, Fibonacci, and Tribonacci polynomials. (#17012 by @oscargus)

    • fixed bug of display of parentheses in mathml (#16985 by @pekochun)

    • Mathematica printing support for numerous functions related to special integrals and factorials added. (#16921 by @oscargus)

    • Added printing of OneMatrix to latex, str, pretty, and MathML presentation printers. (#16906 by @oscargus and @smichr)

    • Added function to print out Indexed (#16766 by @kangzhiq)

    • New function multiline_latex which simplifies generating code for long expressions (#15944 by @oscargus)

    • Theano printing now supports complex variables, conjugates and constant functions (#15885 by @oscargus)

    • Added printing of UniversalSet() for LaTeX ,pretty, MathML presentation, and str printers. (#16631 by @oscargus)

    • added LaTeX printers for class OneMatrix. (#16692 by @Upabjojr)

    • Fixed alignment of expressions inside sums in pretty printer (#16503 by @anpandey)
    • Add support for HadamardProduct in mathml presentation printer. (#16483 by @sylee957)

    • pretty printing of BaseScalar and BaseVector matches the latex form with CoordSys as subscript (#16422 by @kangzhiq and @smichr)

  • series

  • sets

    • Set.powerset will return PowerSet instead of None for infinite sets. (#17775 by @sylee957)
    • ImageSet can now represent sets of nested tuples and can have base sets that are nested ProductSets without flattening. (#17593 by @oscarbenjamin)

    • The definition of ImageSet is now tightened so that in ImageSet(lamda, S1, S2, ...) the number of set arguments must match the number of arguments accepted by the lamda function. Also ImageSet no longer implicitly combines arguments into a flattened ProductSet so ImageSet(lamda, S1*S2, S3) is not equivalent to ImageSet(lamda, S1, S2, S2). This means that ImageSet is well defined in all cases including when mixing sets of tuples and ProductSet as base sets: the set ImageSet(lamda, S1, S2, ...) always means that set of lamda(x1, x2, ...) where x1 in S1, etc. (#17593 by @oscarbenjamin)

    • ImageSet now has attributes base_sets which returns a list of sets and base_pset which returns a ProductSet of the basesets. In the new tighter definition of ImageSet these are more useful than the base_set attribute. (#17593 by @oscarbenjamin)

    • Added PowerSet for representing symbolic power set. (#17581 by @sylee957)

    • Fixed table-of-contents in the set documentation. (#17581 by @sylee957)

    • Added missing documentation about SymmetricDifference, ConditionSet. (#17581 by @sylee957)

    • Implemented iteration methods for Complement, SymmetricDifference. (#17584 by @sylee957)

    • Fixed is_iterable for Complement and SymmetricDifference to give True if the predicate can easily be determined. (#17584 by @sylee957)

    • ProductSet no longer automatically flattens its arguments but provides a flatten() method instead. This also means that the Cartesian product of sets is not associative. (#17557 by @oscarbenjamin)

    • The ProductSet of no sets is no longer the empty set. Instead is the set consisting of the empty tuple. (#17557 by @oscarbenjamin)

    • Passing an iterable argument to ProductSet is now deprecated. An iterable should be unpacked when passed to ProductSet. (#17557 by @oscarbenjamin)

    • Fixed printing of unary ProductSets (#17557 by @oscarbenjamin)

    • ProductSet.as_relational always returns relationals (#17557 by @oscarbenjamin)

    • Equalities involving Tuples can now evaluate and some bugs for equalities involving FiniteSets are fixed. (#17557 by @oscarbenjamin)

    • Fixed as_relational giving error for Complement and SymmetricDifference (#17572 by @sylee957)
    • Improved handling of intersections involving FiniteSets. Evaluation will only occur when it is generally valid and the result will always return as an Intersection when not fully evaluated. (#17526 by @oscarbenjamin)

    • Set.is_subset now returns True, False or None (previously an Intersection was returned instead of None). (#17526 by @oscarbenjamin)

    • FiniteSet._eval_Eq is fixed so that it doesn't evaluate when not possible due to arbitrary symbols in the elements (e.g. Eq(FiniteSet(x, y), FiniteSet(x))). (#17526 by @oscarbenjamin)

    • Range accepts symbolic arguments (#17512 by @smichr)

    • an infinite step is allowed for Range (#17512 by @smichr)

    • all integers can be represented with Range(-oo, oo); for this Range, the step must be 1 (#17512 by @smichr)

    • Range(range(3)) should now be written sympify(range(3)) (#17512 by @smichr)

    • Intervals starting with oo or ending with -oo return an empty set (#17490 by @smichr and @Soniyanayak51)

    • Added is_empty which returns True, False or None and deprecated is_EmptySet. (#17491 by @gschintgen)

    • as_relational has been added to Range. (#17145 by @czgdp1807)

    • Naturals0.intersect(Range) is handled correctly now (#16995 by @smichr and @sympy)

    • processing of arguments of an intersection is more canonical (#16988 by @smichr)

    • Rationals added to fancysets (#16896 by @smichr)

    • interactions between Z, N, N0 and R is improved (#16896 by @smichr)

    • FiniteSet(1) == FiniteSet(1.0) (#16924 by @smichr)

    • containment checks improved, especially for interactions between Integer-types (#16864 by @smichr)

    • imageset simplifies to Range when possible (#16864 by @smichr)

    • imageset over integers does not introduce symbolic Mod (#16864 by @smichr)

    • fancyset Range recognizes null ranges when start or stop is infinite and step is wrong sign (#16862 by @smichr)

    • bug fix in ImageSet contains method makes it more robust for multivariate cases (#16862 by @smichr)

    • arguments of null Range(0, 0, 1) are now Integers (solves printing problem) (#16820 by @ritesh99rakesh)

    • Added documentation and examples for sympy.sets.fancysets.Reals. (#16787 by @highpost)
  • simplify

    • The result after doit() is only returned if it is smaller than before doit(). (#17259 by @oscargus)

    • The content of a Piecewise is simplified even when only parts of the expression is a Piecewise. (#17259 by @oscargus)

    • removed hyperexpand dependance on return from from matrix multiplication (#17353 by @Pristine-Cat)

    • collect_abs is added to radsimp to put mutliple Abs in a term under a single Abs (#17307 by @oscargus and @smichr)

    • separatevars will now separate args of Abs when they are separable (#17307 by @oscargus and @smichr)

    • simplify attempts to simplify expressions containing KroneckerDelta. (#17215 by @ethankward)

  • solvers

    • linear_coeffs gives no longer raises when expr has no symbols of interest (#17814 by @sachin-4099)

    • Fixes NotImplementedError for an equation containing absolute value in Python 3 (#17767 by @sachin-4099)

    • Fixes nonlinsolve bug which raised an AttributeError (#17494 by @sachin-4099)

    • equals is used less often making solution process faster in some cases (#17477 by @smichr)

    • added _solve_modular to handle equations of type a - mod(b, c) = 0 where b is expr (#16976 by @jmig5776)

    • the gcd of parameterized ternary solutions is now removed (#17348 by @smichr)

    • In checkodesol, added recurrence relation of Bessel function to reduce expression contains Bessel function. (#16707 by @RituRajSingh878)
    • solve will separate Abs(x/y) as Abs(x)/Abs(y) when solving for x if x is real so NotImplemented is no longer raised. (#17307 by @oscargus and @smichr)

    • diop_solve docstring updated to state that diophantine() method is recommended over helper functions. (#17193 by @Abhi58 and @smichr)

    • improved bivariate to return all lambert solutions (#16890 by @jmig5776)

  • stats

    • Added Exponentially modified Gaussian ExGaussian distribution to sympy/stats/crv_types.py (#17076 by @ritesh99rakesh)
    • Attributes specific to DiscreteMarkovChain have been added like, is_absorbing_chain, fixed_row_vector, etc. (#17046 by @czgdp1807)
    • joint_rv_types can now be imported with from sympy.stats import * (#16919 by @czgdp1807)
    • Generalized Multivariate Log Gamma Distribution has been added to sympy.stats.joint_rv_types (#16825 by @czgdp1807)

    • Refactored sympy.stats.frv_types and sympy.stats.frv (#16765 by @czgdp1807)

    • multivariate distributions added to sympy.stats.joint_rv_types (#16576 by @czgdp1807)

  • tensor

    • Extended .substitute_indices() method for all tensor expressions. (#17516 by @drybalka)

    • Deprecated .fun_eval() in favor of .substitute_indices(). (#17516 by @drybalka)

    • Deprecated .__call__() for all tensor expressions. (#17516 by @drybalka)

    • Added .fully_symmetric(), .no_symmetry(), .direct_product(), .riemann() methods for TensorSymmetry generation. (#17124 by @drybalka)

    • Added tensor_heads() static method. (#17124 by @drybalka)

    • Deprecated TensorType class. (#17124 by @drybalka)

    • Deprecated tensorhead() and tensorsymmetry() static methods. (#17124 by @drybalka)

    • Bugfix of __getitem__ for single item array (#17282 by @kangzhiq)

    • Modified the behavior of __getitem__ on Array to better match NumPy (#17226 by @kangzhiq)

    • Added specific cases for sparse array in permutedims and tests (#17035 by @kangzhiq)

    • Added specific case for sparse array in div, neg and tests (#17026 by @kangzhiq)

    • Added specific cases for sparse array in tensorproduct and tests (#17000 by @kangzhiq)

    • added support for inheriting assumptions from symbols to IndexedBase (#17009 by @bsamseth and @smichr)

    • Added specific case for sparse array in mul, rmul and tests (#17014 by @kangzhiq)

    • Added specific case for sparse array in derive_by_array (#16937 by @kangzhiq)

    • added support for assumptions on IndexedBase (#16085 by @bsamseth)

    • Added functions to ArrayComprehension. (#16969 by @kangzhiq)

    • Added a new array object ArrayComprehension for list comprehension. (#16845 by @kangzhiq)

    • Make the 'indices' parameter in .replace_with_arrays optional. (#16493 by @kangzhiq)

  • utilities

    • Fixed beta function error in lambdify with the option module='math' (#17501 by @sylee957)
    • Fixed a bug that would crash lambdify if expression contained E with no power. (#17315 by @johanbluecreek)
    • Using stirling method in multiset_partitions method docstring instead of old S2 manually defined method (#17191 by @Abhi58)
    • remove sympy_dir variable from sympy.utilities.runtests. Use get_sympy_dir() instead (note that this is not really public API). (#17180 by @asmeurer)
    • lambdify will properly catch up the submodules used in external module import. (#16933 by @sylee957)
  • other

    • Fix various references throughout the docs so that they link properly. (#17698 by @asmeurer)

    • Added several missing docstrings to the Sphinx documentation. (#17698 by @asmeurer)

    • The headers in docstrings for "Examples", "See Also", "References" and so on are now rendered larger in the HTML documentation. (#17675 by @asmeurer)
    • PyPy 3 is now tested and supported. (#17607 by @asmeurer and @oscarbenjamin)

    • Made [Source] from the documentation redirect to the SymPy GitHub repository instead of having a copy of the source code in the documentation files. (#17504 by @sylee957)

    • Edited all the header names of the doc file to match the name of submodule. (#17499 by @harsh9200)

    • Sorted the Index in alphabetical order. (#17499 by @harsh9200)

Authors

The following people contributed at least one patch to this release (names are given in alphabetical order by last name). A total of 132 people contributed to this release. People with a * by their names contributed a patch for the first time for this release; 68 people contributed for the first time for this release.

Thanks to everyone who contributed to this release!

  • Akash Nagaraj (akasnaga)*
  • Shubham Abhang
  • Abhi58*
  • Louis Abraham*
  • Sachin Agarwal
  • Harsh Agarwal*
  • Supreet Agrawal
  • Abhinav Anand*
  • Oscar Gerardo Lazo Arjona*
  • arooshiverma*
  • Juan Barbosa*
  • Oscar Benjamin
  • Gabriel Bernardino*
  • Parker Berry
  • Johan Blåbäck
  • Francesco Bonazzi
  • Ondřej Čertík
  • Arighna Chakrabarty
  • Pengning Chao*
  • Sean P. Cornelius*
  • Björn Dahlgren
  • Nabanita Dash
  • Anway De*
  • Gaurav Dhingra
  • Mark Dickinson*
  • dranknight09*
  • Zachariah Etienne
  • Isuru Fernando
  • Enric Florit*
  • Mauro Garavello
  • Matthias Geier
  • Sourav Ghosh
  • Lauren Glattly*
  • Christoph Gohle*
  • Erik R. Gomez*
  • Oscar Gustafsson
  • David Hagen*
  • hannah-kari*
  • Hou-Rui*
  • Hugo
  • Denis Ivanenko*
  • jgulian*
  • Shubham Kumar Jha
  • Ishan Joshi
  • Aadit Kamat*
  • kangzhiq
  • Hannah Kari*
  • Atharva Khare
  • Cameron King*
  • Shivani Kohli
  • George Korepanov*
  • Amit Kumar
  • Ritesh Kumar
  • Petr Kungurtsev*
  • Samesh Lakhotia*
  • Ronan Lamy
  • S.Y. Lee
  • Steven Lee*
  • Jun Lin*
  • luzpaz
  • Megan Ly*
  • Morten Olsen Lysgaard*
  • Nikhil Maan*
  • Colin B. Macdonald
  • Riccardo Magliocchetti*
  • Kirtan Mali*
  • Miguel Marco*
  • Maxence Mayrand
  • Pragyan Mehrotra
  • Henry Metlov*
  • Aaron Meurer
  • Jogi Miglani
  • Aaron Miller
  • Sudhanshu Mishra
  • Yogesh Mishra*
  • Jason Moore
  • Yeshwanth N*
  • Akshay Nagar
  • Akash Nagaraj*
  • Sidhant Nagpal
  • Prionti Nasir*
  • Soniya Nayak*
  • Abdullah Javed Nesar
  • Kenneth Emeka Odoh*
  • OrestisVaggelis*
  • Ankit Raj Pandey
  • pekochun*
  • Ruslan Pisarev
  • Tomasz Pytel*
  • Bharat Raghunathan*
  • Samnan Rahee
  • Shekhar Prasad Rajak
  • Rohit Rango
  • Joseph Redfern*
  • Juha Remes
  • Rimi*
  • rimibis*
  • Faisal Riyaz
  • Martin Roelfs
  • Denys Rybalka*
  • Denis Rykov*
  • Samesh*
  • Bendik Samseth*
  • Gilles Schintgen*
  • Stan Schymanski
  • Daniel Sears*
  • Stephan Seitz*
  • Vighnesh Shenoy*
  • Qingsha Shi*
  • Rajiv Ranjan Singh
  • Gagandeep Singh
  • Jashanpreet Singh
  • Ritu Raj Singh
  • Arun Singh
  • Sartaj Singh
  • Animesh Sinha
  • Gleb Siroki
  • Chris Smith
  • Ralf Stephan
  • Kalevi Suominen
  • Divyanshu Thakur
  • TitanSnow*
  • Ivan Tkachenko*
  • Charalampos Tsiagkalis*
  • Versus Void*
  • Ethan Ward
  • Jonathan Warner
  • Arun Yeragudipati*
  • Srinivasa Arun Yeragudipati*
  • Velibor Zeli*
  • Zhi-Qiang Zhou
  • znxftw*