# Midterm Review¶

This is a collection of practice problems for the midterm which will be held on Wednesday, October 21st during class time. The midterm will cover topics listed on the Calendar up through Numerical Integration.

Another good source of review is Homeworks 1-5.

In addition there are the course textbooks:

• 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.

The notebooks that I have been working through reference sections in these books.

### Standard imports¶

In [ ]:
import math as m
import numpy as np
import matplotlib.pyplot as plt


## 1. Volume of a Cylinder¶

Write a function cylinder_volume(r, h) which returns the volume of a cylinder of radius $r>0$ and height $h>0$.

In [ ]:



In [ ]:
# Tests that should be passed
assert abs(cylinder_volume(1, 1) - 3.141592653589793) < 10**-8
assert abs(cylinder_volume(0.5641895835477563, 5) - 5) < 10**-8
assert abs(cylinder_volume(10, 2) - 628.3185307179587) < 10**-8
assert abs(cylinder_volume(10, 10) - 3141.5926535897934) < 10**-8


## 2. Function plotting¶

Use matplotlib to plot the function $sin(\frac{1}{x})$ using $10001$ values of $x$ equally spaced in the interval $[0.00001, 1.00001]$.

In [ ]:



## 3. Evaluating a series¶

Consider the series $\sum_{k=0}^\infty x_k$ where $$x_k = \frac{(-1)^k}{1+\sqrt{k}}$$ defined for $k \geq 0$.

Find the smallest $N \geq 2$ such that $$|x_{N-2}|+|x_{N-1}|+|x_N| < \frac{1}{30 \pi}.$$ Store this value of $N$ in the variable N_stop and store the partial sum $$\sum_{k=0}^N x_k$$ in the variable partial_sum_stop.

In [ ]:



In [ ]:
assert type(N_stop) == int
assert type(partial_sum_stop) == float
assert 79000 < N_stop < 80000
assert 0.71 < partial_sum_stop < 0.72


## 4. Base 7¶

Write a function base7(n) which takes as input an integer $n > 0$ and converts it to a string storing its representation in base $7$. The returned string will consist only of the characters in the set $\{0,1,2,3,4,5,6\}$.

For example, the number $67$ in base $7$ is is given by 124 since $$67 = 1 \cdot 7^2 + 2 \cdot 7 + 4.$$ Thus base7(67) should return the string '124'.

In [ ]:



In [ ]:
# Tests
assert base7(6) == '6', 'Failed for n = 6.'
assert base7(49) == '100', 'Failed for n = 49.'
assert base7(67) == '124', 'Failed for n = 67.'
assert base7(151235) == '1166630', 'Failed for n = 151235.'
assert base7(6723477342423466) == '4062124131215314042', 'Failed for n = 6723477342423466.'


## 5. Base 7 to integer¶

Write a function base7_to_int(s) which takes as input a string s of characters in the list 0, 1, 2, 3, 4, 5, 6 and returns the integer the string represents in base $7$.

For example, base7_to_int('6124') should return 2125 because $$6 \cdot 7^3 + 1 \cdot 7^2 + 2 \cdot 7 + 4 = 2125.$$

(Hints: If a string c stores a digit, you can turn it into its integer representation with int(c).)

In [ ]:



In [ ]:
assert base7_to_int('6124') == 2125, "base7_to_int('6124') is wrong."
assert base7_to_int('6') == 6, "base7_to_int('6') is wrong."
assert base7_to_int('10') == 7, "base7_to_int('10') is wrong."
assert base7_to_int('100') == 49, "base7_to_int('10') is wrong."
assert base7_to_int('1000') == 343, "base7_to_int('10') is wrong."


## 6. ArcTan¶

Inverse tangent is an analytic function. It's Taylor series centered at the origin is given by $$\tan^{-1}(x) = x - \frac{x^3}{3} + \frac{x^5}{5} - \frac{x^7}{7} +\ldots.$$ This series converges for values of $x \in [-1,1]$.

Write a function arctan_partial_sum(x, d) which takes as input a float $x \in [-1,1]$ and an integer $d$ and returns the Taylor polynomial of degree $d$ evaluated at $x$. Use Python's built in floats to carry out the calculation.

