8
$\begingroup$

I'm working on a linear algebra homework for a data science class. I'm suppose to make this matrix into row echelon form but I'm stuck.

Here's the current output

I would like to get rid of -0.75, 0.777, and 1.333 in A[2,0], A[3,0], and A[3,1] respectively; they should be zeroed out.

Below is my current code... can anybody please nudge me in the right direction and tell me what step I'm missing?

import numpy as np

def fixRowTwo(A) :

    # Sets the sub-diagonal elements of row two to zero
    A[2] = A[2] - A[2,0] * A[1]
    A[2] = A[2] - A[2,1] * A[1]

    # Test if diagonal element is not zero.
    if A[2,2] == 0 :
        # Add a lower row to row two.
        A[2] = A[2] + A[3]

        # Sets the sub-diagonal elements to zero again ???
        A[2] = A[2] - A[2,0] * A[1]
        A[2] = A[2] - A[2,1] * A[1]

    if A[2,2] == 0 :
        print("S I N G U L A R")
        sys.Exit()

    # Set the diagonal element to one
    A[2] = A[2] / A[2,2]

    return A

def fixRowThree(A) :

    # Sets the sub-diagonal elements of row two to zero
    A[3] = A[3] - A[3,0] * A[2]
    A[3] = A[3] - A[3,1] * A[2]
    A[3] = A[3] - A[3,2] * A[2]    

    # Test if diagonal element is not zero.
    if A[3,3] == 0:
        print("S I N G U L A R")
        sys.Exit()

    # Set the diagonal element to one
    A[3] = A[3] / A[3,3]

    return A

A = np.array([
        [1, 7, 4, 3],
        [0, 1, 2, 3],
        [3, 2, 0, 3],
        [1, 3, 1, 3]
    ], dtype=np.float_)

fixRowTwo(A)
print("")
print("Row Two:")
print(A)

fixRowThree(A)
print("")
print("Row Three:")
print(A)



$\endgroup$

2 Answers 2

11
$\begingroup$

Since the Gaussian process is recursive, we utilize it in the code.

import numpy as np

def row_echelon(A):
    """ Return Row Echelon Form of matrix A """

    # if matrix A has no columns or rows,
    # it is already in REF, so we return itself
    r, c = A.shape
    if r == 0 or c == 0:
        return A

    # we search for non-zero element in the first column
    for i in range(len(A)):
        if A[i,0] != 0:
            break
    else:
        # if all elements in the first column is zero,
        # we perform REF on matrix from second column
        B = row_echelon(A[:,1:])
        # and then add the first zero-column back
        return np.hstack([A[:,:1], B])

    # if non-zero element happens not in the first row,
    # we switch rows
    if i > 0:
        ith_row = A[i].copy()
        A[i] = A[0]
        A[0] = ith_row

    # we divide first row by first element in it
    A[0] = A[0] / A[0,0]
    # we subtract all subsequent rows with first row (it has 1 now as first element)
    # multiplied by the corresponding element in the first column
    A[1:] -= A[0] * A[1:,0:1]

    # we perform REF on matrix from second row, from second column
    B = row_echelon(A[1:,1:])

    # we add first row and first (zero) column, and return
    return np.vstack([A[:1], np.hstack([A[1:,:1], B]) ])

A = np.array([[4, 7, 3, 8],
              [8, 3, 8, 7],
              [2, 9, 5, 3]], dtype='float')

row_echelon(A)

Feel free to add something like print(A[1:,:1]) if you don't understand some of the constructions

$\endgroup$
1
  • $\begingroup$ I added A = A.copy() at the start to return a new matrix and leave the pass matrix untouched. I also wanted a RREF matrix and so added the following lines to the end: A = np.vstack...; for n in range(1, len(A)): A[n-1::-1] -= A[n] * A[n-1::-1, n:n+1]; return A. Thanks for the helpful example and code. $\endgroup$
    – Harvey
    Jan 31 at 4:11
1
$\begingroup$

I've edited the code very slightly, the only mistake you've made really is at the part where you would eliminate the product of the previous rows and the element in current row. I have commented the parts where you should change that.

import numpy as np

def fixRowTwo(A) :

    # Sets the sub-diagonal elements of row two to zero
    A[2] = A[2] - A[2,0] * A[0] ## Change this to A[0] instead of A[1]
    A[2] = A[2] - A[2,1] * A[1]

    # Test if diagonal element is not zero.
    if A[2,2] == 0 :
        # Add a lower row to row two.
        A[2] = A[2] + A[3]

        # Sets the sub-diagonal elements to zero again ???
        A[2] = A[2] - A[2,0] * A[0] ## Same as earlier
        A[2] = A[2] - A[2,1] * A[1]

    if A[2,2] == 0 :
        print("S I N G U L A R")
        sys.Exit()

    # Set the diagonal element to one
    A[2] = A[2] / A[2,2]

    return A

def fixRowThree(A) :

    # Sets the sub-diagonal elements of row two to zero
    A[3] = A[3] - A[3,0] * A[0] ## Similar to above, change this to A[0]
    A[3] = A[3] - A[3,1] * A[1] ## Change to A[1]
    A[3] = A[3] - A[3,2] * A[2]    

    # Test if diagonal element is not zero.
    if A[3,3] == 0:
        print("S I N G U L A R")
        sys.Exit()

    # Set the diagonal element to one
    A[3] = A[3] / A[3,3]

    return A

A = np.array([
        [1, 7, 4, 3],
        [0, 1, 2, 3],
        [3, 2, 0, 3],
        [1, 3, 1, 3]
    ], dtype=np.float_)

fixRowTwo(A)
print("")
print("Row Two:")
print(A)

fixRowThree(A)
print("")
print("Row Three:")
print(A)
```
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .