import math
math.sqrt(3)
1.7320508075688772
math.sqrt(8)
2.8284271247461903
$\sqrt(8) = 2\sqrt(2)$, but it's hard to see that here
import sympy
sympy.sqrt(3)
SymPy can even simplify symbolic computations
sympy.sqrt(8)
from sympy import symbols
x, y = symbols('x y')
expr = x + 2*y
expr
Note that simply adding two symbols creates an expression. Now let's play around with it.
expr + 1
expr - x
Note that expr - x
was not x + 2y -x
x*expr
from sympy import expand, factor
expanded_expr = expand(x*expr)
expanded_expr
factor(expanded_expr)
from sympy import diff, sin, exp
diff(sin(x)*exp(x), x)
from sympy import limit
limit(sin(x)/x, x, 0)
Solve $x^2 - 2 = 0$ using sympy.solve
# Type solution here
from sympy import solve
from sympy import init_printing, Integral, sqrt
init_printing(use_latex='mathjax')
Integral(sqrt(1/x), x)
from sympy import latex
latex(Integral(sqrt(1/x), x))
'\\int \\sqrt{\\frac{1}{x}}\\, dx'
More symbols. Exercise: fix the following piece of code
# NBVAL_SKIP
# The following piece of code is supposed to fail as it is
# The exercise is to fix the code
expr2 = x + 2*y +3*z
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-18-88f4dc46acc5> in <module> ----> 1 expr2 = x + 2*y +3*z NameError: name 'z' is not defined
Solve $x + 2*y + 3*z$ for $x$
# Solution here
from sympy import solve
Difference between symbol name and python variable name
x, y = symbols("y z")
x
y
# NBVAL_SKIP
# The following code will error until the code in cell 16 above is
# fixed
z
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-23-3a710d2a84f8> in <module> ----> 1 z NameError: name 'z' is not defined
Symbol names can be more than one character long
crazy = symbols('unrelated')
crazy + 1
x = symbols("x")
expr = x + 1
x = 2
What happens when I print expr now? Does it print 3?
print(expr)
x + 1
How do we get 3?
x = symbols("x")
expr = x + 1
expr.subs(x, 2)
x + 1 == 4
False
from sympy import Eq
Eq(x + 1, 4)
Suppose we want to ask whether $(x + 1)^2 = x^2 + 2x + 1$
(x + 1)**2 == x**2 + 2*x + 1
False
from sympy import simplify
a = (x + 1)**2
b = x**2 + 2*x + 1
simplify(a-b)
Write a function that takes two expressions as input, and returns a tuple of two booleans. The first if they are equal symbolically, and the second if they are equal mathematically.
z = symbols("z")
expr = x**3 + 4*x*y - z
expr.subs([(x, 2), (y, 4), (z, 0)])
from sympy import sympify
str_expr = "x**2 + 3*x - 1/2"
expr = sympify(str_expr)
expr
expr.subs(x, 2)
expr = sqrt(8)
expr
expr.evalf()
from sympy import pi
pi.evalf(100)
from sympy import cos
expr = cos(2*x)
expr.evalf(subs={x: 2.4})
from IPython.core.display import Image
Image(filename='figures/comic.png')
Write a function that takes a symbolic expression (like pi), and determines the first place where 789 appears. Tip: Use the string representation of the number. Python starts counting at 0, but the decimal point offsets this
from sympy import Function
f, g = symbols('f g', cls=Function)
f(x)
f(x).diff()
diffeq = Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sin(x))
diffeq
from sympy import dsolve
dsolve(diffeq, f(x))
f = Function('f')
dfdx = f(x).diff(x)
dfdx.as_finite_difference()
from sympy import Symbol
d2fdx2 = f(x).diff(x, 2)
h = Symbol('h')
d2fdx2.as_finite_difference(h)
Now that we have seen some relevant features of vanilla SymPy, let's move on to Devito, which could be seen as SymPy finite differences on steroids!