5 The aim of the SympyCore project is to develop a robust, consistent,
6 and easy to extend Computer Algebra System model for Python.
9 - This document is written in `reStructuredText <http://docutils.sourceforge.net/rst.html>`_ format.
15 To use SympyCore from Python, one needs to import the ``sympycore`` package::
17 >>> from sympycore import *
19 The ``sympycore`` package provides ``Symbol`` and ``Number`` functions to
20 construct symbolic objects and numbers. By default, the symbolic
21 objects are the elements of ``Calculus`` algebra -- a commutative
22 ring of symbolic expressions where exponent algebra is also ``Calculus``
29 >>> x,y,z,v,w=map(Symbol,'xyzvw')
31 To construct expression from a string, use the corresponding algebra
32 class with one argument. For example,
34 >>> Calculus('x+y+1/4 + x**2')+x
35 Calculus('y + x**2 + 1/4 + 2*x')
37 More examples on ``sympycore`` features can be found in `Demo documentation`__.
45 Symbolic expressions represent mathematical concepts like numbers,
46 constants, variables, functions, operators, and various relations
47 between them. Symbolic objects, on the other hand, represent symbolic
48 expressions in a running computer program. The aim of a Computer
49 Algebra System (CAS) is to provide methods to manipulate symbolic
50 objects and by that manipulate symbolic expressions. These
51 manipulations of symbolic expressions have mathematical meaning when
52 the methods are consistent with the rules and theories from
55 There are many possible ways to represent a mathematical concept as a
56 structure of a computer program. SympyCore mimics mathematical
57 concepts via implementing the corresponding algebra and algebraic
58 operations in a class, say Algebra, that is derived from the
59 BasicAlgebra class. So, a symbolic object is an instance of the
60 Algebra class. This instance contains information about the
61 mathematical operator that when applied to operands forms the
62 corresponding symbolic object. The operator and operands of the given
63 symbolic object can be accessed via atrributes ``func`` and
64 ``args``. The value of ``func`` is a callable object and ``args`` is a
65 sequence of symbolic objects. So, if ``A`` is a ``Algebra`` instance
68 <symbolic object> = A.func(*A.args)
70 The actual value of ``func`` is defined by the ``Algebra`` class. For
71 example, in the case of calculus algebra class ``Calculus``, the
72 ``func`` value can be ``Add``, ``Mul``, ``Pow``, ``sin``, ``log``,
73 etc. If the symbolic object represents a symbol (eg a variable) or a
74 number of the algebra then ``func`` contains a callable that returns the
75 symbolic object (the ``args`` in this case will be an empty sequence).
77 The symbolic objects representing symbols and numbers can be
78 constructed via the ``Symbol`` and ``Number`` functions. Such symbolic
79 objects are called atomic. One should note that functions ``Add``,
80 ``Mul``, ``Pow``, ``Symbol``, ``Number``, etc are always specific to
81 the given algebra (in fact, they are defined as classmethods of the
82 corresponding algebra class).
84 While most of the algebra operators assume symbolic objects as their
85 operands then ``Symbol`` and ``Number`` functions may take various
86 Python objects as arguments. For example, the argument to
87 ``Calculus.Symbol`` can be any python object that is immutable (this
88 requirement comes from the fact terms of sums and factors of products
89 are internally saved as Python dictionary keys), and the arguments to
90 ``Calculus.Number`` can be Python number types such as ``int``,
91 ``long``, ``float``, ``complex`` as well as ``mpq``,
92 ``mpf``, ``mpqc`` instances (these are defined in
93 ``sympycore.arithmetic`` package).
95 One can construct symbolic objects from Python strings using algebra
96 ``convert`` class method or algebra constructor with one argument. For
99 >>> Calculus.convert('a-3/4+b**2')
100 Calculus('a + b**2 - 3/4')
101 >>> Calculus('a-3/4+b**2').func
102 <bound method type.Add of <class 'sympycore.calculus.algebra.Calculus'>>
103 >>> Calculus('a-3/4+b**2').args
104 [Calculus('a'), Calculus('-3/4'), Calculus('b**2')]
109 SympyCore project provides a python package ``sympycore`` that consists of
110 several modules and subpackages:
112 1. ``core.py`` - provides a base class ``Basic`` to all symbolic
113 objects. Note that almost any (hashable) python object can be used
114 as an operand to algebraic operations (assuming the corresponding
115 algebra class accepts it) and hence it is not always necessary to
116 derive classes defining some mathematical notion from
117 ``Basic``. Only classes that could be used by other parts of the
118 ``sympycore`` should be derived from ``Basic``. In such cases,
119 these classes are available via ``classes`` attributes (also
120 defined in ``core.py``). For example,
122 >>> from sympycore.core import classes
124 <class 'sympycore.calculus.algebra.Calculus'>
126 <class 'sympycore.physics.units.Unit'>
127 >>> classes.CollectingField
128 <class 'sympycore.basealgebra.pairs.CollectingField'>
130 #. ``arithmetic/`` - provides ``mpq``, ``mpf``, ``mpqc``,
131 ``mpc`` classes that represent low-level fractions,
132 multiprecision floating point numbers, and complex numbers with
133 rational parts. The package defines also ``Infinity`` class to
134 represent extended numbers.
136 #. ``basealgebra/`` - provides abstract base classes representing
137 algebras: ``BasicAlgebra``, ``CommutativeRing``, etc, and base
138 classes for algebras with implementations: ``Primitive``,
139 ``CollectingField``, etc.
141 #. ``calculus/`` - provides class ``Calculus`` that represents the
142 algebra of symbolic expressions. The ``Calculus`` class defines the
143 default algebra in ``sympycore``. For more information, see
144 [section on calculus]. ``calculus/functions/`` - provides symbolic
145 functions like ``exp``, ``log``, ``sin``, ``cos``, ``tan``,
146 ``cot``, ``sqrt``, ...
148 #. ``physics/`` - provides class ``Unit`` that represents the algebra
149 of symbolic expressions of physical quantities. For more
150 information, see [section on physics].
152 #. ``polynomials/`` - provides classes ``Polynomial``,
153 ``UnivariatePolynomial``, ``MultivariatePolynomial`` to represent
154 the algebras of polynomials with symbols, univariate polynomials in
155 (coefficient:exponent) form, and multivariate polynomials in
156 (coefficients:exponents) form, respectively. For more information,
157 see [section on polynomials].
163 In ``sympycore`` all symbolic objects are assumed to be immutable. So,
164 the manipulation of symbolic objects means creating new symbolic
165 objects from the parts of existing ones.
167 There are many methods that can be used to retrive information and
168 subexpressions from a symbolic object. The most generic method is to
169 use attribute pair of ``func`` and ``args`` as described
170 above. However, many such methods are also algebra specific, for
171 example, classes of commutative rings have methods like
172 ``as_Add_args``, ``as_Mul_args``, etc for retriving the operands of
173 operations and ``Add``, ``Mul``, etc for constructing new symbolic
174 objects representing addition, multiplication, etc operations. For
175 more information about such methods, see sections describing the
176 particular algebra classes.
182 ``str(<symbolic object>)``
183 return a nice string representation of the symbolic object. For example,
185 >>> expr = Calculus('-x + 2')
189 ``repr(<symbolic object>)``
190 return a string representation of the symbolic object that can be
191 used to reproduce an equal object:
193 >>> expr=Calculus('-x+2')
197 ``<symbolic object>.as_tree()``
198 return a tree string representation of the symbolic object. For example,
200 >>> expr = Calculus('-x + 2+y**3')
201 >>> print expr.as_tree()
211 where the first line shows the name of a algebra class following the
212 content of the symbolic object in tree form. Note how are
213 represented the coefficients and exponents of the example
219 ``<symbolic object>.as_verbatim()``
220 return symbolic object as an instance of ``Verbatim`` class. All
221 algebra classes must implement ``as_verbatim`` method as this allows
222 converting symbolic objects from one algebra to another that is
223 compatible with respect to algebraic operations. Also, producing the
224 string representations of symbolic objects is done via converting
225 them to Verbatim that implements the corresponding printing
229 Calculus('2 + y**3 - x')
230 >>> expr.as_verbatim()
231 Verbatim('2 + y**3 - x')
233 ``<symbolic object>.as_algebra(<algebra class>)``
234 return symbolic object as an instance of given algebra class. The
235 transformation is done by first converting the symbolic object to
236 ``Verbatim`` instance which in turn is converted to the instance
237 of targer algebra class by executing the corresponding target
238 algebra operators on operands. For example,
240 >>> expr = Calculus('-x + 2')
241 >>> print expr.as_tree()
247 >>> print expr.as_algebra(Verbatim).as_tree()
255 >>> print expr.as_algebra(CollectingField).as_tree()
262 Substitution of expressions
263 ---------------------------
265 ``<symbolic object>.subs(<sub-expr>, <new-expr>)``
266 return a copy of ``<symbolic object>`` with all occurances of
267 ``<sub-expr>`` replaced with ``<new-expr>``. For example,
269 >>> expr = Calculus('-x + 2+y**3')
271 Calculus('2 + y**3 - x')
272 >>> expr.subs('y', '2*z')
273 Calculus('2 + 8*z**3 - x')
275 ``<symbolic object>.subs([(<subexpr1>, <newexpr1>), (<subexpr2>, <newexpr2>), ...])``
276 is equivalent to ``<symbolic object>.subs(<subexp1>,
277 <newexpr1>).subs(<subexpr2>, <newexpr2>).subs``. For example,
280 Calculus('2 + y**3 - x')
281 >>> expr.subs([('y', '2*z'),('z', 2)])
287 ``<symbolic object>.match(<pattern-expr> [, <wildcard1>, <wildcard2> ...])``
288 check if the give symbolic object matches given pattern. Pattern
289 expression may contain wild symbols that match arbitrary
290 expressions, the ``wildcard`` must be then the corresponding
291 symbol. Wild symbols can be matched also conditionally, then the
292 ``<wildcard>`` argument must be a tuple ``(<wild-symbol>, <predicate>)``,
293 where ``<predicate>`` is a single-argument function returning ``True`` if
294 wild symbol matches the expression in argument. If the match is not
295 found then the method returns. Otherwise it will return a dictionary
296 object such that the following condition holds::
298 pattern.subs(expr.match(pattern, ...).items()) == expr
303 >>> pattern = v*x + w*y
304 >>> d = expr.match(pattern, v, w)
305 >>> print 'v=',d.get(v)
307 >>> print 'w=',d.get(w)
309 >>> pattern.subs(d.items())==expr
312 Checking for atomic objects
313 ---------------------------
315 A symbolic object is atomic if ``<symbolic object>.args == ()``.
317 ``<symbolic object>.symbols``
318 is a property that holds a set of all atomic symbols in the given
321 ``<symbolic object>.has(<symbol>)``
322 returns ``True`` if the symbolic expression contains ``<symbol>``.
327 Verbatim algebra elements are symbolic expressions that are not
328 simplified in anyway when performing operatons. For example,
337 In SympyCore a commutative ring is represented by an abstract class
338 ``CommutativeRing``. The ``CommutativeRing`` class defines support
339 for addition, substraction, multiplication, division, and
340 exponentiation operations.
345 Classes deriving from ``CommutativeRing`` must define a number of
346 method pairs ``(Operation, as_Operation_args)`` that satisfy the
347 following condition::
349 cls.Operation(*obj.as_Operation_args()) == obj
351 Here ``Operation`` can be ``Add``, ``Mul``, ``Terms``, ``Factors``,
352 ``Pow``, ``Log``. For example,
354 >>> print map(str, (2*x+y).as_Add_args())
356 >>> print map(str, (2*x+y).as_Mul_args())
358 >>> print map(str, (2*x+y).as_Pow_args())
360 >>> print (2*x+y).as_Terms_args()
361 [(Calculus('y'), 1), (Calculus('x'), 2)]
366 Expanding means applying distributivity law to open parenthesis.
368 ``<symbolic object>.expand()``
369 return an expanded expression. For example,
371 >>> expr = x*(y+x)**2
374 >>> print expr.expand()
375 x**3 + 2*y*x**2 + x*y**2
380 ``<symbolic object>.diff(*symbols)``
381 return a derivative of symbolic expression with respect to given
382 symbols. The diff methods argument can also be a positive integer
383 after some symbol argument. Then the derivative is computed given
384 number of times with respect to the last symbol.
387 >>> print sin(x*y).diff(x)
389 >>> print sin(x*y).diff(x).diff(y)
390 cos(x*y) - x*y*sin(x*y)
391 >>> print sin(x*y).diff(x,4)
397 ``<symbolic object>.integrate(<symbol>, integrator=None)``
398 return an antiderivative of a symbolic expression with respect to
402 >>> from sympycore import *
403 >>> print (x**2 + x*y).integrate(x)
404 1/2*y*x**2 + 1/3*x**3
406 ``<symbolic object>.integrate((<symbol>, <a>, <b>)``
407 return a defined integral of a symbolic expression with respect to
408 ``<symbol>`` over the interval ``[<a>, <b>]``.
411 >>> from sympycore import *
412 >>> print (x**2 + x*y).integrate(x)
413 1/2*y*x**2 + 1/3*x**3
414 >>> print (x**2 + x*y).integrate((x, 1, 3))
417 Commutative ring implementation
418 ===============================
420 Commutative ring operations are implemented in the class
421 ``CollectingField`` (derived from ``CommutativeRing``).
423 The class ``CollectingField`` holds two attributes, ``head``
424 and ``data``. The attribute ``head`` defines the meaning of the
425 attribute ``data`` content:
427 1. If ``<obj>.head==SYMBOL`` then ``<obj>.data`` is treated as an element
428 of the ring. Usually ``<obj>.data`` is a Python string object but
429 in general it can be any hashable Python object.
431 #. If ``<obj>.head==NUMBER`` then ``<obj>.data`` is treated as a
432 number element of the ring, that is, an element that can be
433 represented as *one \* n* where *one* is unit element of the ring
434 and *n* is a number saved in ``<obj>.data``. Usually ``<obj>.data``
435 is a Python ``int``, ``long``, ``float``, ``complex`` object but it
436 can be also any other number-like object that supports arithmetic
437 operations with Python numbers. An examples are ``mpq``,
438 ``mpf``, ``mpqc`` classes defined in ``sympycore.arithmetic``
441 #. If ``<obj>.head==TERMS`` then ``<obj>.data`` contains a Python
442 dictionary holding the pairs ``(<ring element>, <coefficient>)``.
443 The values of ``<coefficients>`` can be Python numbers or
444 number-like objects or elements of some other ring (for example,
445 see ``Unit`` class where the coefficients are ``Calculus``
446 instances). For example, if ``<obj>.data`` is ``{x:2, y:1}`` then
447 ``<obj>`` represents an expression *y + 2\*x*.
449 #. If ``<obj>.head==FACTORS`` then ``<obj>.data`` contains a Python
450 dictionary holding the pairs ``(<ring element>, <exponent>)``. The
451 values of ``<coefficients>`` can be Python numbers of number-like
452 objects or elements of some ring (for exapmle, see ``Calculus``
453 class where the exponents can also be ``Calculus`` instances).
455 #. If ``callable(<obj>.head)`` then ``<obj>`` represents an applied
456 function where ``<obj>.head`` contains a callable object that
457 performs evaluation and ``<obj>.data`` contains an argument
458 instance (for example, an instance of some algebra elements)
459 or a Python ``tuple`` containing argument instances.
461 The constants ``SYMBOL``, ``NUMBER``, ``TERMS``, ``FACTORS`` are defined
462 in ``sympycore/utils.py``.
466 >>> from sympycore.utils import head_to_string
467 >>> head_to_string[x.head]
471 >>> head_to_string[(x+y).head]
473 >>> (x+y).data == {x:1,y:1}
475 >>> head_to_string[(x**y).head]
478 {Calculus('x'): Calculus('y')}
480 <class 'sympycore.calculus.functions.elementary.sin'>
485 Defining functions for ``CollectingField``
486 ---------------------------------------------------
488 The representation of an applied function within the class
489 ``CollectingField`` can hold any Python callable object that
490 satisfies the following basic condition: it must return an instance of
491 a algebra class. The instance may represent an evaluated result of
492 applying the function to its arguments, or when evaluation is not
493 possible, then it return ``<algebra class>(<arguments>,
496 For example, let us define a customized sinus function:
501 ... return Calculus(mysin, x)
512 The default algebra of symbolic expressions with commutative ring
513 operations is represented by the ``Calculus`` class (derived from
514 ``CollectingField``). The ``Calculus`` class can handle
515 rational numbers represented by the ``mpq`` class, multi-precision
516 floating point numbers represented by the ``mpf`` class, and
517 rational complex numbers represented by the ``mpqc`` class.
519 The ``sympycore.calculus.functions`` package defines the following
520 symbolic functions: ``sqrt``, ``exp``, ``log``, ``sin``, ``cos``,
521 ``tan``, ``cot``. It also provides ``Calculus`` based interfaces to
522 constants ``E``, ``pi``, and symbols ``I``, ``oo``, ``moo``, ``zoo``,
528 The ``sympycore.arithmetic`` package is not an algebra package but it
529 implements fractions, multi-precision floating point numbers, rational
530 complex numbers, and `extended numbers`__. In addition, it implements
531 various algorithms from number theory and provides methods to compute
532 the values of constants like pi and Eulers number, etc.
534 __ evaluation_rules.html#extended-numbers
539 The ``sympycore.polynomials`` package has two different
540 implementations for polynomials: ``UnivariatePolynomial`` and
543 ``UnivariatePolynomial``
544 ------------------------
546 The ``UnivariatePolynomial`` class stores polynomial coefficients in a
547 Python tuple. The exponents are implicitly defined as indices of the
548 list so that the degree of a polynomial is equal to the length of the
549 list minus 1. ``UnivariatePolynomial`` is most efficient for
550 manipulating low order and dense polynomials. To specify the variable
551 symbol of a polynomial, use ``symbol`` keyword argument (default
552 variable symbol is ``x``).
555 4 + 3*x + 2*x**2 + x**3
556 >>> poly([4,3,2,1]).degree
558 >>> poly([4,3,2,1],symbol='y')
559 4 + 3*y + 2*y**2 + y**3
561 Coefficients can be arbitrary symbolic expressions:
563 >>> poly([2,y+1,y+z])
564 2 + ((1 + y))*x + ((y + z))*x**2
570 The ``PolynomialRing`` based classes store polynomial exponenets and
571 coefficients information in a Python dictionary object where keys are
572 exponenents (in univariate case Python integers, in multivariate case
573 ``AdditiveTuple`` instances) and values are coefficients.
574 ``PolynomialRing`` is most efficient for manipulating sparse
575 polynomials. The coefficients belong to specified ring (default ring
578 The ``PolynomialRing`` class (derived from ``CommutativeRing``) is
579 a base class to various polynomial rings with different coefficent
580 rings and different number of variables. To create a class
581 representing a polynomial element with variables ``(X, Y, ..)`` and
582 with ``<ring>`` coefficients, use one of the following constructions::
584 PolynomialRing[(X, Y, ..), <ring>]
585 PolynomialRing[<int>, <ring>]
587 where nonnegative ``<int>`` specifies the number of variables (default
588 symbols are then ``X0``, ``X1``, etc). The ``<ring>`` argument can be
589 omitted, then ``Calculus`` is used as a default ring. Variables can
590 be arbitrary symbolic expressions.
594 >>> polyXY = PolynomialRing[('X', 'Y'), Calculus]
596 <class 'sympycore.polynomials.algebra.PolynomialRing[(X, Y), Calculus]'>
598 To create a polynomial with given exponents and coefficients pairs,
599 the ``PolynomialRing`` constructor accepts dictinary objects
600 containing the corresponding pairs:
602 >>> polyXY.convert({(0,0):4, (2,1):3, (0,3):2})
603 PolynomialRing[(X, Y), Calculus]('3*X**2*Y + 2*Y**3 + 4')
605 Univariate polynomials can also be constructed from a list in the same
606 way as ``UnivariatePolynomial`` instances were constructed above:
608 >>> PolynomialRing[1].convert([4,3,2,1])
609 PolynomialRing[X0, Calculus]('X0**3 + 2*X0**2 + 3*X0 + 4')
615 The ``sympycore.matrices`` package defines ``MatrixRing`` that is base
616 class to matrix algebras. Matrix algebras are represented as classes
617 (derived from ``MatrixRing``) parametrized with matrix shape and
618 element ring (default ring is ``Calculus``). To create a matrix
619 ring, use the following constructs::
621 MatrixRing[<shape>, <ring>]
622 SquareMatrix[<size>, <ring>]
623 PermutationMatrix[<size>]
625 where ``<ring>`` can be omitted, then ``Calculus`` is used as a
626 default element ring.
630 >>> m=MatrixRing[3,4]({})
642 The content of the matrix is stored as a dictionary containing
643 pairs ``(<rowindex>,<column-index>): <non-zero element>``.
645 Matrix instances can be constructed from Python dictionary or from a
648 >>> print MatrixRing[2,2]({(0,0):1,(0,1):2,(1,1):3})
651 >>> print MatrixRing[2,2]([[1,2],[3,4]])
655 Permutation matrices can be constructed from a sequence of
658 >>> print PermutationMatrix([1,0,2])
663 Use ``random()`` classmethod to construct matrices with random
666 >>> print SquareMatrix[2].random() #doctest: +SKIP
669 >>> print SquareMatrix[2].random((10,20)) #doctest: +SKIP
674 Canonical forms and suppressed evaluation
675 =========================================
677 See also `Automatic evaluation rules of symbolic expressions`__.
679 __ evaluation_rules.html
681 The ``Calculus`` algebra automatically applies some transformations to
682 expressions. The purpose of these transformations is to permit quick
683 recognition of mathematically equivalent expressions.
684 Sums and products of numbers are always evaluated, and
685 multiples/powers of identical subexpressions are automatically
686 collected together. Rational factors are also automatically
687 distributed over sums. For example, the following transformations
688 are performed automatically::
698 An expression to which default transformations have been applied is
699 said to be in canonical or normalized form. The enforcement of
700 canonical forms is important for performance reasons as it ensures that,
701 in many important basic cases, expressions that are mathematically
702 equivalent will be recognized directly as equal no matter in what
703 form they were entered, without the need to apply additional
704 transformations. The default transformations described above
705 ensure that for example the following expressions cancel completely::
713 2*(x-y) + 2*(y-x) -> 0
715 Ideally we would like the canonical form to be the simplest
716 expression possible, e.g.::
718 cos(x)**2 + sin(x)**2 -> 1
720 Automatically generating the simplest possible form is not always
721 possible, as some expressions have multiple valid representations that
722 may each be useful in different contexts. E.g.: ``cos(2*x)`` and
723 ``cos(x)**2 - sin(x)**2``. In general, detecting whether two expressions are
724 equal is not even algorithmically decidable, and even when it is
725 possible, the required simplifications can be extremely computationally
726 expensive (and unpredictably so).
728 Default transformations are limited to performing operations cases that
729 are fast and have predictable behavior. To perform more expensive
730 simplifications, one should explicitly invoke ``simplify()`` or, depending on
731 the desired form, special-purpose rewriting functions like ``collect()``,
732 ``apart()``, etc (note: these are not yet implemented in SympyCore).
734 It can sometimes be useful to bypass automatic transformations, for
735 example to keep the expression ``2*(x+y)`` in factored form. The most
736 general way to achieve this is to use the ``Verbatim`` class
737 (which performs no simplifications whatsoever) instead of ``Calculus``.
739 >>> Verbatim('2*(x+pi)')
740 Verbatim('2*(x + pi)')
742 You can also construct non-canonical ``Calculus`` instances by manually
743 passing data to the ``Calculus`` constructor. For example:
745 >>> p = Calculus(utils.TERMS, {(pi+x):2})
749 It is important to note that some ``Calculus`` functions assume the input to
750 be in canonical form. Although they should never break (i.e. generate
751 invalid results) when given noncanonical input, they may fail to simplify
752 results. For example, ``sin`` assumes its argument to be flattened such that
753 if it contains an integer multiple of pi that can be eliminated, this term
754 will be available at the top of the expression. Thus:
756 >>> sin(2*(pi+x)) # sin(2*pi + 2*x)
759 Calculus('sin(2*(pi + x))')
761 To canonize an expression, either use the function XXX or convert it to
762 ``Verbatim`` and then back to ``Calculus``.
764 >>> Calculus(Verbatim(p))
765 Calculus('2*pi + 2*x')