In [ ]:



In [ ]:
assert abs(arctan_partial_sum(0.5, 0)) < 10**-8, "Error with input (0.5, 0)."
assert abs(arctan_partial_sum(0.3,1)-0.3) < 10**-8, "Error with input (0.3,1)."
assert abs(arctan_partial_sum(0.7,2)-0.7) < 10**-8, "Error with input (0.7,2)."
assert abs(arctan_partial_sum(0.5,10)-0.46368427579365) < 10**-8, \
"Error with input (0.5,10)."
assert abs(arctan_partial_sum(1,100) - 0.7803986631477527) < 10**-8, \
"Error with input (1,100)."


## 7. ArcTan continued¶

The usual form for the remainder in the Taylor series is not immediately useful, since it requires us to control high order derivatives of $\tan^{-1}$.

However, observe that the degree $d$ term of the Taylor series for $\tan^{-1}$ has absolute value less than $|x|^d$. Thus the remainder $R_d(x)-\tan^{-1}(x)$ satisfies $$-\sum_{k=d+1}^\infty |x|^k < R_d(x) < \sum_{k=d+1}^\infty |x|^k.$$ Observe that $\sum_{k=d+1}^\infty |x|^k$ is a geometric series and can be evaluated by a standard formula.

Write a function arc_tan_degree(x, epsilon) which takes as input an $x \in (-1,1)$ and an $\epsilon>0$ and returns an integer $d$ such that $|R_d(x)|<\epsilon$.

Use your function to compute $\tan^{-1}(\frac{1}{2})$ correct to $8$-significant digits. Store the result as a float in the variable arc_tan_half.

You can use floats and ignore the effects of round off error.

**Remark:** This problem would be too hard and time consuming for a test, but it is still good practice.

In [ ]:



In [ ]:
assert abs(arc_tan_half - m.atan(0.5)) < 10**-8
assert arc_tan_degree(0.25, 100) == 0
assert abs(arctan_partial_sum(0.25, arc_tan_degree(0.25, 0.5*10**-4)) - m.atan(0.25)) < 10**-4
assert abs(arctan_partial_sum(0.75, arc_tan_degree(0.75, 0.5*10**-6)) - m.atan(0.75)) < 10**-6


## 8. Fibonacci list¶

The Fibonacci numbers are defined inductively by $F_0=1$, $F_1=1$ and $$F_{n+1}=F_n + F_{n-1} \quad \text{for all n \geq 1.}$$ The first few values are printed below: $$F_0 = 1,~F_1 = 1,~F_2 = 2,~F_3 = 3,~F_4 = 5,~F_5 = 8,~F_6 = 13,~F_7 = 21,~F_8 = 34,~F_9 = 55.$$

Write a function fibonacci_list(n) which returns a list consisting of the first $n$ Fibonacci numbers. Here $n$ should be an non-negative integer.

In [ ]:



In [ ]:
assert fibonacci_list(10) == [1, 1, 2, 3, 5, 8, 13, 21, 34, 55], \
'fibonacci_list(10) is incorrect'
for n in range(10):
assert len(fibonacci_list(n)) == n, \
f'The length of fibonacci_list({n}) is incorrect'


## 9. Fibonacci induction¶

Inductively prove that if $n \geq 7$, then $F_n > 1.5^n$.

Hint: Show by computation that $F_7 > 1.5^7$ and $F_8 > 1.5^8$. Argue that if $F_n > 1.5^n$ and $F_{n-1} > 1.5^{n-1}$, then $F_{n+1} > 1.5^{n+1}$ using the fact that $F_{n+1}=F_n+F_{n-1}$.

In [ ]:



## 10. Power inequality¶

Prove that $7^n - 5^n > 6^n$ for integers $n \geq 3$.

Remarks: The base case can be confirmed by computation. Include your proof in a Markdown cell in the notebook. (Including a picture of your hand-written proof is okay. You should be able to insert an image in Jupyter by clicking Edit > Insert Image.)

In [ ]:



## 11. Derivative with currying¶

Write a funtion derivative(f, h) which takes as input:

• A function f(x), which takes as input a floating point real number and produces a floating point real number as its output.
• A float $h>0$.

