{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## CS 132 Homework 4 A \n", "\n", "### Due Wednesday August 4th at Midnight (1 minute after 11:59pm) in Gradescope (with grace period of 6 hours)\n", "### Homeworks may be submitted up to 24 hours late with a 10% penalty (same grace period)\n", "\n", "\n", "Please read through the entire notebook, reading the expository material and then do the problems, following the instuctions to try various features; among the exposition of various features of Python there\n", "are three problems which will be graded. All problems are worth 10 points. \n", "\n", "You will need to complete this notebook and then convert to a PDF file in order to submit to Gradescope. Instructions are given here:\n", "\n", "https://www.cs.bu.edu/fac/snyder/cs132/HWSubmissionInstructions.html\n", "\n" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "# Here are some imports which will be used in the code in the rest of the lab \n", "\n", "# Imports used for the code in CS 237\n", "\n", "import numpy as np # arrays and functions which operate on arrays\n", "\n", "import matplotlib.pyplot as plt # normal plotting\n", "\n", "\n", "# NOTE: You may not use any other libraries than those listed here without explicit permission." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "# Gaussian Elimination\n", "\n", "# number of digits of precision to print out\n", "\n", "prec = 4\n", "\n", "########################################################################################################\n", "\n", "# Returns the Row Echelon (upper triangular) form\n", "\n", "def forwardElimination(A,traceLevel=0):\n", " \n", " A = (np.copy(A)).astype(float)\n", " \n", " if (traceLevel > 0):\n", " print(\"Running Forward Elimination on:\\n\")\n", " print(np.round(A, decimals=4),\"\\n\")\n", " print()\n", " \n", " (numRows,numCols) = A.shape\n", " \n", " # r = row we are currently working on pivot value is A[r][c]\n", " r = 0 \n", " for c in range(numCols): # solve for variable in column c \n", " # find row in column c with first non-zero element, and exchange with row r \n", " r1 = r\n", " while(r1 < numRows):\n", " if (not np.isclose(A[r1][c],0.0)): # A[r1][c] is first non-zero element at or below r in column c\n", " break\n", " r1 += 1\n", " \n", " if(r1 == numRows): # all zeros below r in this column\n", " continue # go on to the next column, but still working on same row \n", " \n", " if(r1 != r): \n", " # exchange rows r1 and r\n", " A[[r1,r],:] = A[[r,r1],:] \n", " if (traceLevel == 2): \n", " print(\"Exchange R\" + str(r1+1) + \" and R\" + str(r+1) + \"\\n\") \n", " print(np.round(A, decimals=4)) \n", " print() \n", "\n", " # now use pivot A[r][c] to eliminate all vars in this column below row r\n", " for r2 in range(r+1,numRows):\n", " rowReduce(A,r,c,r2,traceLevel)\n", " \n", " r += 1 \n", " if (r >= numRows):\n", " break\n", " \n", " return A\n", "\n", "# for pivot A[r][c], eliminate variable in location A[r2][c] in row r2 using row operations\n", "\n", "def rowReduce(A,r,c,r2,traceLevel=0):\n", "\n", " if(not np.isclose(A[r2][c],0.0)):\n", "\n", " factor = -A[r2][c]/A[r][c] \n", " A[r2] += factor * A[r]\n", " \n", " if(traceLevel == 2):\n", " print(\"R\" + str(r2+1) + \" += \" + str(np.around(factor,prec)) + \"*R\" + str(r+1) + \"\\n\") \n", " print(np.round(A, decimals=4))\n", " print()\n", "\n", "# Take a Row Echelon Form and return a Reduced Row Echelon Form\n", "\n", "def backwardSubstitute(A,augmented=True,traceLevel=0): \n", " \n", " numRows,numCols = A.shape\n", " \n", " if (A.dtype != 'float64'):\n", " A = A.astype(float)\n", "\n", " # now back-substitute the variables from bottom row to top\n", " if (traceLevel > 0):\n", " print(\"Creating Reduced Row Echelon Form...\\n\") \n", "\n", " for r in range(numRows):\n", "\n", " # find variable in this row\n", " for c in range(numCols):\n", " if(not np.isclose(A[r][c],0.0)):\n", " break \n", " \n", " if ((augmented and c >= numCols-1) or (c >= numCols)): # inconsistent or redundant row\n", " continue \n", " \n", " # A[r][c] is variable to eliminate\n", " \n", " factor = A[r][c]\n", " \n", " if (np.isclose(factor,0.0)): # already eliminated\n", " continue\n", " \n", " if(not np.isclose(factor,1.0)): \n", " A[r] *= 1/factor\n", " if (traceLevel == 2):\n", " print(\"R\" + str(r+1) + \" = R\" + str(r+1) + \"/\" + str(np.around(factor,prec)) + \"\\n\") \n", " print(np.round(A, decimals=4))\n", " print()\n", "\n", " for r2 in range(r): \n", " rowReduce(A,r,c,r2,traceLevel)\n", " \n", " return A \n", "\n", " \n", "# try to find row of all zeros except for last column, in augmented matrix. \n", "\n", "def noSolution(A):\n", " numRows,numCols = A.shape\n", " for r in range(numRows-1,-1,-1): # start from bottom, since inconsistent rows end up there\n", " for c in range(numCols):\n", " if(not np.isclose(A[r][c],0.0)): # found first non-0 in this row\n", " if(c == numCols-1):\n", " return True\n", " else:\n", " break\n", " return False\n", "\n", "########################################################################################################\n", "\n", "# Runs GE and returns a reduced row echelon form\n", "\n", "# If b == None assumes that A is NOT an augmented matrix, and runs GE and returns Reduced Row Echelon Form\n", "\n", "# If b is a column matrix then adjoins it to A and runs GE;\n", "# Always returns the Reduced Row Echelon Form\n", "# If inconsistent then also prints out \"Inconsistent!\"\n", "\n", "# If b is a length n array instead of a 1 x n array (column vector)\n", "# b will be converted to a column vector, for convenience. \n", "\n", "# traceLevel 0 will not print anything out during the run\n", "# traceLevel 1 will print out various stages of the process and the intermediate matrices\n", "# traceLevel 2 will also print out the row operations used at each step. \n", "\n", "# If you want to produce an Echelon Form (NOT reduced), then use forwardElimination instead. \n", "\n", "# See examples for more explanation of how to use this\n", "\n", "def GaussianElimination(A,b=None, traceLevel = 0):\n", " if( type(b) != type(None)):\n", " if( (A.shape)[0] == 1 ):\n", " b = np.array([b]).T\n", " Ab = (np.hstack((A.copy(),b))).astype(float)\n", " else:\n", " Ab = A.copy().astype(float)\n", " \n", " if( traceLevel > 0 and type(b) == type(None)):\n", " print(\"Creating Reduced Row Echelon Form:\\n\")\n", " print(np.round(Ab, decimals=4))\n", " print()\n", " elif( traceLevel > 0 ):\n", " print(\"Running Gaussian Elimination on augmented matrix:\\n\")\n", " print(np.round(Ab, decimals=4))\n", " print()\n", " \n", " B = forwardElimination(Ab,traceLevel)\n", " \n", " if( traceLevel > 0 ):\n", " print(\"Echelon Form:\\n\")\n", " print( np.round(B, decimals=4) + np.zeros(B.shape),\"\\n\") # adding -0.0 + 0 gives 0.0\n", " print()\n", " \n", " if ( type(b) != type(None) and noSolution(B) ):\n", " print(\"No solution!\")\n", "\n", " C = backwardSubstitute(B,type(b)!=type(None),traceLevel)\n", " \n", " if( traceLevel > 0 ):\n", " print(\"Reduced Row Echelon Form:\\n\")\n", " print( np.round(C, decimals=4) + np.zeros(C.shape),\"\\n\") # adding -0.0 + 0 gives 0.0\n", " print()\n", " \n", " return C\n", "\n", "########################################################################################################\n", " \n", "def GE(A,b=None, traceLevel = 0):\n", " return GaussianElimination(A,b,traceLevel)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Problem 1\n", "\n", "In this problem you will write code to calculate the PLU decomposition of a matrix, AND the determinant\n", "in the case that the matrix is square, as discussed in lecture. \n", "\n", "Please review lectures 8B and 9 for a complete discussion of what you need to do; a brief summary\n", "is as follows.\n", "\n", "Gaussian Elimination can be implemented completely by matrix multiplication using elementary\n", "matrices to perform row operations; since we are only concerned with creating the echelon form\n", "(not the reduced form, with pivots = 1.0 and back substitution), we only need to perform forward\n", "elimination, using only\n", "row exchanges and row reductions (adding a multiple of one row to another). \n", "\n", "Therefore if we denote the echelon form (an upper-triangular matrix) by $U$, a row exchange by $P$, a row reduction by $R$, and either one of these by $E$,\n", "Gaussian Elimination with $i$ row exchanges and $j$ row reductions can be expressed as\n", "\n", "$$U\\ =\\ E_{i+j} E_{i+j-1} \\ldots E_{2} E_{1} A$$\n", "\n", "As explained in lecture, the row exchanges commute with the row reductions, so this can be written as\n", "\n", "$$U\\ =\\ R_{j}\\ldots R_{1} P_{i} \\ldots P_{1} A$$\n", "\n", "or, since elementary matrices are invertible, as\n", "\n", "$$A\\ =\\ P_{1}\\ldots P_{i} R^{-1}_{1} \\ldots R^{-1}_{j} U.$$\n", "\n", "Note that each $P_i$ is its own inverse, and to invert a row reduction, instead of\n", "adding a multiple of one row to another, simply *subtract*. \n", "\n", "The PLU decomposition is therefore \n", "\n", "$$P=P_{1}\\ldots P_{i},$$ \n", "\n", "$$L=R^{-1}_{1} \\ldots R^{-1}_{j},$$ \n", "\n", "and $U$ is the echelon form produced by forward elimination. \n", "\n", "In order to calculate $P$ and $L$, initialize each of these to $I_m$, where $m$ is the number\n", "of rows in $A$ ($A$ need not be square, but $P$ and $L$ will be square). Then, for\n", "each row operation, update $P$ and $L$ by *right* multiplying by the inverse of the appropriate\n", "elementary matrix:\n", "\n", "$$ P = P @ P_k\\quad\\quad\\quad \\text{ or }\\quad\\quad\\quad L = L @ R^{-1}_k.$$\n", "\n", "Again, review the lectures to understand this process so you can add code to the following, which is simply\n", "the code for `forwardElimination` from the previous code cell, with comment hints about what to do.\n", "You should not have to change anything except where \"your code here\" is indicated. \n", "\n", "Tests are given below. " ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "# Calculate the PLU decomposition of a matrix by keeping track of\n", "# the row ops and accumulating the appropriate matrices.\n", "\n", "# While we are at it, if the matrix is square, we calculate the determinant by\n", "# taking the product of the diagonal of U, and determine\n", "# the sign by counting the number of row exchanges\n", "\n", "# NOTE: i and j are matrix rows, R1 is row 0\n", "\n", "\n", "def PLU_Decomposition(A,traceRowOps=False):\n", " \n", " A = (np.copy(A)).astype(float)\n", " \n", " if (traceRowOps):\n", " print(\"\\nRunning Forward Elimination on:\\n\")\n", " print(np.round(A, decimals=4),\"\\n\")\n", " print()\n", " \n", " if (traceRowOps):\n", " print(\"Creating Echelon Form...\\n\")\n", " \n", " (numRows,numCols) = A.shape\n", " \n", " # Now initialize the permutation matrix P, the lower triangular L, and also a counter for the number of\n", " # row exchanges. P and L will be square matrices with the same number of rows as A\n", " \n", " # YOUR CODE HERE\n", " \n", " P = np.array([]) # just to get it to compile, you'll have to change these two\n", " L = np.array([])\n", " numExchs = 0 # number of row exchanges\n", "\n", " \n", " # r = row we are currently working on pivot value is A[r][c]\n", " r = 0 \n", " for c in range(numCols): # solve for variable in column c \n", " # find row in column c with first non-zero element, and exchange with row r \n", " r1 = r\n", " while(r1 < numRows):\n", " if (not np.isclose(A[r1][c],0.0)): # A[r1][c] is first non-zero element at or below r in column c\n", " break\n", " r1 += 1\n", " \n", " if(r1 == numRows): # all zeros below r in this column\n", " continue # go on to the next column, but still working on same row \n", " \n", " if(r1 != r): # Exchange rows r1 and r\n", " tmp = A[r1].copy()\n", " A[r1] = A[r]\n", " A[r] = tmp\n", " \n", " # YOUR CODE HERE to count the number of row exchanges AND update P\n", "\n", " \n", " if (traceRowOps): \n", " print(\"Exchange R\" + str(r1+1) + \" and R\" + str(r+1) + \"\\n\") \n", " print(np.round(A, decimals=4)) \n", " print() \n", "\n", " # now use pivot A[r][c] to eliminate all vars in this column below row r\n", " for r2 in range(r+1,numRows):\n", " if(not np.isclose(A[r2][c],0.0)): \n", " factor = -A[r2][c]/A[r][c] \n", " A[r2] += factor * A[r]\n", " \n", " # YOUR CODE HERE to update L with inverse of the row reduction just done\n", "\n", "\n", " if(traceRowOps):\n", " print(\"R\" + str(r2+1) + \" += \" + str(np.around(factor,prec)) + \"*R\" + str(r+1) + \"\\n\") \n", " print(np.round(A, decimals=4))\n", " print() \n", " r += 1 \n", " if (r >= numRows):\n", " break\n", " \n", " # Note: A has actually been turned into U at this point\n", " \n", " U = A\n", " \n", " # Now calculate the determinant, if A is square\n", " # Determinant of U is PRODUCT of the diagonal elements\n", " # but the sign changes each time there is a row exchange. \n", " \n", " # If matrix is not square set d to None\n", " \n", " d = None\n", " \n", " # YOUR CODE HERE\n", " \n", " \n", " return (P,L,U,d)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.size" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", " [[1 2]\n", " [3 4]] \n", "\n", "P:\n", " [] \n", "\n", "L:\n", " [] \n", "\n", "U:\n", " [[ 1. 2.]\n", " [ 0. -2.]] \n", "\n" ] } ], "source": [ "# (A)\n", "\n", "def test(A):\n", " (P,L,U,d) = PLU_Decomposition(A)\n", "\n", " print(\"A:\\n\",np.around(A,4),'\\n')\n", " print(\"P:\\n\",np.around(P,4),'\\n')\n", " print(\"L:\\n\",np.around(L,4),'\\n')\n", " print(\"U:\\n\",np.around(U,4),'\\n')\n", " if(type(d) != type(None)):\n", " print(\"d:\\n\",np.around(d,4),'\\n')\n", " if(P.size > 0):\n", " print(\"P@L@U:\\n\",np.around(P@L@U,4))\n", "\n", " # Test it!\n", " np.isclose(A,P@L@U).all()\n", "\n", "A = np.array([[1,2], [3,4]])\n", "\n", "test(A)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", " [[ 1 -1 0 0]\n", " [-1 2 -1 0]\n", " [ 0 -1 2 -1]\n", " [ 0 0 -1 2]] \n", "\n", "P:\n", " [] \n", "\n", "L:\n", " [] \n", "\n", "U:\n", " [[ 1. -1. 0. 0.]\n", " [ 0. 1. -1. 0.]\n", " [ 0. 0. 1. -1.]\n", " [ 0. 0. 0. 1.]] \n", "\n" ] } ], "source": [ "# (B)\n", "\n", "B = np.array([[1,-1,0,0], [-1,2,-1,0],[0,-1,2,-1],[0,0,-1,2]])\n", "\n", "test(B)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", " [[1 2 3]\n", " [4 5 6]\n", " [7 8 9]] \n", "\n", "P:\n", " [] \n", "\n", "L:\n", " [] \n", "\n", "U:\n", " [[ 1. 2. 3.]\n", " [ 0. -3. -6.]\n", " [ 0. 0. 0.]] \n", "\n" ] } ], "source": [ "# (C)\n", "\n", "C = np.array([[1,2,3], [4,5,6],[7,8,9]])\n", "\n", "test(C)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", " [[1 1 1]\n", " [1 2 2]\n", " [1 2 3]] \n", "\n", "P:\n", " [] \n", "\n", "L:\n", " [] \n", "\n", "U:\n", " [[1. 1. 1.]\n", " [0. 1. 1.]\n", " [0. 0. 1.]] \n", "\n" ] } ], "source": [ "#(D)\n", "\n", "D = np.array([[1,1,1], [1,2,2],[1,2,3]])\n", "\n", "test(D)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", " [[0.5366 0.9777 0.0044 ... 0.6811 0.1108 0.3741]\n", " [0.7849 0.0715 0.9217 ... 0.2989 0.241 0.6094]\n", " [0.9242 0.1246 0.31 ... 0.8826 0.7166 0.0276]\n", " ...\n", " [0.1087 0.9667 0.6172 ... 0.3932 0.859 0.1589]\n", " [0.5529 0.6893 0.0641 ... 0.085 0.7321 0.0954]\n", " [0.0883 0.1598 0.3141 ... 0.7664 0.086 0.1625]] \n", "\n", "P:\n", " [] \n", "\n", "L:\n", " [] \n", "\n", "U:\n", " [[ 5.36600e-01 9.77700e-01 4.40000e-03 ... 6.81100e-01 1.10800e-01\n", " 3.74100e-01]\n", " [ 0.00000e+00 -1.35840e+00 9.15300e-01 ... -6.97300e-01 7.90000e-02\n", " 6.22000e-02]\n", " [ 0.00000e+00 0.00000e+00 -7.48100e-01 ... 5.10000e-01 4.35200e-01\n", " -6.88100e-01]\n", " ...\n", " [ 0.00000e+00 0.00000e+00 -0.00000e+00 ... 3.07680e+00 -1.07950e+00\n", " -7.07900e-01]\n", " [ 0.00000e+00 -0.00000e+00 -0.00000e+00 ... -1.02295e+01 4.35210e+00\n", " 8.26700e-01]\n", " [ 0.00000e+00 -0.00000e+00 0.00000e+00 ... -2.03390e+00 -2.35800e-01\n", " 2.00060e+00]] \n", "\n" ] } ], "source": [ "# (E)\n", "\n", "E = np.random.random((51,72))\n", "\n", "test(E)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Problem 2\n", "\n", "You must use your code for `analyzeMatrix` from HW 02 for this problem. In the next cell, paste\n", "in your solution and then complete the following code template to calculate the eigenvalues of a 2x2 matrix. \n", "Further hints are written in the template. " ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "# Paste your code for analyzeMatrix here\n", "\n", "\n", "\n", " " ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "# Solution: Calculate the eigenvalues of a 2 x 2 matrix \n", "\n", "# Use the following two function to determine the characteristic polynomial\n", "\n", "# compute the trace of a 2x2 matrix\n", "def trace(A):\n", " return 0 # just to get it to compile -- your code here\n", "\n", "# compute the determinant of a 2x2 matrix\n", "def det(A):\n", " return 0 # just to get it to compile -- your code here\n", "\n", "\n", "def eigen(A):\n", " \n", " # use the quadratic formula to calculate the roots of the characteristic polynomial\n", "\n", " a = 0 # just to get it to compile -- your code here\n", " b = 0 # just to get it to compile -- your code here\n", " c = 0 # just to get it to compile -- your code here\n", "\n", " # d = discriminant (expression inside the square root)\n", " d = 0 # just to get it to compile -- your code here \n", " \n", "\n", " # determine whether there are only complex eigenvalues, 1 (duplicated) real eigenvalue, or 2 distinct real eigenvalues\n", " # then use analyzeMatrix to calculate the eigenbasis for each real eigenvalue.\n", " \n", " # Print out which case (based on discriminant), and any real eigenvalues with associated eigenspace\n", " # as shown below in Part A\n", " \n", " # Remember to use np.isclose(d,0.0) instead of d == 0.0. \n", " \n", " # Your code here\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### (A)\n", "\n", "Test your code with the following matrix; you should design your code so that it prints out something\n", "like this:\n", "\n", " [[1 0]\n", " [0 0]] \n", "\n", " two distinct real eigenvalues\n", "\n", " lambda_1 = 1.0\n", " [[1.]\n", " [0.]] \n", "\n", " lambda_2 = 0.0\n", " [[0.]\n", " [1.]]\n", "\n", "\n", " Out[3]: (array([1., 0.]),\n", " array([[1., 0.],\n", " [0., 1.]]))" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 0]\n", " [0 0]] \n", "\n" ] }, { "data": { "text/plain": [ "(array([1., 0.]),\n", " array([[1., 0.],\n", " [0., 1.]]))" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = np.array( [[1,0],[0,0]] ) # Has two distinct real eigenvalues\n", "\n", "print(A,'\\n')\n", "\n", "eigen(A)\n", "\n", "# test it; remember that eigenvectors may be scaled differently and\n", "# this function returns eigenvectors as columns in a matrix\n", "\n", "np.linalg.eig(A)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 1]\n", " [1 1]] \n", "\n" ] }, { "data": { "text/plain": [ "(array([2., 0.]),\n", " array([[ 0.70710678, -0.70710678],\n", " [ 0.70710678, 0.70710678]]))" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# (B) Test on the following matrix in the same way\n", "\n", "B = np.array( [[1,1],[1,1]] ) # Has two distinct real eigenvalues\n", "\n", "print(B,'\\n')\n", "\n", "eigen(B)\n", "\n", "# test it; remember that eigenvectors may be scaled differently and\n", "# this function returns eigenvectors as columns in a matrix\n", "\n", "np.linalg.eig(B)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-1 1]\n", " [ 0 -1]] \n", "\n" ] }, { "data": { "text/plain": [ "(array([-1., -1.]),\n", " array([[ 1.00000000e+00, -1.00000000e+00],\n", " [ 0.00000000e+00, 2.22044605e-16]]))" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# (C) Test on the following matrix in the same way\n", "\n", "C = np.array( [[-1,1],[0,-1]] ) # Should have only 1 eigenvalue, with 1D eigenspace\n", "\n", "print(C,'\\n')\n", "\n", "eigen(C)\n", "\n", "# test it; remember that eigenvectors may be scaled differently and\n", "# this function returns eigenvectors as columns in a matrix\n", "\n", "np.linalg.eig(C)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 0]\n", " [0 1]] \n", "\n" ] }, { "data": { "text/plain": [ "(array([1., 1.]),\n", " array([[1., 0.],\n", " [0., 1.]]))" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# (D) Test on the following matrix in the same way\n", "\n", "D = np.array( [[1,0],[0,1]] ) # Should have only 1 eigenvalue, with 2D eigenspace\n", "\n", "print(D,'\\n')\n", "\n", "eigen(D)\n", "\n", "# test it; remember that eigenvectors may be scaled differently and\n", "# this function returns eigenvectors as columns in a matrix\n", "\n", "np.linalg.eig(D)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1 3]\n", " [-1 -2]] \n", "\n" ] }, { "data": { "text/plain": [ "(array([-0.5+0.8660254j, -0.5-0.8660254j]),\n", " array([[ 0.8660254+0.j , 0.8660254-0.j ],\n", " [-0.4330127+0.25j, -0.4330127-0.25j]]))" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# (E) Test on the following matrix in the same way\n", "\n", "E = np.array( [[1,3],[-1,-2]] ) # Has complex eigenvalues\n", "\n", "print(E,'\\n')\n", "\n", "eigen(E)\n", "\n", "# test it; remember that eigenvectors may be scaled differently and\n", "# this function returns eigenvectors as columns in a matrix\n", "\n", "np.linalg.eig(E)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }