Lab Sheet 07: Symbolic Calculus
In this lab sheet we will see how to carry out basic aspects of Calculus (limits, differentiation and integration) with Python.
Building blocks

Calculating limits.
A video describing the concept.
It is possible to calculate limits easily with SymPy. Let us consider the following function as a running example:
First let us define this function in Python as a function:
>>> import sympy as sym >>> def f(x): ... return 1 / x >>> f(2) 0.5
We can now pass it symbolic variable:
>>> x = sym.symbols('x') >>> f(x) 1/x
We can compute the limits at \(\pm\infty\):
>>> sym.limit(f(x), x, sym.oo) 0 >>> sym.limit(f(x), x, sym.oo) 0 >>> sym.limit(f(x), x, +sym.oo) 0
We can also compute the limit at \(0\) however we must be careful here (you will recall from basic calculus that the limit depends on the direction):
>>> sym.limit(f(x), x, 0) # The default direction of approach is positive. oo >>> sym.limit(f(x), x, 0, dir="+") oo >>> sym.limit(f(x), x, 0, dir="") oo
Experiment with caculating the limit of different functions.

Differentiation.
A video describing the concept.
We can use SymPy to carry out differentiation:
>>> sym.diff(f(x), x) 1/x**2 >>> sym.diff(sym.cos(x), x) sin(x)
We can carry out various orders of differentiation. These all give the second order derivative of \(\cos(x)\):
>>> sym.diff(sym.diff(sym.cos(x), x), x) cos(x) >>> sym.diff(sym.cos(x), x, x) cos(x) >>> sym.diff(sym.cos(x), x, 2) cos(x)
SymPy can handle differentiation of functions with multiple variables (you will learn more about this in further Calculus):
>>> y = sym.symbols('y') >>> sym.diff(sym.cos(x) * sym.sin(y), x) # Differentiating with respect to x sin(x)*sin(y) >>> sym.diff(sym.cos(x) * sym.sin(y), y) # Differentiating with respect to y cos(x)*cos(y)
Finally it is also possible for SymPy to differentiate hypothetical functions (ones that we do not know anything about):
>>> g = sym.Function('g') # We create g as a generic function >>> sym.diff(g(x), x, 2) Derivative(g(x), x, x)
Try and experiment with differentiating more complicated functions.

Integration.
A video describing the concept.
As well as differentiation it is possible to carry out integration.
We can do both definite and indefinite integrals:
>>> sym.integrate(f(x), x) # An indefinite integral log(x) >>> sym.integrate(f(x), (x, sym.exp(1), sym.exp(5))) # A definite integral 4
We can use this to verify the fundamental theorem of calculus for the specific example of our function \(f\):
>>> sym.integrate(sym.diff(f(x), x), x) 1/x
We can also verify this for generic functions:
>>> g = sym.Function('g') >>> sym.integrate(sym.diff(g(x), x), x) == g(x) True >>> sym.diff(sym.integrate(g(x), x), x) == g(x) True
Experiment with integrating other functions.

Plotting. It is possible to use SymPy to create plots.
A video describing the concept.
To view these in jupyter we need to run this line:
%matplotlib inline
We can then create plots using the
plot
command:>>> sym.plot(f(x), (x, 1, 1)) <...
Thatâ€™s not very clear, let us modify the limits on the y axis.
>>> sym.plot(f(x), (x, 1, 1), ylim=(10, 10)) <...
We can also choose to modify the labels on the axes:
>>> sym.plot(f(x), (x, 1, 1), ylim=(10, 10), xlabel=None, ylabel="$1/x$") <...
Finally we can also combine various plots of different functions together. To do this we build each plot separately (telling Python not to
show
them) and then combine them:>>> p1 = sym.plot(f(x), (x, 1, 1), show=False) >>> p2 = sym.plot(x, (x, 1, 1), show=False, line_color="red") >>> p1.extend(p2) >>> p1.ylim = (10, 10) >>> p1.xlabel = None # Try using strings here >>> p1.ylabel = None >>> p1.show()
It is also possible to save a file of the graph. Depending on how you name the file the type of tile will be different:
>>> p1.save("my_plot.pdf") # Try `.png` etc...
Attempt to create plots of other functions.

Worked example
A video describing the concept.
We are going to use the above to attempt to find and classify all points of inflection for the following quartic function:
First let us take a look at the function:
>>> def f(x): ... return x ** 4 + 9 * x ** 2 + 4 * x  12 >>> sym.plot(f(x), (x, 20, 20) , ylim=(20, 20)) <...
Let us find the roots of the functions:
>>> sym.solveset(f(x), x) {2, 1, 3}
We have a quatric so one of those roots (of which there are only 3) must be repeated, let us see if we can factor our function:
>>> f(x).factor() (x  3)*(x  1)*(x + 2)**2
We see that (2) is a repeated root.
Let us confirm the limiting behaviour of our function:
>>> sym.limit(f(x), x, sym.oo) oo >>> sym.limit(f(x), x, sym.oo) oo
Finally, we also see that there are 3 points of inflection so let us find them:
>>> poi = sym.solveset(sym.diff(f(x), x), x) >>> poi {2, 1 + sqrt(6)/2, sqrt(6)/2 + 1}
Let us now evaluate which of these gives a positive or negative value of the second derivative:
>>> for point in list(poi): # We convert the poi to a list ... print(point, (sym.diff(f(x), x, 2).subs({x: point})) > 0) 2 False 1 + sqrt(6)/2 False sqrt(6)/2 + 1 True
We see that 2 points of inflection give negative second derivative (so they are local maxima), whereas \(\sqrt{6}/2+1\) is a local minimum. This confirms the plot.
Further work
These questions aim to push a bit further.

Consider the function below:
Identify the roots and limits (at \(\pm\infty\)) of the function and confirm this with a plot.

For the function of question 6, identify and classify all points of inflection.

(Optional) There are various algebraic relationships on limits:
Confirm these for the following particular examples:

(Optional) The point of this question is to investigate the definition of a derivative:
 Consider \(f(x) = x^3 + 3x  20\);
 Compute \(\frac{f(x+h)f(x)}{h}\);
 Compute the above limit as \(h\to 0\) and verify that this is the derivative of \(f\).