The derivative function should return a new function df(x). The function df(x) should take as input a floating point real number x and return the symmetric two-point approximation of the derivative of $f$ at $x$ using points at distance $h$ from $x$.

The derivative function should make use of currying.

In [ ]:



In [ ]:
# Test
f = lambda x: np.sin(x)
df = derivative(f, 10**-8)
for x in np.linspace(0, 3, 201):
assert abs( df(x) - np.cos(x) ) < 10**-8, \
"The value df({:0.2f}) is incorrect.".format(x)


## 12. Speed of a crash¶

A malfunctioning drone crashes destroying itself. The list altitude_list below contains pairs consisting of a time (in seconds) and a measurement of the drone's altitude (in meters). The drone crashes shortly after the $5$ second mark.

• Approximately fast was the drone falling when it crashed into the ground? Store the answer (which would be in meters per second) in the variable crash_speed.

• Before the drone crashed, it accellerated upward for some unknown reason. What was the fastest speed it was moving upward over the provided time interval? At approximately what time was it moving at that speed? Store the respective answers in up_speed and up_time.

In [2]:
altitude_list = [(0.0, 2.0438), (0.1, 2.1013), (0.2, 2.1577), (0.3, 2.2136), (0.4, 2.2699),
(0.5, 2.3271), (0.6, 2.3859), (0.7, 2.4472), (0.8, 2.5117), (0.9, 2.5799),
(1.0, 2.6528), (1.1, 2.7311), (1.2, 2.8154), (1.3, 2.9066), (1.4, 3.0053),
(1.5, 3.1123), (1.6, 3.2281), (1.7, 3.3535), (1.8, 3.4888), (1.9, 3.6347),
(2.0, 3.7915), (2.1, 3.9593), (2.2, 4.1384), (2.3, 4.3285), (2.4, 4.5294),
(2.5, 4.7406), (2.6, 4.9613), (2.7, 5.1904), (2.8, 5.4263), (2.9, 5.6672),
(3.0, 5.9109), (3.1, 6.1543), (3.2, 6.3941), (3.3, 6.6263), (3.4, 6.8462),
(3.5, 7.048), (3.6, 7.2256), (3.7, 7.3716), (3.8, 7.4775), (3.9, 7.5341),
(4.0, 7.5307), (4.1, 7.4553), (4.2, 7.2945), (4.3, 7.0336), (4.4, 6.656),
(4.5, 6.1436), (4.6, 5.4763), (4.7, 4.6323), (4.8, 3.5874), (4.9, 2.3156),
(5.0, 0.7886)]

In [ ]:



In [ ]:
# Test
f = lambda x: np.sin(x)
df = derivative(f, 10**-8)
for x in np.linspace(0, 3, 201):
assert abs( df(x) - np.cos(x) ) < 10**-8, \
"The value df({:0.2f}) is incorrect.".format(x)


## 13. Implementing a quadrature rule¶

This problem concerns the following quadrature rule, defined for any interval $[a, b]$: $$Q_{[a,b]}(f) = (b-a) \left(\frac{1}{4} f\left(\frac{2a+b}{3}\right) + \frac{1}{2} f\left(\frac{a+b}{2}\right) + \frac{1}{4} f\left(\frac{a+2b}{3}\right)\right).$$

• Define a function q(a , b, f) which takes as input floating point real numbers $a$ and $b$ with $a<b$ and a function f representing a real-valued function $f:{\mathbb R} \to {\mathbb R}$. The function should return $Q_{[a,b]}(f)$.

• What is the degree of of precision of $Q_{[a,b]}$? Store the answer in the variable q_degree.

In [ ]:



This problem continues the last one, where we defined q(f, a, b) to represent $Q_{[a,b]}(f)$.
Write a function q_compound(n, f) which takes as input a positive integer $n$ and a function $f$ as above. The function should divide the interval $[0,1]$ into $n$ equal sized subintervals. It should return the sum of $Q_{\ast}(f)$ where $\ast$ varies over the $n$ subintervals.
Test that q_compound is reasonable by comparing the approximate integral with the actual integral for some nice function on $[0, 1]$.