Reputation: 323
I'm defining variables to convert a given matrix to its echelon form, the exercise ask me to define different variables to check whether a matrix is singular or not, and to convert it to its echelon form, this is the exercise and what I've done so far:
import numpy as np
# Our function will go through the matrix replacing each row in order turning it into echelon form.
# If at any point it fails because it can't put a 1 in the leading diagonal,
# we will return the value True, otherwise, we will return False.
# There is no need to edit this function.
def isSingular(A) :
B = np.array(A, dtype=np.float_) # Make B as a copy of A, since we're going to alter it's values.
try:
fixRowZero(B)
fixRowOne(B)
fixRowTwo(B)
fixRowThree(B)
except MatrixIsSingular:
return True
return False
# This next line defines our error flag. For when things go wrong if the matrix is singular.
# There is no need to edit this line.
class MatrixIsSingular(Exception): pass
# For Row Zero, all we require is the first element is equal to 1.
# We'll divide the row by the value of A[0, 0].
# This will get us in trouble though if A[0, 0] equals 0, so first we'll test for that,
# and if this is true, we'll add one of the lower rows to the first one before the division.
# We'll repeat the test going down each lower row until we can do the division.
# There is no need to edit this function.
def fixRowZero(A) :
if A[0,0] == 0 :
A[0] = A[0] + A[1]
if A[0,0] == 0 :
A[0] = A[0] + A[2]
if A[0,0] == 0 :
A[0] = A[0] + A[3]
if A[0,0] == 0 :
raise MatrixIsSingular()
A[0] = A[0] / A[0,0]
return A
# First we'll set the sub-diagonal elements to zero, i.e. A[1,0].
# Next we want the diagonal element to be equal to one.
# We'll divide the row by the value of A[1, 1].
# Again, we need to test if this is zero.
# If so, we'll add a lower row and repeat setting the sub-diagonal elements to zero.
# There is no need to edit this function.
def fixRowOne(A) :
A[1] = A[1] - A[1,0] * A[0]
if A[1,1] == 0 :
A[1] = A[1] + A[2]
A[1] = A[1] - A[1,0] * A[0]
if A[1,1] == 0 :
A[1] = A[1] + A[3]
A[1] = A[1] - A[1,0] * A[0]
if A[1,1] == 0 :
raise MatrixIsSingular()
A[1] = A[1] / A[1,1]
return A
# This is the first function that you should complete.
# Follow the instructions inside the function at each comment.
def fixRowTwo(A) :
# Insert code below to set the sub-diagonal elements of row two to zero (there are two of them).
A[2] = (A[2] - A[2,0]) * (A[2] - A[2,1])
# Next we'll test that the diagonal element is not zero.
if A[2,2] == 0 :
# Insert code below that adds a lower row to row 2.
A[2] = A[2] + A[3]
# Now repeat your code which sets the sub-diagonal elements to zero.
A[2] = (A[2] - A[2,0]) * (A[2] - A[2,1])
if A[2,2] == 0 :
raise MatrixIsSingular()
# Finally set the diagonal element to one by dividing the whole row by that element.
A[2] = A[2]/A[2,2]
return A
# You should also complete this function
# Follow the instructions inside the function at each comment.
def fixRowThree(A) :
# Insert code below to set the sub-diagonal elements of row three to zero.
A[3] = (A[3] - A[3,0]) * (A[3] - A[3,1]) * (A[3] - A[3,2])
# Complete the if statement to test if the diagonal element is zero.
if A[3,3] == 0:
raise MatrixIsSingular()
# Transform the row to set the diagonal element to one.
A[3] = A[3]/A[3,3]
return A
I get to use fixRowZero(A), fixRowOne(A) and fixRowTwo(A), but when I use the fixRowThree(A), I get the following error message:
---------------------------------------------------------------------------
MatrixIsSingular Traceback (most recent call last)
<ipython-input-58-d25352be9b2c> in <module>
----> 1 fixRowThree(A)
<ipython-input-57-4faff915d9e0> in fixRowThree(A)
82 # Complete the if statement to test if the diagonal element is zero.
83 if A[3,3] == 0:
---> 84 raise MatrixIsSingular()
85 # Transform the row to set the diagonal element to one.
86 A[3] = A[3]/A[3,3]
MatrixIsSingular:
What am I doing wrong? When I pass a matrix to check it whether it's singular or not it gives returns me True or False accordingly, so it seems to work fine, but when I use the fixRowThree() function returns me this error message
Upvotes: 0
Views: 1900
Reputation: 171
I'm probably late to answer this question. But let's clarify a few things for those who might encounter this exercise.
From the way I see it, you did not understand the task at hand:
# set the sub-diagonal elements of row three to zero.
If you return to the function fixRowOne, you will see this expression:
A[1] = A[1] - A[1,0] * A[0]
And what does this expression do?
# First we'll set the sub-diagonal elements to zero, i.e. A[1,0].
All you have to do is follow this very expression. Even though there was no error in your FixSecondRow function, it is wrong because it did not follow the same pattern. Maybe, your code was lucky with the sample test.
In row Two, there are two sub diagonal elements: A[2,0] and A[2,1]. A sub diagonal elements are the elements that come before the diagonal element of said row. You have to do the same process of nullifying each one. Because in the other previous rows, the diagonal elements are already 1, we can use them to eliminate the sub diagonals easily by a matrix transformation:
A[2] = A[2] - A[2,0]* A[0]
A[2] = A[2] - A[2,1]* A[1]
For the Third Row, you have to follow the same pattern.
I hope this explanation would clear any confusion for anyone trying to understand the echelon form and matrices' transformations.
The reason why I did not post a full solution is that this exercise is a part of a Coursera course: Mathematics for Machine Learning: Linear Algebra. I have a correct code that passed the assignment but it would be counter-productive to post it.
Upvotes: 3