1 <?xml version=
"1.0" encoding=
"utf-8" ?>
2 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml" xml:
lang=
"en" lang=
"en">
5 <meta http-equiv=
"Content-Type" content=
"text/html; charset=utf-8" />
6 <meta name=
"generator" content=
"Docutils 0.4.1: http://docutils.sourceforge.net/" />
7 <title>Structure of SympyCore
</title>
8 <meta name=
"author" content=
"Pearu Peterson" />
9 <style type=
"text/css">
12 :Author: Pearu Peterson
13 :Contact: pearu.peterson AT gmail DOT com
14 :Copyright: This stylesheet has been placed in the public domain.
16 Stylesheet for use with Docutils.
19 @import url(html4css1.css);
21 /* Your customizations go here. For example: */
26 background-color: #ccc;
27 font-size:
13px; font-family: arial, sans-serif;
34 background-color: #fff;
36 border:
5px solid #ddd;
41 border: medium outset ;
43 background-color: #ffffee ;
48 div.sidebar p.rubric {
49 font-family: sans-serif ;
53 font-family: sans-serif ;
58 font-family: sans-serif ;
62 font-family: consolas, lucida console, courier new, monospace;
66 pre.literal-block, pre.doctest-block {
68 border-top:
1px solid #ccc;
69 border-bottom:
1px solid #ccc;
70 background-color:#f0f0f0;
74 div.admonition, div.attention, div.caution, div.danger, div.error,
75 div.hint, div.important, div.note, div.tip, div.warning {
77 border: medium outset ;
79 background-color: #fffacd;
82 div.admonition p.admonition-title, div.hint p.admonition-title,
83 div.important p.admonition-title, div.note p.admonition-title,
84 div.tip p.admonition-title {
86 font-family: sans-serif }
88 div.attention p.admonition-title, div.caution p.admonition-title,
89 div.danger p.admonition-title, div.error p.admonition-title,
90 div.warning p.admonition-title {
93 font-family: sans-serif }
98 <div class=
"document" id=
"structure-of-sympycore">
99 <h1 class=
"title">Structure of SympyCore
</h1>
100 <table class=
"docinfo" frame=
"void" rules=
"none">
101 <col class=
"docinfo-name" />
102 <col class=
"docinfo-content" />
104 <tr><th class=
"docinfo-name">Author:
</th>
105 <td>Pearu Peterson
</td></tr>
106 <tr class=
"field"><th class=
"docinfo-name">Website:
</th><td class=
"field-body"><a class=
"reference" href=
"http://sympycore.googlecode.com">http://sympycore.googlecode.com
</a></td>
108 <tr class=
"field"><th class=
"docinfo-name">Created:
</th><td class=
"field-body">March
2008</td>
112 <!-- -*- rest -*- -->
113 <div class=
"sidebar">
114 <p class=
"first sidebar-title">Table of contents
</p>
115 <div class=
"contents local last topic">
116 <ul class=
"auto-toc simple">
117 <li><a class=
"reference" href=
"#introduction" id=
"id2" name=
"id2">1 Introduction
</a></li>
118 <li><a class=
"reference" href=
"#fundamental-idea" id=
"id3" name=
"id3">2 Fundamental idea
</a><ul class=
"auto-toc">
119 <li><a class=
"reference" href=
"#implementation-of-principles" id=
"id4" name=
"id4">2.1 Implementation of principles
</a></li>
120 <li><a class=
"reference" href=
"#pre-defined-expression-heads" id=
"id5" name=
"id5">2.2 Pre-defined expression heads
</a></li>
123 <li><a class=
"reference" href=
"#classes-in-sympycore" id=
"id6" name=
"id6">3 Classes in SympyCore
</a><ul class=
"auto-toc">
124 <li><a class=
"reference" href=
"#low-level-numbers" id=
"id7" name=
"id7">3.1 Low-level numbers
</a></li>
125 <li><a class=
"reference" href=
"#constructing-instances" id=
"id8" name=
"id8">3.2 Constructing instances
</a></li>
126 <li><a class=
"reference" href=
"#various-representations" id=
"id9" name=
"id9">3.3 Various representations
</a></li>
127 <li><a class=
"reference" href=
"#id1" id=
"id10" name=
"id10">3.4 Constructing instances
</a></li>
128 <li><a class=
"reference" href=
"#verbatim-algebra" id=
"id11" name=
"id11">3.5 Verbatim algebra
</a></li>
129 <li><a class=
"reference" href=
"#logic-algebra" id=
"id12" name=
"id12">3.6 Logic algebra
</a></li>
130 <li><a class=
"reference" href=
"#collecting-field" id=
"id13" name=
"id13">3.7 Collecting field
</a></li>
133 <li><a class=
"reference" href=
"#defining-functions-in-sympycore" id=
"id14" name=
"id14">4 Defining functions in SympyCore
</a></li>
134 <li><a class=
"reference" href=
"#how-does-it-work-in-sympycore" id=
"id15" name=
"id15">5 How does it work in SympyCore?
</a><ul class=
"auto-toc">
135 <li><a class=
"reference" href=
"#how-strings-are-parsed-to-expressions" id=
"id16" name=
"id16">5.1 How strings are parsed to expressions?
</a></li>
136 <li><a class=
"reference" href=
"#how-arbitrary-python-objects-are-converted-to-expressions" id=
"id17" name=
"id17">5.2 How arbitrary Python objects are converted to expressions?
</a></li>
137 <li><a class=
"reference" href=
"#how-algebra-expressions-are-converted-to-other-algebras" id=
"id18" name=
"id18">5.3 How algebra expressions are converted to other algebras?
</a></li>
138 <li><a class=
"reference" href=
"#how-verbatim-expressions-are-converted-to-other-algebras" id=
"id19" name=
"id19">5.4 How verbatim expressions are converted to other algebras?
</a></li>
144 <div class=
"section">
145 <h1><a class=
"toc-backref" href=
"#id2" id=
"introduction" name=
"introduction">1 Introduction
</a></h1>
146 <p>This document gives an overview of data types that are used in
147 <tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> to represent symbolic expressions. First, the fundametal
148 idea of defining a Python type
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt>, that holds a pair of Python
149 objects, is explained. Then
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> is used to implement classes that
150 represent different mathematical concepts --- the actual class
151 structure of
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> is outlined. Subsequent sections document
152 the features of
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> classes in detail.
</p>
154 <div class=
"section">
155 <h1><a class=
"toc-backref" href=
"#id3" id=
"fundamental-idea" name=
"fundamental-idea">2 Fundamental idea
</a></h1>
156 <p>The fundamental idea behind the implementation of
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt>
157 classes is based on the following assertions:
</p>
159 <li>Any symbolic expression can be expressed as a pair of
<em>expression
160 head
</em> and
<em>expression data
</em>. The
<em>expression head
</em> defines
161 how the
<em>expression data
</em> is interpreted.
</li>
162 <li>Symbolic expression represents an unevaluated element of an
163 <em>algebraic structure
</em> under consideration. In the following we call
164 a algebraic structure as an algebra for brevity. An algebra is
165 represented by a Python class (an
<em>algebra class
</em>) and the
166 instances of this class represent symbolic expressions.
</li>
167 <li>An algebra may define
<em>operations
</em> between its elements
168 to form
<em>composite
</em> symbolic expressions. Each operation is
169 represented by the corresponding expression head. Since the same
170 operation may be defined for different algebras then the
171 same expression head (defining evaluation rules and other methods)
172 is used for symbolic expressions of different algebra classes.
</li>
173 <li>Symbolic expressions can be constructed directly from expression
174 head and data parts, or indirectly from performing operations with
175 other symbolic operations. Direct construction,
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span>
176 <span class=
"pre">class
>(
<head
>,
</span> <span class=
"pre"><data
>)
</span></tt>, results an unevaluated symbolic expression
177 instance while indirect construction,
<tt class=
"docutils literal"><span class=
"pre"><expr1
></span> <span class=
"pre"><operation
></span>
178 <span class=
"pre"><expr2
></span></tt>, evaluates the symbolic expression instance to a canonical
179 form. Direct construction does not have any argument validity checks for
180 efficiency and should be used internally by evaluation methods.
</li>
182 <div class=
"section">
183 <h2><a class=
"toc-backref" href=
"#id4" id=
"implementation-of-principles" name=
"implementation-of-principles">2.1 Implementation of principles
</a></h2>
184 <p>The assertions of the fundamental idea is implemented as follows:
</p>
186 <li>To hold the head and data parts of symbolic expressions, a class
187 <tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> is defined that instances will have an attribute
<tt class=
"docutils literal"><span class=
"pre">pair
</span></tt>
188 holding the head and data pair. In a way, the
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> class
189 represents an algebra with no mathematical properties - it just
190 holds some
<em>head
</em> and some
<em>data
</em>.
</li>
191 <li>To define the algebra operations for symbolic expressions,
192 subclasses of
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> implement the corresponding methods.
</li>
193 <li>The head parts of symbolic expressions are instances of
194 <tt class=
"docutils literal"><span class=
"pre">sympycore.heads.Head
</span></tt> classes that implement the evaluation rules
195 of the corresponding algebra operations. Since head instances are
196 singletons then Python
<tt class=
"docutils literal"><span class=
"pre">is
</span></tt> operation can be used for comparing
197 expression heads.
</li>
199 <p>The following section gives an overview of pre-defined expression heads.
</p>
201 <div class=
"section">
202 <h2><a class=
"toc-backref" href=
"#id5" id=
"pre-defined-expression-heads" name=
"pre-defined-expression-heads">2.2 Pre-defined expression heads
</a></h2>
203 <p>All head instances are available as attributes to the holder object
204 <tt class=
"docutils literal"><span class=
"pre">sympycore.core.heads
</span></tt>.
</p>
205 <div class=
"section">
206 <h3><a id=
"atomic-heads" name=
"atomic-heads">2.2.1 Atomic heads
</a></h3>
209 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SYMBOL
</span></tt> head represents any element of
210 the algebra. The corresponding expression data part can be any
211 Python object (usually it is a string).
<tt class=
"docutils literal"><span class=
"pre">SYMBOL
</span></tt> head defines no
212 interpretation rules for the data.
</blockquote>
215 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">NUMBER
</span></tt> head represents a generalized
216 repetition operation of algebra elements. The data part can be any
217 Python object that supports Python numbers protocol, that is, the
218 objects type must define all basic arithmetic operations. Usually
219 the data part contains number instances such as integers, floats,
220 complex numbers or numbers defined by the
221 <tt class=
"docutils literal"><span class=
"pre">sympycore.arithmetic.numbers
</span></tt> module: rational numbers and
222 arbitrary precision floating point numbers. The data part can also
223 contain symbolic expression of some other algebra (
<em>coefficient
224 algebra
</em>), then such expressions are considered as coefficients that
225 always commute with the elements of the given algebra.
</blockquote>
227 <div class=
"section">
228 <h3><a id=
"arithmetic-heads" name=
"arithmetic-heads">2.2.2 Arithmetic heads
</a></h3>
231 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">POS
</span></tt> head represents unevaluated unary
232 positive sign operation. The data part must be a symbolic expression.
233 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(POS,
</span> <span class=
"pre">a)
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">+a
</span></tt>.
</blockquote>
236 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">NEG
</span></tt> head represents unevaluated unary
237 negative sign operation. The data part must be a symbolic
239 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(NEG,
</span> <span class=
"pre">a)
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">-a
</span></tt>.
</blockquote>
242 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">ADD
</span></tt> head represents unevaluated n-ary
243 addition operation. The data part must be a Python list of symbolic
244 expression. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(ADD,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span>
245 <span class=
"pre">+
</span> <span class=
"pre">b
</span> <span class=
"pre">+
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
248 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SUB
</span></tt> head represents unevaluated n-ary
249 subtraction operation. The data part must be a Python list of symbolic
250 expression. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(SUB,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span>
251 <span class=
"pre">-
</span> <span class=
"pre">b
</span> <span class=
"pre">-
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
254 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">MUL
</span></tt> head represents unevaluated n-ary
255 multiplication operation. The data part must be a Python list of symbolic
256 expression. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(MUL,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span>
257 <span class=
"pre">*
</span> <span class=
"pre">b
</span> <span class=
"pre">*
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
260 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">NCMUL
</span></tt> head represents unevaluated n-ary
261 non-commutative multiplication operation. The data part must be a
262 Python list of symbolic expression that are not numbers. For
263 example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(NCMUL,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">*
</span> <span class=
"pre">b
</span> <span class=
"pre">*
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
266 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">DIV
</span></tt> head represents unevaluated n-ary
267 division operation. The data part must be a Python list of symbolic
268 expression. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(DIV,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span>
269 <span class=
"pre">/
</span> <span class=
"pre">b
</span> <span class=
"pre">/
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
272 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">POW
</span></tt> head represents unevaluated
273 exponentiation operation. The data part must be a Python
2-tuple of
274 symbolic expressions representing base and exponent parts. For
275 example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(POW,
</span> <span class=
"pre">(a,
</span> <span class=
"pre">b))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">**
</span> <span class=
"pre">b
</span></tt>.
</blockquote>
276 <p>TERM_COEFF_DICT
</p>
278 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">TERM_COEFF_DICT
</span></tt> head represents
279 unevaluated unordered addition operation. The data part must be a
280 Python dictionary of symbolic expression and coefficient pairs.
281 Coefficients must support number operations.
282 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(TERM_COEFF_DICT,
</span> <span class=
"pre">{a:
2,
</span> <span class=
"pre">b:
1})
</span></tt> represents
283 <tt class=
"docutils literal"><span class=
"pre">2*a
</span> <span class=
"pre">+
</span> <span class=
"pre">b
</span></tt>.
</blockquote>
286 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">BASE_EXP_DICT
</span></tt> head represents
287 unevaluated unordered multiplication operation. The data part must be a
288 Python dictionary of symbolic expression and exponent pairs.
289 Exponent objects must support number operations.
290 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(BASE_EXP_DICT,
</span> <span class=
"pre">{a:
2,
</span> <span class=
"pre">b:
1})
</span></tt> represents
291 <tt class=
"docutils literal"><span class=
"pre">a**
2</span> <span class=
"pre">*
</span> <span class=
"pre">b
</span></tt>.
</blockquote>
292 <p>EXP_COEFF_DICT
</p>
294 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">EXP_COEFF_DICT
</span></tt> head represents
295 unevaluated unordered polynomial addition operation. The data part
296 must be a
<tt class=
"docutils literal"><span class=
"pre">Pair
</span></tt> instance containing a tuple of variable
297 expressions and a dictionary of integer exponents and coefficient
298 pairs. Coefficient objects must support number operations. For
299 example,
<tt class=
"docutils literal"><span class=
"pre">Algbera(EXP_COEFF_DICT,
</span> <span class=
"pre">Pair((x,
</span> <span class=
"pre">sin(x)),
</span> <span class=
"pre">{(
0,
1):
2,
</span>
300 <span class=
"pre">(
2,
3):
5}))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">2*sin(x)
</span> <span class=
"pre">+
</span> <span class=
"pre">5*x**
2*sin(x)**
3</span></tt>.
</blockquote>
301 <p>LSHIFT, RSHIFT
</p>
303 Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">LSHIFT
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">RSHIFT
</span></tt> heads represent
304 unevaluated n-ary
<em>left-shift
</em> and
<em>right-shift
</em> operations. The
305 data part must be a list of symbolic expressions.
306 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(LSHIFT,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
<<b
<<c
</span></tt>.
</blockquote>
307 <p>INVERT, BOR, BXOR, BAND, FLOORDIV
</p>
309 Binary operations.
</blockquote>
311 <div class=
"section">
312 <h3><a id=
"logic-heads" name=
"logic-heads">2.2.3 Logic heads
</a></h3>
315 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">NOT
</span></tt> head represents unevaluated unary
316 logical
<em>negation
</em> operation. The data part must be a symbolic
317 expression that is an instance of a
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> algebra class. For
318 example,
<tt class=
"docutils literal"><span class=
"pre">Logic(NOT,
</span> <span class=
"pre">a)
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">not
</span> <span class=
"pre">a
</span></tt>.
</blockquote>
321 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">OR
</span></tt> head represents unevaluated n-ary
322 logical
<em>disjunction
</em> operation. The data part must be a list of
323 <tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instances. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(OR,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt>
324 represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">or
</span> <span class=
"pre">b
</span> <span class=
"pre">or
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
327 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">XOR
</span></tt> head represents unevaluated n-ary
328 logical
<em>exclusive disjunction
</em> operation. The data part must be a
329 list of
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instances. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(XOR,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt>
330 represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">xor
</span> <span class=
"pre">b
</span> <span class=
"pre">xor
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
333 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">AND
</span></tt> head represents unevaluated n-ary
334 logical
<em>conjunction
</em> operation. The data part must be a list of
335 <tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instances. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(AND,
</span> <span class=
"pre">[a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c])
</span></tt>
336 represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">and
</span> <span class=
"pre">b
</span> <span class=
"pre">and
</span> <span class=
"pre">c
</span></tt>.
</blockquote>
339 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">IMPLIES
</span></tt> head represents unevaluated
340 binary logical
<em>conditional
</em> operation (if-then). The data part must
341 be a
2-tuple of
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instances. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(IMPLIES,
</span>
342 <span class=
"pre">(a,
</span> <span class=
"pre">b))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">implies
</span> <span class=
"pre">b
</span></tt>.
</blockquote>
345 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">EQUIV
</span></tt> head represents unevaluated
346 binary logical
<em>biconditional
</em> operation (if-and-only-if). The data part must
347 be a
2-tuple of
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instances. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(EQUIV,
</span>
348 <span class=
"pre">(a,
</span> <span class=
"pre">b))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre">equiv
</span> <span class=
"pre">b
</span></tt>.
</blockquote>
350 <div class=
"section">
351 <h3><a id=
"relational-heads" name=
"relational-heads">2.2.4 Relational heads
</a></h3>
352 <p>The symbolic expressions of relational operations are instances of the
353 <tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> algebra class. The data parts of relational operations are Python
354 2-tuples of symbolic expressions.
</p>
355 <p>EQ, NE, LT, LE, GT, GE
</p>
357 Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">EQ
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">NE
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">LT
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">LE
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">GT
</span></tt>, or
358 <tt class=
"docutils literal"><span class=
"pre">GE
</span></tt> heads represent unevaluated binary relational operations
359 <em>equal
</em>,
<em>not-equal
</em>,
<em>less-than
</em>,
<em>less-equal
</em>,
<em>greater-than
</em>, or
360 <em>greater-equal
</em>, respectively. For example,
<tt class=
"docutils literal"><span class=
"pre">Logic(LT,
</span> <span class=
"pre">(a,
</span> <span class=
"pre">b))
</span></tt>
361 represents
<tt class=
"docutils literal"><span class=
"pre">a
</span> <span class=
"pre"><</span> <span class=
"pre">b
</span></tt>.
</blockquote>
364 Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">IN
</span></tt> or
<tt class=
"docutils literal"><span class=
"pre">NOTIN
</span></tt> heads represent
365 unevaluated binary relational operations
<em>in
</em> or
<em>not-in
</em>,
366 respectively. The left-hand-side operand should be an element of the
367 right-hand-side operand which is a
<tt class=
"docutils literal"><span class=
"pre">Set
</span></tt> instance.
</blockquote>
370 Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">IN
</span></tt> or
<tt class=
"docutils literal"><span class=
"pre">NOTIN
</span></tt> heads represent
371 unevaluated binary relational operations
<em>in
</em> or
<em>not-in
</em>,
372 respectively.
</blockquote>
374 <div class=
"section">
375 <h3><a id=
"container-heads" name=
"container-heads">2.2.5 Container heads
</a></h3>
376 <p>TUPLE, LIST, DICT
</p>
378 Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">TUPLE
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">LIST
</span></tt>, or
<tt class=
"docutils literal"><span class=
"pre">DICT
</span></tt> heads
379 represent unevaluated tuple, list, or dict expressions,
380 respectively. The data parts must be Python tuple, list, or dict
381 instances, respectively, of symbolic expressions. For example,
382 <tt class=
"docutils literal"><span class=
"pre">Algebra(TUPLE,
</span> <span class=
"pre">(a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">c))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">(a,b,c)
</span></tt>.
</blockquote>
384 <div class=
"section">
385 <h3><a id=
"special-heads" name=
"special-heads">2.2.6 Special heads
</a></h3>
388 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">CALLABLE
</span></tt> head represents an element
389 of functions algebra. The data part must be Python callable object
390 that returns a symbolic expression representing an element of
391 functions values algebra. Symbolic expressions with
<tt class=
"docutils literal"><span class=
"pre">CALLABLE
</span></tt>
392 head are usually used in connection with
<tt class=
"docutils literal"><span class=
"pre">APPLY
</span></tt> head to represent
393 unevaluated applied function expressions. In fact, if the callable
394 data part cannot evaluate its arguments then it should return
395 <tt class=
"docutils literal"><span class=
"pre">Algebra(APPLY,
</span> <span class=
"pre">(FunctionAlgebra(CALLABLE,
</span> <span class=
"pre"><callable
>),
</span> <span class=
"pre"><argument1
>,
</span> <span class=
"pre">...))
</span></tt>.
</blockquote>
398 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SPECIAL
</span></tt> head does not represent any
399 element of the given algebra. That said, the data part can hold any
400 Python object. In practice, data can be Python
<tt class=
"docutils literal"><span class=
"pre">Ellipsis
</span></tt> or
401 <tt class=
"docutils literal"><span class=
"pre">None
</span></tt> objects. Also, data can hold extended number instances
402 (e.g. infinities) of the given algebra.
</blockquote>
405 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">APPLY
</span></tt> head represents an unevaluated
406 applied function expression. The data part must be a tuple of
407 symbolic expressions where the first element belongs to functions
408 algebra and the rest of the elements are function arguments.
409 For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(APPLY,
</span> <span class=
"pre">(f,
</span> <span class=
"pre">x,
</span> <span class=
"pre">y))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">f(x,
</span> <span class=
"pre">y)
</span></tt>.
</blockquote>
412 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">KWARG
</span></tt> head represents a keyword
413 argument to symbolic functions. The data part must be a
2-tuple of
414 symbolic expressions. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(KWARG,
</span> <span class=
"pre">(a,b))
</span></tt>
415 represents
<tt class=
"docutils literal"><span class=
"pre">a=b
</span></tt>.
</blockquote>
418 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SUBSCRIPT
</span></tt> head represents an
419 unevaluated applied subscript expression. The data part must be a
420 tuple of symbolic expressions. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(SUBSCRIPT,
</span>
421 <span class=
"pre">(f,i,j))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">f[i,j]
</span></tt>.
</blockquote>
424 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SLICE
</span></tt> head represents an
425 unevaluated slice expression. The data part must be a
426 3-tuple of symbolic expressions. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(SLICE,
</span>
427 <span class=
"pre">(i:Algebra(SPECIAL,
</span> <span class=
"pre">None):k))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">i::k
</span></tt>.
</blockquote>
430 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SUBSCRIPT
</span></tt> head represents an
431 unevaluated applied attribute expression. The data part must be a
432 2-tuple of symbolic expressions. For example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(ATTR,
</span> <span class=
"pre">(f,
</span>
433 <span class=
"pre">a))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">f.a
</span></tt>.
</blockquote>
436 A symbolic expression with
<tt class=
"docutils literal"><span class=
"pre">SUBSCRIPT
</span></tt> head represents a
437 lambda expression. The data part must be a
2-tuple of a tuple
438 (lambda arguments) and symbolic expression (lambda body). For
439 example,
<tt class=
"docutils literal"><span class=
"pre">Algebra(LAMBDA,
</span> <span class=
"pre">((a,b),
</span> <span class=
"pre">c))
</span></tt> represents
<tt class=
"docutils literal"><span class=
"pre">lambda
</span> <span class=
"pre">a,
</span> <span class=
"pre">b:
</span>
440 <span class=
"pre">c
</span></tt>.
</blockquote>
444 <div class=
"section">
445 <h1><a class=
"toc-backref" href=
"#id6" id=
"classes-in-sympycore" name=
"classes-in-sympycore">3 Classes in SympyCore
</a></h1>
446 <p>The following diagram summarizes what classes
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> is going
448 <pre class=
"literal-block">
467 int, long, float, complex
469 <div class=
"section">
470 <h2><a class=
"toc-backref" href=
"#id7" id=
"low-level-numbers" name=
"low-level-numbers">3.1 Low-level numbers
</a></h2>
471 <p>Many algebras define numbers as generalized repetitions of the algebra
472 unit element. Sympycore uses and defines the following number types
473 for purely numerical tasks, i.e. both operands and operation results
475 <table border=
"1" class=
"docutils">
481 <tr><td>int, long
</td>
482 <td>integers of arbitrary size
</td>
488 <td>arbitrary precision floating point numbers
</td>
491 <td>complex numbers with rational parts
</td>
494 <td>arbitrary precision complex floating point numbers
</td>
498 <p>Python
<tt class=
"docutils literal"><span class=
"pre">float
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">complex
</span></tt> instances are converted to
<tt class=
"docutils literal"><span class=
"pre">mpf
</span></tt>
499 and
<tt class=
"docutils literal"><span class=
"pre">mpc
</span></tt> instances, respectively, when used in operations with
500 symbolic expressions.
</p>
501 <p>These number types are called
"low-level
" numbers because some of
502 their properties may be unusual for generic numbers (e.g. mpf is
503 derived from Python tuple) but these properties are introduced to
504 improve the efficiency of number operations.
</p>
505 <p>For example,
<tt class=
"docutils literal"><span class=
"pre">mpq
</span></tt> number is assumed to hold a normalized rational
506 number that is not integer. Operations between
<tt class=
"docutils literal"><span class=
"pre">mpq
</span></tt> instances that
507 would produce integer result, will return
<tt class=
"docutils literal"><span class=
"pre">int
</span></tt> (or
<tt class=
"docutils literal"><span class=
"pre">long
</span></tt>)
508 instance. Similarly, the real valued result of an operation between
509 complex numbers
<tt class=
"docutils literal"><span class=
"pre">mpqc
</span></tt> (or
<tt class=
"docutils literal"><span class=
"pre">mpc
</span></tt>) will be an instance of
<tt class=
"docutils literal"><span class=
"pre">int
</span></tt>
510 or
<tt class=
"docutils literal"><span class=
"pre">long
</span></tt> or
<tt class=
"docutils literal"><span class=
"pre">mpq
</span></tt> (or
<tt class=
"docutils literal"><span class=
"pre">mpf
</span></tt>) type.
</p>
511 <div class=
"warning">
512 <p class=
"first admonition-title">Warning
</p>
513 <p class=
"last">THE CONTENT BELOW NEEDS A REVISION.
</p>
515 <div class=
"warning">
516 <p class=
"first admonition-title">Warning
</p>
517 <p class=
"last">The Python code fragments shown in this section are presented only
518 for illustration purposes. The
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> may use slightly
519 different implementation (explained in the following sections) that
520 gives a better performance. However, the basic idea remain the same.
</p>
522 <p>In
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt>, any symbolic expression is defined as an instance of a
523 <tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> class (or one of its subclasses):
</p>
524 <pre class=
"literal-block">
527 def __init__(self, head, data):
528 self.pair = (head, data)
530 head = property(lambda self: self.pair[
0])
531 data = property(lambda self: self.pair[
1])
533 <p>To define an algebra with additional properties that define opertions
534 between its elements, a Python class is derived from the
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt>
536 <pre class=
"literal-block">
539 def operation(self, other):
543 <p>where an operation between algerba elements is implemented in a method
544 <tt class=
"docutils literal"><span class=
"pre">operation
</span></tt>.
</p>
545 <p>For example. a commutative ring element can be represented as an
546 instance of the following class:
</p>
547 <pre class=
"literal-block">
548 class CommutativeRing(Expr):
550 def __add__(self, other):
551 return CommutativeRing('+', (self, other))
553 __radd__ = __add__ # addition is commutative
555 def __mul__(self, other):
556 return CommutativeRing('*', (self, other))
559 <div class=
"section">
560 <h2><a class=
"toc-backref" href=
"#id8" id=
"constructing-instances" name=
"constructing-instances">3.2 Constructing instances
</a></h2>
561 <p>For convenience, one can provide additional methods or functions that
562 will simplify creating instances of the
<tt class=
"docutils literal"><span class=
"pre">Expr
</span></tt> based classes. For
563 example, to construct a symbol of a commutative ring, one can define
564 the following function:
</p>
565 <pre class=
"literal-block">
567 return CommutativeRing('S', name)
569 <p>To construct a number of a commutative ring, one can define:
</p>
570 <pre class=
"literal-block">
572 return CommutativeRing('N', value)
574 <p>To construct an applied unary function with a value in a commutative
575 ring, one can define:
</p>
576 <pre class=
"literal-block">
578 "Return the value of function F
"
579 return
<result
>
581 def Apply(function, argument):
582 return CommutativeRing(function, argument)
584 <p>Since
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> defines many classes representing different
585 algebras, the functions above are usually implemented as Python
586 <tt class=
"docutils literal"><span class=
"pre">classmethod
</span></tt>-s of the corresponding algebra classes. Also, the
587 <tt class=
"docutils literal"><span class=
"pre">head
</span></tt> parts may be changed to anything more appropiate.
</p>
589 <div class=
"section">
590 <h2><a class=
"toc-backref" href=
"#id9" id=
"various-representations" name=
"various-representations">3.3 Various representations
</a></h2>
591 <p>Note that a fixed symbolic expression may have different but
592 mathematically equivalent representations. For example, consider the
593 following symbolic expression:
</p>
594 <pre class=
"literal-block">
597 <p>This expression may have at least three different representations:
</p>
598 <pre class=
"literal-block">
599 Ring(head='ADD', data=(x**
3,
2*y))
600 Ring(head='TERMS', data=((x**
3,
1), (y,
2)))
601 Ring(head=(x,y), data=(((
3,
0),
1), ((
0,
1),
2)))
603 <p>where the
<tt class=
"docutils literal"><span class=
"pre">data
</span></tt> structures are interpreted as follows:
</p>
604 <pre class=
"literal-block">
607 x**
3 * y**
0 *
1 + x**
0 * y**
1 *
2
610 <p>In general, there is no preferred representation for a symbolic
611 expression, each representation has its pros and cons depending on
614 <div class=
"section">
615 <h2><a class=
"toc-backref" href=
"#id10" id=
"id1" name=
"id1">3.4 Constructing instances
</a></h2>
616 <p>There are two types of symbolic expressions: atomic and composites.
617 Atomic expressions are symbols and numbers. Symbols can be considered
618 as unspecified numbers. Composite expressions are unevaluated forms of
619 operators or operations defined between symbolic expressions.
</p>
620 <p>In SympyCore, each algebra class defines classmethods
621 <tt class=
"docutils literal"><span class=
"pre">Symbol(
<obj
>)
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">Number(
<obj
>)
</span></tt> that can be used to construct
622 atomic expressions. In fact, they will usually return
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span>
623 <span class=
"pre">class
>(SYMBOL,
</span> <span class=
"pre"><obj
>)
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>(NUMBER,
</span> <span class=
"pre"><obj
>)
</span></tt>,
624 respectively. Regarding nubers, it is callers responsibility to ensure
625 that
<tt class=
"docutils literal"><span class=
"pre"><obj
></span></tt> is usable as a number. Some algebra classes also
626 define class attributes
<tt class=
"docutils literal"><span class=
"pre">zero
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">one
</span></tt> holding identity numbers
627 with respect to addition and multiplication operations. In
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt>
628 algebra, these numbers are aliases to
<tt class=
"docutils literal"><span class=
"pre">false
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">true
</span></tt> values,
630 <p>Depending on the callers need, there are at least three possibilities
631 in SympyCore to construct composite expressions:
</p>
632 <ol class=
"arabic simple">
633 <li>Use
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>(
<head
>,
</span> <span class=
"pre"><data
>)
</span></tt> that will return an algebra
634 class instance with given head and data. No evaluation or
635 canonization is performed. This construction is usually used by
636 low-level methods that must ensure that the data part contains
637 proper data, that is, data in a form that the rest of sympycore
639 <li>Use
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>.
<Operation
>(
<operands
>)
</span></tt> class method call
640 that will perform basic canonization of the operation applied to
641 operands and returns canonized result as an instance of the algebra
642 class. This construction is usually used by high-level methods that
643 must ensure that operands are instances of operands algebra.
</li>
644 <li>Use
<tt class=
"docutils literal"><span class=
"pre"><Operation
>(
<operands
>)
</span></tt> function call that will convert
645 operands to operands algebra instances and then returns the result
646 of
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>.
<Operation
></span></tt> classmethod. This construction
647 should be used by end-users.
</li>
649 <p>There exist also some convenience and implementation specific
650 possibilities to construct expressions:
</p>
651 <ol class=
"arabic simple" start=
"4">
652 <li>Use
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>.convert(
<obj
>,
</span> <span class=
"pre">typeerror=True)
</span></tt> to convert
653 Python object
<tt class=
"docutils literal"><span class=
"pre"><obj
></span></tt> to algebra instance. If conversation is not
654 defined then
<tt class=
"docutils literal"><span class=
"pre">TypeError
</span></tt> is raised by default. When
655 <tt class=
"docutils literal"><span class=
"pre">typeerror=False
</span></tt> then
<tt class=
"docutils literal"><span class=
"pre">NotImplemented
</span></tt> is returned instead of
656 raising the exception.
</li>
657 <li>Use
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
>(
<obj
>)
</span></tt> that is an alias to
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span>
658 <span class=
"pre">class
>.convert(
<obj
>)
</span></tt> call.
</li>
661 <div class=
"section">
662 <h2><a class=
"toc-backref" href=
"#id11" id=
"verbatim-algebra" name=
"verbatim-algebra">3.5 Verbatim algebra
</a></h2>
663 <p>SympyCore defines
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> class that represents verbatim algebra.
664 Verbatim algebra contains expressions in unevaluated form. The
665 verbatim algebra can be used to implement generic methods for
666 transforming symbolic expressions to strings, or to instances of other
669 <div class=
"section">
670 <h2><a class=
"toc-backref" href=
"#id12" id=
"logic-algebra" name=
"logic-algebra">3.6 Logic algebra
</a></h2>
671 <p>SympyCore defines
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> class that represents n-ary predicate
672 expressions. The following operations are defined by the
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt>
674 <ol class=
"arabic simple">
675 <li><tt class=
"docutils literal"><span class=
"pre">Not(x)
</span></tt> represents boolean expression
<tt class=
"docutils literal"><span class=
"pre">not
</span> <span class=
"pre">x
</span></tt>. Operand algebra
676 class is
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt>.
</li>
677 <li><tt class=
"docutils literal"><span class=
"pre">And(x,y,..)
</span></tt> represents boolean expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">and
</span> <span class=
"pre">y
</span> <span class=
"pre">and
</span> <span class=
"pre">..
</span></tt>.
678 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt>.
</li>
679 <li><tt class=
"docutils literal"><span class=
"pre">Or(x,y,..)
</span></tt> represents boolean expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">or
</span> <span class=
"pre">y
</span> <span class=
"pre">or
</span> <span class=
"pre">..
</span></tt>.
680 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt>.
</li>
681 <li><tt class=
"docutils literal"><span class=
"pre">Lt(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre"><</span> <span class=
"pre">y
</span></tt>.
682 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
683 <li><tt class=
"docutils literal"><span class=
"pre">Le(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre"><=
</span> <span class=
"pre">y
</span></tt>.
684 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
685 <li><tt class=
"docutils literal"><span class=
"pre">Gt(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">></span> <span class=
"pre">y
</span></tt>.
686 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
687 <li><tt class=
"docutils literal"><span class=
"pre">Ge(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">>=
</span> <span class=
"pre">y
</span></tt>.
688 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
689 <li><tt class=
"docutils literal"><span class=
"pre">Eq(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">==
</span> <span class=
"pre">y
</span></tt>.
690 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
691 <li><tt class=
"docutils literal"><span class=
"pre">Ne(x,
</span> <span class=
"pre">y)
</span></tt> represents relational expression
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">!=
</span> <span class=
"pre">y
</span></tt>.
692 Operand algebra class is
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>.
</li>
695 <div class=
"section">
696 <h2><a class=
"toc-backref" href=
"#id13" id=
"collecting-field" name=
"collecting-field">3.7 Collecting field
</a></h2>
697 <p>SympyCore defines
<tt class=
"docutils literal"><span class=
"pre">CollectingField
</span></tt> class to represent sums and
698 products in
<tt class=
"docutils literal"><span class=
"pre">{
<term
>:
<coefficent
>}
</span></tt> and
<tt class=
"docutils literal"><span class=
"pre">{
<base
>:
<exponent
>}
</span></tt>
699 forms, respectively. The class name contains prefix
"Collecting
"
700 because in operations with
<tt class=
"docutils literal"><span class=
"pre">CollectingField
</span></tt> instances, equal terms
701 and equal bases are automatically collected by upgrading the
702 coefficient and exponent values, respectively.
</p>
703 <p>The following operations are defined by the
<tt class=
"docutils literal"><span class=
"pre">CollectingField
</span></tt> and
704 its subclasses
<tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">Unit
</span></tt>:
</p>
705 <ol class=
"arabic simple">
706 <li><tt class=
"docutils literal"><span class=
"pre">Add(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..)
</span></tt> represents addition
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">+
</span> <span class=
"pre">y
</span> <span class=
"pre">+
</span> <span class=
"pre">..
</span></tt>.
707 Operand algebra class is the same as algebra class.
</li>
708 <li><tt class=
"docutils literal"><span class=
"pre">Mul(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..)
</span></tt> represents multiplication
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">*
</span> <span class=
"pre">y
</span> <span class=
"pre">*
</span> <span class=
"pre">..
</span></tt>.
709 Operand algebra class is the same as algebra class.
</li>
710 <li><tt class=
"docutils literal"><span class=
"pre">Terms((x,a),
</span> <span class=
"pre">(y,b),
</span> <span class=
"pre">..)
</span></tt> represents a sum
<tt class=
"docutils literal"><span class=
"pre">a*x
</span> <span class=
"pre">+
</span> <span class=
"pre">b*y
</span> <span class=
"pre">+
</span> <span class=
"pre">..
</span></tt>
711 where
<tt class=
"docutils literal"><span class=
"pre">x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..
</span></tt> must be non-numeric instances of the algebra
712 class and
<tt class=
"docutils literal"><span class=
"pre">a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">..
</span></tt> are low-level numbers.
</li>
713 <li><tt class=
"docutils literal"><span class=
"pre">Factors((x,a),
</span> <span class=
"pre">(y,b),
</span> <span class=
"pre">..)
</span></tt> represents a product
<tt class=
"docutils literal"><span class=
"pre">x**a
</span> <span class=
"pre">*
</span> <span class=
"pre">y**b
</span> <span class=
"pre">*
</span> <span class=
"pre">..
</span></tt>
714 where
<tt class=
"docutils literal"><span class=
"pre">x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..
</span></tt> must be instances of the algebra
715 class and
<tt class=
"docutils literal"><span class=
"pre">a,
</span> <span class=
"pre">b,
</span> <span class=
"pre">..
</span></tt> are either low-level numbers or instances of
716 exponent algebra.
</li>
717 <li><tt class=
"docutils literal"><span class=
"pre">Pow(x,
</span> <span class=
"pre">y)
</span></tt> represents exponentiation
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">**
</span> <span class=
"pre">y
</span></tt> where
<tt class=
"docutils literal"><span class=
"pre">x
</span></tt> must
718 be instance of the algebra class and
<tt class=
"docutils literal"><span class=
"pre">y
</span></tt> must be either low-level
719 number or an instance of exponent algebra.
</li>
720 <li><tt class=
"docutils literal"><span class=
"pre">Sub(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..)
</span></tt> represents operation
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">-
</span> <span class=
"pre">y
</span> <span class=
"pre">-
</span> <span class=
"pre">..
</span></tt> where operands
721 must be instances of the algebra class.
</li>
722 <li><tt class=
"docutils literal"><span class=
"pre">Div(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..)
</span></tt> represents operation
<tt class=
"docutils literal"><span class=
"pre">x
</span> <span class=
"pre">/
</span> <span class=
"pre">y
</span> <span class=
"pre">/
</span> <span class=
"pre">..
</span></tt> where operands
723 must be instances of the algebra class.
</li>
724 <li><tt class=
"docutils literal"><span class=
"pre">Apply(f,
</span> <span class=
"pre">(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..))
</span></tt> represents unevaluated function call
725 <tt class=
"docutils literal"><span class=
"pre">f(x,
</span> <span class=
"pre">y,
</span> <span class=
"pre">..)
</span></tt>.
</li>
729 <div class=
"section">
730 <h1><a class=
"toc-backref" href=
"#id14" id=
"defining-functions-in-sympycore" name=
"defining-functions-in-sympycore">4 Defining functions in SympyCore
</a></h1>
731 <p>In general, unevaluated applied functions in
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> are
732 represented as a pair:
</p>
733 <pre class=
"literal-block">
734 <Algebra class
>(
<callable
>,
<arguments
>)
736 <p>where
<tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">class
></span></tt> defines an algebra where the function values
737 belong to,
<tt class=
"docutils literal"><span class=
"pre"><callable
></span></tt> is a Python callable object that may define
738 some basic canonization rules, and
<tt class=
"docutils literal"><span class=
"pre"><arguments
></span></tt> is either a tuple
739 of function arguments or for single argument functions, the argument
741 <p>To simplify the infrastructure for handling defined functions, the
742 defined functions in
<tt class=
"docutils literal"><span class=
"pre">sympycore
</span></tt> should be defined as classes
743 derived from
<tt class=
"docutils literal"><span class=
"pre">DefinedFunction
</span></tt> class (defined in
744 <tt class=
"docutils literal"><span class=
"pre">sympycore.core
</span></tt>). Such defined functions will be available as
745 attributes of the
<tt class=
"docutils literal"><span class=
"pre">defined_functions
</span></tt> holder object, and most
746 importantly, the expression string parser will recognize symbols with
747 defined function names as defined functions.
</p>
748 <p>Here follows a typical definition of a defined function
<tt class=
"docutils literal"><span class=
"pre">myfunc
</span></tt> for
749 a given
<tt class=
"docutils literal"><span class=
"pre">Algebra
</span></tt> class:
</p>
750 <pre class=
"literal-block">
751 class myfunc(DefinedFunction):
753 def __new__(cls, *args):
754 # perform any canonization of arguments (including
755 # converting arguments to operands algebra) and return
756 # simplified result. Otherwise,
757 return Algebra(cls, args)
760 <div class=
"section">
761 <h1><a class=
"toc-backref" href=
"#id15" id=
"how-does-it-work-in-sympycore" name=
"how-does-it-work-in-sympycore">5 How does it work in SympyCore?
</a></h1>
762 <div class=
"section">
763 <h2><a class=
"toc-backref" href=
"#id16" id=
"how-strings-are-parsed-to-expressions" name=
"how-strings-are-parsed-to-expressions">5.1 How strings are parsed to expressions?
</a></h2>
764 <p>Expressions represent elements of some algebra. Therefore, to parse a
765 string and to create an expression from it, one needs to specify to
766 which algebra the expression should belong to. In sympycore, this is
767 done by calling the corresponding algebra constructor with a single
769 <pre class=
"literal-block">
770 Algebra('
<expr
>')
772 <p>that will return the result of
<tt class=
"docutils literal"><span class=
"pre">Algebra.convert('
<expr
>')
</span></tt>. Continue
773 reading the next section about the
<tt class=
"docutils literal"><span class=
"pre">convert
</span></tt> method.
</p>
775 <div class=
"section">
776 <h2><a class=
"toc-backref" href=
"#id17" id=
"how-arbitrary-python-objects-are-converted-to-expressions" name=
"how-arbitrary-python-objects-are-converted-to-expressions">5.2 How arbitrary Python objects are converted to expressions?
</a></h2>
777 <p>Each algebra class has classmethod
<tt class=
"docutils literal"><span class=
"pre">convert(
<obj
>,
</span> <span class=
"pre">typeerror=True)
</span></tt>
778 that is used to convert arbitrary Python objects to Algebra instances.
779 The following algorithm is used:
</p>
780 <ol class=
"arabic simple">
781 <li>If
<tt class=
"docutils literal"><span class=
"pre"><obj
></span></tt> is already
<tt class=
"docutils literal"><span class=
"pre">Algebra
</span></tt> instance, then it is returned
783 <li>Next, the classmethod
<tt class=
"docutils literal"><span class=
"pre">Algebra.convert_number(
<obj
>,
</span> <span class=
"pre">typeerror)
</span> <span class=
"pre">-
></span>
784 <span class=
"pre">r
</span></tt> is called. On success,
<tt class=
"docutils literal"><span class=
"pre">Algebra.Number(r)
</span></tt> is returned. In
785 most cases,
<tt class=
"docutils literal"><span class=
"pre">Algebra.Number
</span></tt> class method just returns
786 <tt class=
"docutils literal"><span class=
"pre">cls(NUMBER,
</span> <span class=
"pre">r)
</span></tt>. But there exist exceptions.
</li>
787 <li>Next, if
<tt class=
"docutils literal"><span class=
"pre"><obj
></span></tt> is Python string or
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> instance, then
788 <tt class=
"docutils literal"><span class=
"pre">Verbatim.convert(
<obj
>).as_algebra(Algebra)
</span></tt> is returned.
</li>
789 <li>Next, if
<tt class=
"docutils literal"><span class=
"pre"><obj
></span></tt> is some algebra instance then
790 <tt class=
"docutils literal"><span class=
"pre"><obj
>.as_algebra(Algebra)
</span></tt> is returned.
</li>
791 <li>Finally, if none of the above did not return a result, then
792 <tt class=
"docutils literal"><span class=
"pre">TypeError
</span></tt> will be raised when
<tt class=
"docutils literal"><span class=
"pre">typeerror
</span></tt> is
793 <tt class=
"docutils literal"><span class=
"pre">True
</span></tt>. Otherwise
<tt class=
"docutils literal"><span class=
"pre">NotImplemented
</span></tt> will be returned.
</li>
795 <p>Continue reading the next section about the
<tt class=
"docutils literal"><span class=
"pre">as_algebra
</span></tt> method.
</p>
797 <div class=
"section">
798 <h2><a class=
"toc-backref" href=
"#id18" id=
"how-algebra-expressions-are-converted-to-other-algebras" name=
"how-algebra-expressions-are-converted-to-other-algebras">5.3 How algebra expressions are converted to other algebras?
</a></h2>
799 <p>Each algebra class has instance method
<tt class=
"docutils literal"><span class=
"pre">as_algebra(
<other
</span> <span class=
"pre">algebra
</span>
800 <span class=
"pre">class
>)
</span></tt> that is used to convert instances of one algebra class to
801 instances of another algebra class. By default, the conversion is
802 carried out using the intermediate
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> algebra. First, the
803 instance of one algebra is converted to
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> algebra and then
804 the instance of a
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> algebra is converted to another
805 algebra. So, every algebra class must define
<tt class=
"docutils literal"><span class=
"pre">as_verbatim()
</span></tt>
806 instance method that should return a
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt> instance containing
807 verbatim representation of the algebra expression.
</p>
808 <p>Of course, if an expression in one algebra does not make sense as an
809 expression of the other algebra, the
<tt class=
"docutils literal"><span class=
"pre">TypeError
</span></tt> will be raised.
</p>
810 <p>Continue reading the next section about the
<tt class=
"docutils literal"><span class=
"pre">Verbatim.as_algebra
</span></tt>
813 <div class=
"section">
814 <h2><a class=
"toc-backref" href=
"#id19" id=
"how-verbatim-expressions-are-converted-to-other-algebras" name=
"how-verbatim-expressions-are-converted-to-other-algebras">5.4 How verbatim expressions are converted to other algebras?
</a></h2>
815 <p>Verbatim expressions are converted to another algebras in
<tt class=
"docutils literal"><span class=
"pre"><Verbatim
</span>
816 <span class=
"pre">instance
>.as_algebra(
<Algebra
</span> <span class=
"pre">class
>)
</span></tt> instance method.
<tt class=
"docutils literal"><span class=
"pre">Verbatim
</span></tt>
817 instance holds a pair
<tt class=
"docutils literal"><span class=
"pre">(
<expression
</span> <span class=
"pre">head
>,
</span> <span class=
"pre"><expression
</span> <span class=
"pre">data
>)
</span></tt> and
818 the task of
<tt class=
"docutils literal"><span class=
"pre">as_algebra
</span></tt> method is to use information in triple
819 <tt class=
"docutils literal"><span class=
"pre"><expression
</span> <span class=
"pre">head
>,
</span> <span class=
"pre"><expression
</span> <span class=
"pre">data
>,
</span> <span class=
"pre"><Algebra
</span> <span class=
"pre">class
></span></tt> and
820 construct an
<tt class=
"docutils literal"><span class=
"pre"><Algebra
></span></tt> instance representing expression in the
822 <p>First, let us consider atomic expressions such as numbers and symbols.
</p>
823 <p>In general, numbers can be low-level numbers such as
<tt class=
"docutils literal"><span class=
"pre">int
</span></tt>,
824 <tt class=
"docutils literal"><span class=
"pre">long
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">mpq
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">mpf
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">mpc
</span></tt>,
<tt class=
"docutils literal"><span class=
"pre">mpqc
</span></tt>, but numbers of one
825 algebra can be expressions of some other algebra. So, in case of
826 verbatim numbers,
<tt class=
"docutils literal"><span class=
"pre">Algebra.convert(
<Verbatim
</span> <span class=
"pre">instance
>.data)
</span></tt> is
828 <p>In general, symbols are Python string objects but certain string
829 values may be names of mathematical constants or predefined functions
830 for the given algebra. So, in the case of verbatim symbols,
831 <tt class=
"docutils literal"><span class=
"pre">Algebra.convert_symbol(
<Verbatim
</span> <span class=
"pre">instance
>.data)
</span></tt> is returned. It
832 also means that
<tt class=
"docutils literal"><span class=
"pre">Algebra
</span></tt> classes must define classmethod
833 <tt class=
"docutils literal"><span class=
"pre">convert_symbol
</span></tt> that can either return a algebra symbol instance
834 <tt class=
"docutils literal"><span class=
"pre">Algebra(SYMBOL,
</span> <span class=
"pre">data)
</span></tt> or a predefined function or mathematical
836 <p>Expressions are operations with operands. Therefore, to convert
837 verbatim expression to an expression of a given algebra, the algebra
838 must have a support for the given operation. The following table
839 summarizes how algebras can support different operations.
</p>
840 <table border=
"1" class=
"docutils">
846 <tr><td>Expression head
</td>
847 <td>Support hooks in
<tt class=
"docutils literal"><span class=
"pre">Algebra
</span></tt> class
</td>
850 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.__pos__(operand)
</span></tt></td>
853 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.__neg__(operand)
</span></tt></td>
856 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Add(*operands)
</span></tt></td>
859 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Sub(*operands)
</span></tt></td>
862 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Mul(*operands)
</span></tt></td>
865 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Div(*operands)
</span></tt></td>
868 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Pow(*operands)
</span></tt></td>
871 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Mod(*operands)
</span></tt></td>
874 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Lt(*operands)
</span></tt></td>
877 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Gt(*operands)
</span></tt></td>
880 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Le(*operands)
</span></tt></td>
883 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Ge(*operands)
</span></tt></td>
886 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Eq(*operands)
</span></tt></td>
889 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Ne(*operands)
</span></tt></td>
892 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.And(*operands)
</span></tt></td>
895 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Or(*operands)
</span></tt></td>
898 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Not(*operands)
</span></tt></td>
901 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Element(*operands)
</span></tt></td>
904 <td><tt class=
"docutils literal"><span class=
"pre">Algebra.Not(Algebra.Element(*operands))
</span></tt></td>
911 <p>Note that the operands to operations of a given algebra do not always
912 belong to the same algebra. For example, the operands of
<tt class=
"docutils literal"><span class=
"pre">LT
</span></tt> can be
913 <tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt> instances but the operation result is
<tt class=
"docutils literal"><span class=
"pre">Logic
</span></tt> instance.
914 The algebras can also vary within a list of operands. For example, the
915 first operand to
<tt class=
"docutils literal"><span class=
"pre">IN
</span></tt> should be an instance of set element algebra
916 while the second operand is a
<tt class=
"docutils literal"><span class=
"pre">Set
</span></tt> instance.
917 To support all these cases, the algebra class may need to define the
918 following additional methods:
</p>
919 <ol class=
"arabic simple">
920 <li><tt class=
"docutils literal"><span class=
"pre">Algebra.get_operand_algebra(head,
</span> <span class=
"pre">index=
0)
</span></tt> - return the algebra
921 class of
<tt class=
"docutils literal"><span class=
"pre">index
</span></tt>-th operand in operation defined by
<tt class=
"docutils literal"><span class=
"pre">head
</span></tt>.
</li>
922 <li><tt class=
"docutils literal"><span class=
"pre"><Algebra
</span> <span class=
"pre">instance
>.get_element_algebra()
</span></tt> - return the element
923 algebra class. The method must be defined by
<tt class=
"docutils literal"><span class=
"pre">Set
</span></tt> and
924 <tt class=
"docutils literal"><span class=
"pre">MatrixRing
</span></tt> classes, for instance. This method is instance
925 method because the result may depend the instance content. For
926 example,
<tt class=
"docutils literal"><span class=
"pre">Set('Reals').get_element_algebra()
</span></tt> would return
927 <tt class=
"docutils literal"><span class=
"pre">Calculus
</span></tt> while
<tt class=
"docutils literal"><span class=
"pre">Set('Functions').get_element_algebra()
</span></tt>
928 should return
<tt class=
"docutils literal"><span class=
"pre">FunctionRing
</span></tt>.
</li>