lab8

In this laboratory, we practice working with mathematical functions of the type $y=f(x)$ implemented as python functions, and ways to analyse them. This includes computing function values y for arguments x (create_plot_data), plotting of the function (myplot), finding a value $x$ for which two functions $f_1(x)$ and $f_2(x)$ have the same value (find_cross). The reverse_dic task exercises working with dictionaries.

f1(x)

Write a function f1(x) which accepts a number x as input and computes and returns

\[f_1(x) = \cos(2\pi x)\exp(-x^2)\]

.


f2(x)

Write a function f2(x) which accepts the number x as input and computes and returns

\[f_2(x) = \log(x + 2.1)\]

where \(\log()\) refers to the natural logarithm (the Python function name is math.log).


create_plot_data(f, xmin, xmax, n)

Implement a function create_plot_data(f, xmin, xmax, n) which returns a tuple (xs, ys) where xs and ys are two sequences, each containing n numbers:

\[\mathtt{xs} = [x_0, x_1, \ldots, x_{n-1}] \qquad \mathrm{with} \qquad x_i = x_\mathrm{min} + (x_\mathrm{max} - x_\mathrm{min})\frac{i}{n - 1}\]

and

\[\mathtt{ys}=[f(x_0), f(x_1), \ldots, f(x_{n-1})\]

The function is expected to work for any \(n \ge 2\).

Examples (here the tuple of returned sequences is a tuple of lists):

In [ ]: def f(x):
...:     return x * 10
...:

In [ ]: create_plot_data(f, -1, 1, 2)
Out[ ]: ([-1.0, 1.0], [-10.0, 10.0])

In [ ]: create_plot_data(f, 0, 2, 5)
Out[ ]: ([0.0, 0.5, 1.0, 1.5, 2.0], [0.0, 5.0, 10.0, 15.0, 20.0])


In [ ]: def f(x):
...:     return 0
...:

In [ ]: create_plot_data(f, 0, 1.5, 4)
Out[ ]: ([0.0, 0.5, 1.0, 1.5], [0, 0, 0, 0])

myplot()

  • Implement a function myplot() that computes $f_1(x)$ and plots $f_1(x)$ using 1001 points for $x$ ranging from -2 to +2. The function should return None. For plotting, use matplotlib. You can re-use the functions you have implemented before for this laboratory.

  • Then extend this function myplot to also plot $f_2(x)$ in the same graph.

    To plot two or more curves on the same figure, just use the plot() command twice.

  • Label the x-axis, and provide a legend showing the function name (i.e. f1 and f2) for the two curves.

  • Extend the function myplot() so that it saves a png file of the graph (with name plot.png) and a pdf file of the graph (with name plot.pdf) through matplotlib commands.

    (Note: Generally, it is better to use pdf files rather than png files as pdf files are based on vector graphics and produce higher print quality, and can be zoomed without appearing pixelated. On the other hand, png files are good choice, for example, to include in webpages.)

  • Use the matplotlib navigation bar (at the bottom of the figure) to zoom into the image. For \(x > 0\), what is the (approximate) value \(x\) of the functions where \(f_1(x) = f_2(x)\)?

    If you cannot zoom into the plot, refer to Remark 1 and 2 below.

Remark 1 for users of IPython console and Spyder:

If you are using the the IPython console and by default your plots appear inline, i.e. in the IPYthon console or in the Plots panel in Spyder, then you cannot zoom into the figure. If so, you should use the command %matplotlib qt5 in the IPython console. After you have done this, the next plot figure should appear in its own pop-up window, and allow you to zoom in and out in the figure.

To switch back to figures showing in the IPython console, use %matplotlib inline.

Remark 2 for Jupyter Notebook users:

If you are using the Jupyter Notebook and by default your plots appear inline, i.e. in the IPYthon console, then you cannot zoom into the figure. If so, you should use the command %matplotlib notebook to get interactive plots. You may need to restart the kernel before issuing this command.

To switch back to figures appearing in your notebook, use %matplotlib inline.


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 lab8.py for this assignment.

Additional (voluntary) tasks are available in lab8-extra.

End of lab8.