# Homework 4¶

Directions: Add work to this notebook to solve the problems below.

Be careful to name the objects you create as described in the problem. Some problems may include some tests you can run to test your code.

Before you submit your work, make sure it runs correctly without errors. Click “Kernel > Restart & Run All” to restart and run everything.

Some problems are derived from problems in these books:

• LL: Programming for Computations - Python by Svein Linge and Hans Petter Langtangen, 2nd edition.
• L: A Primer on Scientific Programming with Python by Hans Petter Langtangen, 2nd edition.
• TAK: Applied Scientific Computing With Python by Peter R. Turner, Thomas Arildsen, and Kathleen Kavanagh.

### Standard imports¶

In [ ]:
import math as m


## 1. cosh x¶

The function $cosh(x) = \frac{e^x + e^{-x}}{2}$ is analytic with Taylor series $$\cosh x = 1 + \frac{x^2}{2!} + \frac{x^4}{4!} + \ldots = \sum_{k=0}^\infty \frac{x^{2k}}{(2k)!}$$ What degree Taylor polynomial is needed to estimate $\cosh(1/2)$ with a truncation error less than $\epsilon>0$? Use Taylor's Theorem to figure this out how to decide this. Write a function cosh_half_degree(epsilon) that returns this degree. Write a second function cosh_half(epsilon) that returns the value of the degree $d$ Taylor polynomial evaluated at $\frac{1}{2}$, where $d$ is the value returned by cosh_half_degree(epsilon).

Check that your answer achieves the desired accuracy with $\epsilon=10^{-8}$ by comparing your answer to the value of $cosh(\frac{1}{2})$ returned by the cosh function in the math library (i.e., m.cosh(0.5)).

(This is similar to Problem 5 from Chapter 2 of TAK.)

In [ ]:



In [ ]:
assert type(cosh_half_degree(0.1)) == int, "cosh_half_degree should return an integer."
assert type(cosh_half(0.5)) == float, "cosh_half should return a float."


## 2. Taylor Polynomials for the exponential function¶

Write a function exp_poly which takes as input a degree $d$ and returns a function that evaluates the Taylor polynomial of degree $d$ for the exponential function centered at zero. (You should use closures as described in the Plotting Graphs notebook.)

(Hint: You are asked to do something similar to the sin_polynomial function in the Taylor Series notebook.)

In [ ]:



In [ ]:
# Define $p$ to be the Taylor polynomial of degree 1:
p = exp_poly(1)
# Note that the Taylor polynomial should be p(x)=x+1
assert p(5.5)==6.5, "Unexpected result!"


## 3. Taylor's remainder formula¶

Let $f:{\mathbb R} \to {\mathbb R}$ be a infinitely differentiable function with the property that the derivative of any order $n \geq 1$ satisfies $-1 \leq f^{(n)}(x) \leq 1$ for each $x \in {\mathbb R}$. We will consider the Taylor series of $f$ centered at zero. Let $P_d(x)$ be the degree $d$ Taylor polynomial centered at zero.

By Taylor's theorem, the remainder, $R_d(x) = f(x) - P_d(x),$ always has the form $$R_d(x)=\frac{f^{(d+1)}(y)}{(d+1)!} x^{d+1},$$ for some $y$ between $0$ and $x$.

Using the information above, write a function minimal_degree(x, epsilon) which takes as input a float $x$ and a float $\epsilon>0$ and returns the smallest $d$ for which it can be guaranteed that $$|R_d(x)|<\epsilon.$$

In [ ]:



In [ ]:
# We test some cases with x=2:
assert minimal_degree(2, 3) == 0, \
"Wrong answer when x=2 and epsilon=3"
assert minimal_degree(2, 1.5) == 2, \
"Wrong answer when x=2 and epsilon=1.5"
assert minimal_degree(2, 1) == 3, \
"Wrong answer when x=2 and epsilon=1"
assert minimal_degree(2, 0.5) == 4, \
"Wrong answer when x=2 and epsilon=0.5"


## 4. Comparing approximations for the derivative¶

Consider the approximation $$f'(x_0)\approx \frac{f(x_0+h) - f(x_0)}{h}$$ for the case of $f(x)=\ln x$ at the point $x_0=1$. Compute the approximation with $h=10^{-k}$ for $k \in \{1,\ldots, 10\}$. Store the results in a list approx1. (So, approx1[3] should be the computation with $h=10^{-4}$.)

