Exercises of lab 1

Exercise 1

Compute first 30 Fibonacci numbers, which are defined by equations $f_0=1;\,f_1=1;\, f_{i}=f_{i-1}+f_{i-2},\ i\geq 2.$

Solution Fist make sure that the package NumPy is imported by executing the following line

import numpy as np

Let us make our code more universal by by introducing a variable n which specifies how many values we want. For solving the problem we will give it the value 30, but it can be easily changed if we want to see a different number of Fibonaccy numbers.

Create a vector with n elements to store the Fibonacci numbers, filled initially with ones (then first two elements (with indexes 0 and 1) have correct values

Now we need to repeat a line for computation $ f_{i}=f_{i-1}+f_{i-2}$ for i=2,3,...,n-1 A complect of such i values can be produced with several several commands, for exampel range(2,n) or arange(2,n). In the case of for cycle it is better to use the first version since the atual vector of i values is not produced, but outside of definition of for cycles we need the second command. If you want to know the detailed differences of the commands, please ask. Compute all the values with a for cycle and print out the values:

The answers are printed out in the scientific notation of the form $a\cdot 10^b$, where a is the number before e and b is the number after e, so 2.33000000e+02 is actually $2.33\cdot 10^2=233$.

Exercise 2

Generate $n=20$ values from the standard normal distribution and store the values in a vector x. Compute the values of the vector y defined by $$y_0=x_0;\ y_{n-1}=x_{n-1};\ y_i=\frac{x_{i-1}+x_i+x_{i+1}}{3},\ i=1,2,\ldots,n-2.$$

Solution Generating values for vector x is easy, it can be don with the command np.random.randn(n). Each time we execute the command, we should get n new values from the standard normal distribution and usually this is what we want. But in order to to compare the results of two different solutions (the sample solution and your own solution), it is possible to fix a set of the random numbers by executing the command np.random.seed(a_number) before using np.random.randn(n) - after using this command (with the same integer a_number) we always get the same sequence of random numbers.

Define a vector y filled with n zeros and set the first and last elements:

Now it is possible to compute the values for $y_i,\ i=1,\ldots,n-1$ like in the case of the previous exercise with a for cycle like

for i in range(1,n-1): y[i]=(x[i-1]+x[i]+x[i+1])/3

but it is a much better idea to avoid for cycles by using vector operations. There are many ways to achieve this, but for beginners the simplest one is to use the property of numpy package that instead of a single index we can use vectors of indexes. For example, if i is a vector with components 2,3,4, then x[i] is also a vector with components x[2],x[3],x[4]. Adding a number to a vector adds the number to all elements of the vector, so i+2 has components 4,5,6 and x[i]+x[i+2] gives a vector with three components x[2]+x[4],x[3]+x[5],x[4]+x[6] and it turns out that this approach is faster than computing the numbers one by one by in a for cycle if the number of terms computed is not very small.

Use this idea to compute the values of $y_i,\ i=1,\ldots,n-1$ without for cycles

Exercise 3

Define a function $g(x)=\sin(2x)+\frac{\cos(x)}{2x}$. Plot the graph of the function for $1\leq x\leq 10$ by using the values of the function at 101 points.

Solution

If you want to make your graph nicer, you can use additional commands like xlabel, ylabel,title from pylab and use them (like pl.xlabel('x') on a separate line) to set labes for axes and the title of the graph.

Exercise 4

Write a function simpleMax(f,a,b,n) that computes approximately the maximal value of the function $f$ over the interval $[a,b]$ by evaluation it at the points $a,\, a+h,\,a+2h,\ldots,b$, where $h=\frac{b-a}{n}$. Use the function simpleMax to compute approximately the maximal value of the function $g$ from the previous exercise for $x\in [1,3]$ in the case $n=200$ (answer should be 1.1794485797597516).

Solution

Again it is possible to solve the problem by using vectorized commands. A good way is to compute first a vector x containing all x values we want to use, then compute with a single command the values of the function f at those points (just by f(x)) and then compute the maximal value of elements of a vector by the function amax.

Exercise 5

Write a function Simple2dMax(f,a,b,m,c,d,n) which computes approximately the maximum of a function of 2 variables by computing the maximal value at the points $$x_i=a+ih_1,\ y_j=c+j h_2, \ i=0,\ldots,m,\ j=0,\ldots,n,$$ where $h_1=\frac{b-a}{m},\ h_2=\frac{d-c}{n}$. Test the correctness of the function by computing the maximal value of $u(x,y)=x^2+xy-2y^2$ over the unit square $0\leq x\leq 1,\ 0\leq y\leq 1$ in the case $m=10,\ n=20$ (the answer should be 1.125).

Solution

It is a little tricky exercise if one wants to use vector operations to have an efficient code. It is important to understand that most functions work nicely in numpy and scipy if one of the arguments is replaced by a vector but using a vector for sevaral arguments at the same time does not usually give us what we want. A reasonable approach is to use one for cycle to let one of the variables to take values one by one, but use vector commands to compute maximum over all values of the other variable.