# Tutor profile: Adrián M.

## Questions

### Subject: SciPy

How can I minimize the points in an elliptic paraboloid that lay on a two-dimensional plane?

To carry out this task we will use function minimize from the scipy module optimize. This module allows us to perform optimizations while applying constraints to our problem. With the following line, we will be importing this function. from scipy.optimize import minimize This function takes several parameters but in this case, we will only use 5 of them. The "fun" parameter takes a python function. This function represents the function we want to minimize, in this case, the elliptic paraboloid. The input of this function must be a list-like object with the independent variables (x and y) of the paraboloid. The output must be the value of the function in the specified point. The function of a paraboloid is the following: $$ f(x,y)=ax^2+by^2+c$$ For the sake of simplicity, in the example we will use the expression where a and b equals 1 and c is 0: $$ f(x,y)=x^2+y^2$$ Then the function should look like this: def paraboloid(x): # Expanding the vector of independent variables x, y = x return x**2+y**2 The second parameter, x0, is a list of coordinates. It specifies a starting point for the optimization algorithm. It must have as many elements as independent variables have our objective function. In this case, it could be: starting_point = [ 5, 7] The closer to the minimum the faster the algorithm will get the answer. The third parameter is the method. This parameter takes a string specifying the name of the method. in this case, we will use the method Sequential Least-Squares Programming (SLSQP). The fourth parameter is the jacobian of our objective function. The jacobian is a vector holding the partial derivates of a function. Its length also corresponds with the number of independent variables of the function. In this case the partial derivates are: $$ \frac{\partial f}{\partial x} = 2x \ \ \ \frac{\partial f}{\partial y} = 2y$$ Therefore, the Jacobian is: [2x, 2y] In any function, the Jacobian points to the steepest direction. This is why it is used in minimization problems, you can find a minimum (if there is any) going in the opposite direction of the Jacobian. We must pass a function that receives the independent variables and returns the Jacobian vector. def jacobian(x): # Expanding the vector of independent variables x,y = x return [2*x, 2*y] The Last parameter we have to specify is the constraint. In this case, the constraint is that we want to minimize the points of the paraboloid that lay in a plane. We can express a plane in the following way: $$p(x, y) = ax + by + c$$ In this case, we will use the next plane: $$p(x, y) = - x - y + 4$$ Then, to fulfil our constraint it must be true that $$ f(x, y) = p(x,y) $$ i.e. the point is in the paraboloid and in the plane. If we substitute these terms we get: $$ x^2+y^2=-x-y+4\ \rightarrow \ x^2+y^2+x+y-4 = 0$$ So, the points to optimize will satisfy the right equation. It is important than the condition is equalled to 0 and that only the independent variables of the objective function appear in it. The constraints parameter takes a list of dictionaries (in case we had several constraints). The dictionaries must have at least two key-value pairs. The first key is "type", and its value is either of two strings, "eq" or "ineq". This indicates if the constraint is an equality or an inequality. In our case, we have equalled the constraint to 0, therefore, we will use "eq". The second key is "fun" and its value is a python function representing the constraint. The input of this function is the same than the paraboloid function, a list of independent variables, in this case, x and y. the output must be the left part of the constraint equation ( $$ x^2+y^2+x+y-4$$). The function will look like this: def cons(x): # Expanding the vector of independent variables x,y = x return x**2+y**2+x+y-4 and the dictionary will be the following: cons_dict = {'type': 'eq', 'fun' : cons} With all of this clear, the only thing we have to do is to call the function minimize and pass the parameters. The result is stored in another variable. res = minimize(fun=paraboloid, x0=starting_point, method='SLSQP', jac=jacobian, constraints=[cons_dict]) Finally, we can print the content in the result: print(res) fun: 2.0000000000377467 jac: array([2., 2.]) message: 'Optimization terminated successfully.' nfev: 8 nit: 8 njev: 8 status: 0 success: True x: array([1., 1.]) In this object, we can find information about the x, y coordinates of the result (x), the z coordinate of this point (fun), the jacobian (steepest direction) of the paraboloid (jac) and the result of the optimization process (message) among others.

### Subject: Python Programming

How can I flat a nested list without using loops?

You can flat a nested list using a list comprehension. Internally, the loops are still happening but the syntax is much tidier. A list comprehension is an expression that outputs a list and has the following structure: [ELEMENT for ELEMENT in LIST] We can divide a list comprehension into two parts. The first one is where we determine the elements of the output list. It is what we find between the opening square bracket and the "for". In the example, it is the first appearance of the word "ELEMENT". In this first part, we can perform any kind of operation in the element. For example, suppose that the list LIST is composed of integers we could write "ELEMENT + 1" in order to get all the elements of LIST plus one in the output list. The second part is where we indicate the input list that we are going to iterate. We also specify how we are going to refer to the elements of the input list in the first part. In the example, the input list is "LIST" and the name of each element is "ELEMENT". In a comprehension list, there can be as many second parts as you like. This is the key to flat a nested list. For instance, imagine that we have the following nested list: NESTED_LIST = [ [0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15] ] The list comprehension to flat this list would be the following: [ELEMENT for SUBLIST in NESTED_LIST for ELEMENT in SUBLIST] Notice that we have 2 second-parts "for SUBLIST in NESTED_LIST" and "for ELEMENT in SUBLIST". This has the same effect as using nested loops, for each SUBLIST in NESTED_LIST we will iterate through all ELEMENTS in SUBLIST. Each iteration will generate a new element of the output list. Finally, because we are only referring to "ELEMENT" in the first part of the list comprehension, we will end up with a list with all the elements in the sublists of the nested list.

### Subject: Numpy

How can I change the value of the cells of a matrix that fulfil a condition?

In Numpy, we use slices to access and modify matrix cells. For instance, let A be a 2 by 2 matrix: $$ A= \left[ \begin{array}{cc} 3 & 4 \\ 1 & 3 \end{array} \right] $$ We can retrieve the value of the first row like so: $$ A[0] \to \left[ \begin{array}{cc} 3 & 4 \end{array} \right]$$ And we can also modify the values of the cells specified in the slice $$ A[0] = 0 $$ $$ A \to \left[ \begin{array}{cc} 0 & 0 \\ 1 & 3 \end{array} \right] $$ Other matrices can be also used as slices. In particular, Boolean matrices (whose cells can be either True or False) are called masks and are useful for modifying or accessing cells with certain properties. Generating a mask is quite simple. Let's generate one that indicates which cells are greater than 2: $$ A > 2 \to \left[ \begin{array}{cc} False & False \\ False & True \end{array} \right] $$ We can use this mask to modify only cells that fulfill our condition (being greater than 2). Let's assign the value 2 to those cells: $$ A[A > 2] = 2$$ $$A \to \left[ \begin{array}{cc} 0 & 0 \\ 1 & 2 \end{array} \right] $$ In the same way, we can build a mask using any condition and then use it as a slice to modify the cells that fulfil the condition.

## Contact tutor

needs and Adrián will reply soon.