Do the same for the approximation $$f'(x_0)\approx \frac{f(x_0+h) - f(x_0-h)}{2h},$$ storing the result in approx2.

The absolute error is the difference of an approximation from the actual value. Store the list of errors in the first case in error1 and the list of errors in the second case in error2.

Discuss based on your computations what the best approximation is, and what the best choice of $h$ seems to be.

(This problem was based on Problems 1 and 4 from TAK § 3.2)

In [ ]:



In [ ]:
assert type(approx1)==list, "Error: approx1 should be a list."
assert len(approx1)==10, "Error: approx1 should have 10 elements."
assert type(approx2)==list, "Error: approx2 should be a list."
assert len(approx2)==10, "Error: approx2 should have 10 elements."
assert type(error1)==list, "Error: error1 should be a list."
assert len(error1)==10, "Error: error1 should have 10 elements."
assert type(error2)==list, "Error: error2 should be a list."
assert len(error2)==10, "Error: error2 should have 10 elements."
assert abs(approx1[0] - m.log(1.1)/0.1) < 10**-8, "approx1[0] is incorrect."


## 5. Comparing formulas for the second derivative¶

Repeat the previous exercise (Comparing approximations for the derivative), this time comparing approximations for the second derivative. For approx3 use $$f''(x_0) \approx \frac{f(x_0+h) - 2 f(x_0) + f(x_0-h)}{h^2}.$$ for approx4 use $$f''(x_0) \approx \frac{-f(x_0+2h) + 16 f(x_0+h) - 30 f(x_0) + 16 f(x_0-h) - f(x_0-2h)}{12 h^2}.$$

Use the same function $f(x)=\ln x$ at the point $x_0=1$ and same values of $h$ as before. Also compute the corresponding lists of errors error3 and error4.

Explain which approximation is better and what the best choice of $h$ is.

In [ ]:



In [ ]:
# Tests:
assert type(approx3)==list, "Error: approx1 should be a list."
assert len(approx3)==10, "Error: approx1 should have 10 elements."
assert type(approx4)==list, "Error: approx2 should be a list."
assert len(approx4)==10, "Error: approx2 should have 10 elements."
assert type(error3)==list, "Error: error1 should be a list."
assert len(error3)==10, "Error: error1 should have 10 elements."
assert type(error4)==list, "Error: error2 should be a list."
assert len(error4)==10, "Error: error2 should have 10 elements."
assert abs(approx3[0] - -1.0050335853501344) < 10**-8, "approx1[0] is incorrect."


## 6. Tracking a drone¶

The time_position list below contains pairs $(t, p)$ consisting of the the time $t$ (in seconds) and position $p$ (in meters) of a drone. (The drone is moving within a line.) Estimate its signed velocity and acceleration for times $t \in \{2,4,6,8,10\}$. Place the pairs $(t,v)$ where $v$ is the estimated velocity in order in a list velocity. Similarly, place the pairs $(t,a)$ where $a$ is the estimated acceleration in a list acceleration.

(This is Problem 8 from TAK § 3.2.)

In [1]:
time_position = [(0,0.7),(2,1.9),(4,3.7),(6,5.3),(8,6.3), \
(10,7.4),(12,8.0)]
for t,pos in time_position:
print("At {} seconds, the drone is at position {} meters." \
.format(t,pos))

At 0 seconds, the drone is at position 0.7 meters.
At 2 seconds, the drone is at position 1.9 meters.
At 4 seconds, the drone is at position 3.7 meters.
At 6 seconds, the drone is at position 5.3 meters.
At 8 seconds, the drone is at position 6.3 meters.
At 10 seconds, the drone is at position 7.4 meters.
At 12 seconds, the drone is at position 8.0 meters.

In [ ]:



In [ ]:
# For printing out your answers:
for t,v in velocity:
print("At {} seconds, the drone's velocity is approximately {:.3f} m/s." \
.format(t,v))
for t,a in acceleration:
print("At {} seconds, the drone's acceleration is approximately {:.3f} m/s^2." \
.format(t,a))

In [ ]:
# Tests
assert type(velocity)==list, "Error: velocity should be a list."
assert len(velocity)==5, "Error: velocity should have 5 elements."
assert len(velocity[0])==2, "Error: each member of velocity should be a pair."
assert type(acceleration)==list, "Error: acceleration should be a list."
assert len(acceleration)==5, "Error: acceleration should have 5 elements."
assert len(acceleration[0])==2, "Error: each member of acceleration should be a pair."