{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Programming with Python (lab classes)\n", "#### Vedran Ĺ ego, [vsego.org](http://vsego.org/)\n", "\n", "## Content:\n", "\n", "1. Modules" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 1.** Write a module symtoep for creating various [symmetric](http://en.wikipedia.org/wiki/Symmetric_matrix) [Toeplitz matrices](http://en.wikipedia.org/wiki/Toeplitz_matrix) with the following functions:\n", "\n", "* general(L) that returns a symmetric Toeplitz matrix with the first row equal to the elements of the list L.\n", "\n", "* tridiagonal(n, d, sd) that returns a [tridiagonal](http://en.wikipedia.org/wiki/Tridiagonal_matrix) symmetric Toeplitz matrix of order n, with the float number d on the diagonal and the float number sd right below and above it (the rest of the elements are zero).\n", "\n", "* filled(n, d, nd) that returns a symmetric Toeplitz matrix of order n, with the float number d on the diagonal and all the non-diagonal elements equal to nd.\n", "\n", "* menu() that displays a choice\n", " \n", " Load a symmetric Toeplitz matrix:\n", " 1. General symmetric Toeplitz matrix\n", " 2. Tridiagonal symmetric Toeplitz matrix\n", " 3. Filled symmetric Toeplitz matrix\n", " Your choice (1-3):\n", " \n", " and asks the user to choose. Then,\n", " * if the user chooses \"1\", the function asks for a list L of numbers (preferably as a string of comma-separated floats, but you can use some other method as well), and then returns general(L),\n", " * if the user chooses \"2\", the function asks for an integer n and floats d and sd, and returns tridiagonal(n, d, sd).\n", " * if the user chooses \"3\", the function asks for an integer n and floats d and nd, and returns filled(n, d, sd).\n", " * if the user chooses anything else, the choice is redisplayed and user is asked to choose again.\n", "\n", "When run like a program, this module should do nothing.\n", "\n", "Toeplitz matrices are those that have constant elements on all diagonals.\n", "* An example of a symmetric Toeplitz matrix of order $3$:\n", "$$\\begin{bmatrix} 1 & 2 & 3 & 4 & 5 \\\\ 2 & 1 & 2 & 3 & 4 \\\\ 3 & 2 & 1 & 2 & 3 \\\\ 4 & 3 & 2 & 1 & 2 \\\\ 5 & 4 & 3 & 2 & 1 \\end{bmatrix}$$\n", "* An example of a tridiagonal (all elements other than those on the main and its neighbour diagonals are zero) symmetric Toeplitz matrix of order $3$:\n", "$$\\begin{bmatrix} 1 & 2 & 0 & 0 & 0 \\\\ 2 & 1 & 2 & 0 & 0 \\\\ 0 & 2 & 1 & 2 & 0 \\\\ 0 & 0 & 2 & 1 & 2 \\\\ 0 & 0 & 0 & 2 & 1 \\end{bmatrix}$$\n", "* An example of a \"filled\" symmetric Toeplitz matrix of order $3$:\n", "$$\\begin{bmatrix} 1 & 2 & 2 & 2 & 2 \\\\ 2 & 1 & 2 & 2 & 2 \\\\ 2 & 2 & 1 & 2 & 2 \\\\ 2 & 2 & 2 & 1 & 2 \\\\ 2 & 2 & 2 & 2 & 1 \\end{bmatrix}$$\n", "\n", "All the functions have to return the matrices as NumPy's matrix type, which is easily created from a list or any other two-dimensional array-like type, using the function [numpy.matrix](http://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.html). For example, the first of the three matrices shown above can be created as follows:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2 3 4 5]\n", " [2 1 2 3 4]\n", " [3 2 1 2 3]\n", " [4 3 2 1 2]\n", " [5 4 3 2 1]]\n" ] } ], "source": [ "import numpy as np\n", "L = list(range(1,6))\n", "res = list()\n", "for i in range(5):\n", " row = list()\n", " for j in range(5):\n", " row.append(L[abs(i-j)])\n", " res.append(row)\n", "res = np.matrix(res)\n", "print(res)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It can be done more easily using a generator expression:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2 3 4 5]\n", " [2 1 2 3 4]\n", " [3 2 1 2 3]\n", " [4 3 2 1 2]\n", " [5 4 3 2 1]]\n" ] } ], "source": [ "import numpy as np\n", "L = list(range(1,6))\n", "res = np.matrix([[L[abs(i-j)] for i in range(5)] for j in range(5)])\n", "print(res)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may implement the functions tridiagonal(n, d, sd) and filled(n, d, nd) either on their own or simply by creating L and calling general(L). The former approach is prefered, in which case [numpy.zeros](http://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html), [numpy.ones](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ones.html), [numpy.fill_diagonal](http://docs.scipy.org/doc/numpy/reference/routines.indexing.html), and [numpy.tri](http://docs.scipy.org/doc/numpy/reference/generated/numpy.tri.html#numpy.tri) may help you, along with the matrix addition (done with the usual plus + operator) and multiplication with a constant (done with the usual multiplication * operator). These functions are much faster than setting the elements index by index, but you are free to work without them." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 2.** Using the module symtoep, write a program that loads a matrix (one of the 3 supported types), and then prints it and its eigenvalues.\n", "\n", "To compute the eigenvalues of a symmetric matrix, use [scipy.linalg.eigvalsh](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.eigvalsh.html). If, for some reason, SciPy doesn't work, use [numpy.linalg.eigvalsh](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eigvalsh.html).\n", "\n", "Ideally, make your program run properly with either (but this is not a must). For example,\n", "python\n", "try:\n", " import scipy.linalg as la\n", "except ImportError:\n", " import numpy.linalg as la\n", "...\n", "print(la.eigvalsh(A))\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 3.** Using the module symtoep, write a program that loads a matrix (one of the 3 supported types), and then prints it and a message explaining if it is positive semidefinite or not.\n", "\n", "To test positive semidefiniteness, try to compute the [Cholesky factorization](http://en.wikipedia.org/wiki/Cholesky_decomposition), using either [scipy.linalg.cholesky](http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.cholesky.html) or [numpy.linalg.cholesky](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.cholesky.html). If the computation fails (i.e., a numpy.linalg.linalg.LinAlgError exception is raised), the matrix is not positive semidefinite. Otherwise, it is.\n", "\n", "The same remarks from Problem 2 regarding the import of SciPy/NumPy modules apply." ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }