lab9¶
For the find_cross
exercise, please copy the source code of functions f1
and f2
from
lab7 into your lab9.py
file and re-used them here.
make_multiplier(factor)
¶
Write a function make_multiplier(factor)
that returns a function
which takes an argument x
and which should return factor * x
.
Examples
In [ ]: g = make_multiplier(10)
In [ ]: g(1)
Out[ ]: 10
In [ ]: g(2)
Out[ ]: 20
In [ ]: g = make_multiplier(0.5)
In [ ]: g(10)
Out[ ]: 5.0
In [ ]: g(100)
Out[ ]: 50.0
newton(f, x, feps, maxit)
¶
Implement a function newton(f, x, feps, maxit)
which takes a
function f(x)
and an initial guess x
for the root of the
function f(x)
, an allowed tolerance feps
and the maximum number
of iterations that are allowed maxit
. The newton
function should
use the following Newton-Raphson algorithm (here in pseudo code):
while |f(x)| > feps, do
x = x - f(x) / fprime(x)
where fprime(x)
is an approximation of the first derivative
\(\frac{\mathrm{d}f}{\mathrm{d}x}(x)\) at position \(x\).
You should use the derivative function derivative
that you have
implemented before to compute fprime(x)
.
If maxit
or fewer iterations are necessary for |f(x)|
to become
smaller than feps
, then the value for x
should be returned:
In [ ]: def f(x):
....: return x ** 2 - 2
....:
In [ ]: newton(f, 1.0, 0.2, 15)
Out[ ]: 1.4166666666783148
In [ ]: newton(f, 1.0, 0.2, 15) - math.sqrt(2)
Out[ ]: 0.002453104305219611
In [ ]: newton(f, 1.0, 0.001, 15)
Out[ ]: 1.4142156862748523
In [ ]: newton(f, 1.0, 0.001, 15) - math.sqrt(2)
Out[ ]: 2.1239017571339502e-06
In [ ]: newton(f, 1.0, 0.000001, 15) - math.sqrt(2)
Out[ ]: 1.5949463971764999e-12
If more than maxit
iterations are necessary for the function
newton
, then the newton
function should raise the
RuntimeError
exception with the message:
Failed after X iterations
where X
is to be replaced with the
number of iterations:
In [23]: def g(x):
....: return math.sin(x) + 1.1 # has no root!
....:
In [24]: newton(g, 1.0, 0.02, 15)
Traceback (most recent call last):
File "<ipython-input-6-0a9db3f67256>", line 1, in <module>
newton(g, 1.0, 0.02, 15)
File "..lab7.py", line 16, in newton
raise RuntimeError(f"Failed after {maxit} iterations")
RuntimeError: Failed after 15 iterations
The relevant line of Python to be executed if the number of maxit
iterations is reached, is
raise RuntimeError(f"Failed after {maxit} iterations")
Hint
Python provides a while
loop that can be used in the implementation. Here is
an example:
In [ ]: import time
In [ ]: a = 10
In [ ]: while a > 0:
...: print(f"Countdown: a={a}")
...: time.sleep(1) # wait for 1 second
...: a = a - 1
...: print("Done")
find_cross()
¶
Write a function find_cross()
which uses scipy.optimize.brentq
to find the value \(x\) (numerically) for which
\(f_1(x) = \cos(2 \pi x)\exp(-x^2)\) and
\(f_2(x) = \log(x + 2.1)\) have the same value. We are only
interested in the solution where \(x > 0\). You can and should make
use of your knowledge about the approximate value of \(x\) from the
my_plot
exercise.
Your function find_cross()
should return the approximation of the
root that scipy.optimize.brentq
returns (the default tolerance
settings are okay).
Please submit your file lab9.py
for this assignment.
Additional (voluntary) tasks are available in lab9-extra.
End of lab9.