Symolic Computation playground!¶
This is a playgrond area for learning and trying out stuffs of symbolic computation via sympy
for Vitor.
The try out here is based on Sympy
toturial: an introduction to SymPy for someone who has not used the library before.
Introductory (What is Symbolic Computation?)¶
manipulate irrational numbers¶
perfect square: precise result
import math
math.sqrt(9)
3.0
non-perfect square: approximation result
math.sqrt(8)
2.8284271247461903
The way it does in sympy
: square roots of numbers that are not perfect squares are left unevaluated by default.
import sympy
sympy.sqrt(3)
And symbolic results can be symbolically simplified!
sympy.sqrt(8)
A More Interesting Example: computing symbolic expressions with variables¶
Symbolic computation systems (often called computer algebra systems, or just CASs) such as SymPy are capable of computing symbolic expressions with variables.
x, y = symbols('x y')
try:
expr1 = x + 2y # not like this!
except error:
print("SyntaxError: invalid decimal literal")
Cell In[5], line 3
expr1 = x + 2y # not like this!
^
SyntaxError: invalid decimal literal
For example, the way in sympy
to define $x+2y$
from sympy import symbols
x, y = symbols('x y')
expr = x + 2*y
expr
Play around now!
simplification automatically
expr + 1
expr - x
Notice: factor form
x*expr
What if we want expanded form? use expand
from sympy import expand, factor
expanded_expr = expand(x*expr)
expanded_expr
The other way around? To factor the expaned form:
factor(expanded_expr)
The Real Power of Symbolic Computation !?¶
The real power of a symbolic computation system such as SymPy is the ability to do all sorts of computations symbolically.
“Symbolically”… What does it imply actually?
We will see some more examples!
from sympy import *
x, t, z, nu = symbols('x t z nu')
x
t
z
nu
# init_printing(pretty_print=False,use_unicode=True)
diff(sin(x)*exp(x), x)
integrate(exp(x)*sin(x) + exp(x)*cos(x), x)
integrate(sin(x**2), (x, -oo, oo))
limit(sin(x)/x, x, 0)
solve(x**2 - 2, x)
[-sqrt(2), sqrt(2)]
y = Function('y')
dsolve(Eq(y(t).diff(t, t) - y(t), exp(t)), y(t))
Matrix([[1, 2], [2, 2]]).eigenvals()
{3/2 - sqrt(17)/2: 1, 3/2 + sqrt(17)/2: 1}
besselj(nu, z).rewrite(jn)
latex(Integral(cos(x)**2, (x, 0, pi)))
'\\int\\limits_{0}^{\\pi} \\cos^{2}{\\left(x \\right)}\\, dx'
Why two “ \ “ above???
print("\\pi")
\pi
print("\pi")
\pi
Conclusion: needed to change \\
to \
manually… For a direct copy-paste into a Markdown cell without manual intervention, unfortunately, there’s no automatic way to convert the double backslashes to single backslashes due to the escape character behavior in Python strings and the different contexts in which the LaTeX is rendered (Python string vs. Markdown).
Consider to create a python function to achieve it!
$\int\limits_{0}^{\pi} \cos^{2}{\left(x \right)}\, dx$
import re
def convert_latex_for_markdown(latex_str):
return re.sub(r'\\\\', r'\\', latex_str)
print(convert_latex_for_markdown(latex(Integral(cos(x)**2, (x, 0, pi)))))
\int\limits_{0}^{\pi} \cos^{2}{\left(x \right)}\, dx
$\int\limits_{0}^{\pi} \cos^{2}{\left(x \right)}, dx$
Gotchas (Working with symbolic expressions in Python)¶
Symbols¶
from sympy import *
x + 1
If we run in python and not in jupter notebook, it would gives error:
Traceback (most recent call last):
File “
NameError: name ‘x’ is not defined
Naming of symbols!
x = symbols('x')
x + 1
x, y, z = symbols('x y z')
a, b = symbols('b a')
a
b
crazy = symbols('unrelated')
crazy + 1
“Symbol”: Sympy
symbol
“Variable”: Python
variable
x = symbols('x')
expr = x + 1
x = 2
print(expr)
x + 1
python
variable changed. But not sympy
symbol.
x = 'abc'
expr = x + 'def'
expr
'abcdef'
x = 'ABC'
expr
'abcdef'
To change the value of a Symbol in an expression, use subs
:
x = symbols('x')
expr = x + 1
expr.subs(x, 2)
Equal signs¶
x + 1 == 4
False
Eq(x + 1, 4)
(x + 1)**2 == x**2 + 2*x + 1
False
“==” only equals in “exact structure! It is for structural equality.
Not for symbolic equality and mathematical equality.
recall that if $a = b$, then $a - b = 0$
If two symbolic expressions are identically equal.
simplify
a = (x + 1)**2
b = x**2 + 2*x + 1
simplify(a - b)
c = x**2 - 2*x + 1
simplify(a - c)
equals
: evaluating them numerically at random points.
a = cos(x)**2 - sin(x)**2
b = cos(2*x)
a.equals(b)
True
^ and /¶
^ represent logical exclusive OR, XOR in Python
True ^ False
True
True ^ True
False
False ^ False
False
Xor(x, y)
Sympy
objects and Python
objects
type(Integer(1) + 1)
sympy.core.numbers.Integer
type(1 + 1)
int
Division in sympy
gives rational
Integer(1)/Integer(3)
type(Integer(1)/Integer(3))
sympy.core.numbers.Rational
from __future__ import division
1/2
0.5
Rational(1, 2)
x + 1/2
x + Rational(1, 2)
Lambdify (Lambdification to numerical functions)¶
forwards
import numpy
a = numpy.arange(10)
expr = sin(x)
f = lambdify(x, expr, "numpy")
f(a)
array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ,
-0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])
f = lambdify(x, expr, "math")
f(0.1)
0.09983341664682815
def mysin(x):
"""
My sine. Note that this is only accurate for small x.
"""
return x
f = lambdify(x, cos(x)*sin(x), {"sin":mysin,"cos":mysin})
f(0.1)
0.010000000000000002
0.1+0.2
0.30000000000000004
import inspect
print(inspect.getsource(f))
def _lambdifygenerated(x):
return sin(x)*cos(x)
sympy.print_tree(expr)
sin: sin(x)
commutative: True
+-Symbol: x
commutative: True
f(0.5)
0.25
sin(0.5)
type(sympy.sin)
sympy.core.function.FunctionClass
type(sin)
sympy.core.function.FunctionClass
This module provides convenient functions to transform SymPy expressions to lambda functions which can be used to calculate numerical values very fast.
from sympy.abc import x
from sympy.utilities.lambdify import implemented_function
from sympy import lambdify
f = implemented_function('f', lambda x: x+1)
lam_f = lambdify(x, f(x))
lam_f(4)
5
from sympy.abc import x, y, z
from sympy.utilities.lambdify import lambdastr
lambdastr(x, x**2)
lambdastr((x,y,z), [z,y,x])
'lambda x,y,z: ([z, y, x])'
lambdastr((x, (y, z)), x + y)
'lambda _0,_1: (lambda x,y,z: (x + y))(_0,_1[0],_1[1])'
Codegen (Code generation: the principle behind lambdification)¶
See here.