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.