Finding the Rank of a matrix manually isn"t a time taking process. So have you tried to do it in python. Show
So this is the recipe on how we can find the Rank of a Matrix. Step 1 - Loading LibraryWe have imported numpy which is needed. Step 2 - Creating a MatrixWe have created a matrix by using np.array with different values in it. Step 3 - Calculating RankWe have calculated rank of the matrix by using numpy function np.linalg.matrix_rank and passing the matrix through it. The rank of a Matrix is defined as the number of linearly independent columns present in a matrix. The number of linearly independent columns is always equal to the number of linearly independent rows. In this article, we are going to find Rank of a Matrix. There is an inbuilt function defined in numpy.linalg package as shown below, rank = numpy.linalg.matrix_rank(a) Python code to find rank of a matrix# Linear Algebra Learning Sequence # Rank of a Matrix import numpy as np a = np.array([[4,5,8], [7,1,4], [5,5,5], [2,3,6]]) rank = np.linalg.matrix_rank(a) print('Matrix : ', a) print('Rank of the given Matrix : ',rank) Output: Matrix : [[4 5 8] [7 1 4] [5 5 5] [2 3 6]] Rank of the given Matrix : 3 This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. You can’t perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. Like the previous post, once we decide to wean ourselves off numpy and scipy, NOT because we don’t love them (we do love them) or want to use them (we do want to use them), but mostly so that we can learn machine learning principles more deeply by understanding how to code the tools ourselves, all of those basic helper functions from the post on basic tools also become necessary. AND, understanding the math to coding steps for determinants IS actually slightly, if not VERY, helpful and insightful. Furthermore, a new data science expert acquaintance of mine, that I had the pleasure of hearing speak recently, stated something in his talk that stayed with me (and I paraphrase), “I continue to study linear algebra to gain more insights into machine learning and AI.” Such ongoing effort is very much the spirit of this blog. Math BackgroundI am a big fan of studying multiple references when learning, or reviewing, something important to me, so I don’t mind telling you that I reviewed the wiki page for determinants, and I personally felt that it is quite good. However, while this is going to look a bit like that page, I will be injecting my own personal slants on determinant steps with a view to the upcoming coding of those steps and will be constructively lazy. Also, as a starting “linear algebraish” note, this is for SQUARE matrices. Let’s start with a 2 x 2 matrix. Equations 1: A 2 x 2 Matrix A and the Method to Calculate It’s Determinant What’s is the above saying? For any 2 x 2 matrix, the determinant is a scalar value equal to the product of the main diagonal elements minus the product of it’s counter diagonal elements. I really wish that all size matrices could be calculated this easily. The post would be trivial at best if it was. And yet, in essence, the whole method does boil down to this basic operation AFTER you see how to get to this step many times over for larger and larger matrices. The steps that break the calculation of a determinant down to this point aren’t hard either. They’re actually quite simple, BUT they are NOT easy! If I were you, what I am about to show you, IF you’ve never seen it before, would scare my lazy self! However, PLEASE stay courageous in your endeavors to stay constructively lazy, because you will, I hope, be amazed at how few lines of code we need to break down into the steps required to calculate a determinant for any size matrix. However, there is an even better, more efficient, and faster way to find a determinant with some exceptional constructive laziness! I will be showing the math to code for both methods, AND we’ve essentially done most of the work for the second method in two previous recent blog posts. So, walking before we run, how would one find the determinant of a 3 x 3 matrix using the first (classical) method? A=\begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \vert A \vert = \begin{vmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{vmatrix} = a_{11} \begin{vmatrix} \square & \square & \square \\ \square & a_{22} & a_{23} \\ \square & a_{32} & a_{33} \end{vmatrix} -a_{12} \begin{vmatrix} \square & \square & \square \\ a_{21} & \square & a_{23} \\ a_{31} & \square & a_{33} \end{vmatrix} + a_{13} \begin{vmatrix} \square & \square & \square \\ a_{21} & a_{22} & \square \\ a_{31} & a_{32} & \square \end{vmatrix} = a_{11} \begin{vmatrix}a_{22} & a_{23} \\ a_{32} & a_{33} \end{vmatrix} -a_{12} \begin{vmatrix}a_{21} & a_{23} \\ a_{31} & a_{33} \end{vmatrix} + a_{13} \begin{vmatrix}a_{21} & a_{22} \\ a_{31} & a_{32} \end{vmatrix} \vert A \vert = a_{11} \cdot \lparen a_{22} \cdot a_{33} - a_{32} \cdot a_{23} \rparen -a_{12} \cdot \lparen a_{21} \cdot a_{33} - a_{31} \cdot a_{23} \rparen + a_{13} \cdot \lparen a_{21} \cdot a_{32} - a_{31} \cdot a_{22} \rparenEquations 2: A 3 x 3 Matrix A and the Methods to Calculate It’s Determinant That was a bit intimidating, and it gets worse for larger and larger matrices. If you mostly work with 3 x 3 matrices, you really want to know how to use the rule of Sarrus also, because it’s really simple to remember, and to calculate by hand, and to code if you want to. However, for those brave souls that came here to learn to do the real work of calculating a determinant for ANY size matrix, the rule of Sarrus is only a stepping stone to one location – the determinants for 3×3 matrices. Points to note from Equations 2:
I almost hate to point this out, but let’s be thorough here. You could also do, in essence, the same approach by starting with the first column instead of the first row:
You tough guys and gals who are more stoic and less constructively lazy than us mere mortal math people may be thinking, “Dang, Thom! You’re such a wimp!” While that’s true, maybe seeing the next step AND imagining going to larger and larger size matrices will cause you to cringe in mathematical laziness a bit more! A=\begin{bmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \end{bmatrix} \vert A \vert = \begin{vmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \end{vmatrix} = a_{11} \begin{vmatrix} \square & \square & \square & \square \\ \square & a_{22} & a_{23} & a_{24} \\ \square & a_{32} & a_{33} & a_{34} \\ \square & a_{42} & a_{43} & a_{44} \end{vmatrix} -a_{12} \begin{vmatrix} \square & \square & \square & \square \\ a_{21} & \square & a_{23} & a_{24} \\ a_{31} & \square & a_{33} & a_{34} \\ a_{41} & \square & a_{43} & a_{44} \end{vmatrix} + a_{13} \begin{vmatrix} \square & \square & \square & \square \\ a_{21} & a_{22} & \square & a_{24} \\ a_{31} & a_{32} & \square & a_{34} \\ a_{41} & a_{42} & \square & a_{44} \end{vmatrix} - a_{14} \begin{vmatrix} \square & \square & \square & \square \\ a_{21} & a_{22} & a_{23} & \square \\ a_{31} & a_{32} & a_{33} & \square \\ a_{41} & a_{42} & a_{43} & \square \end{vmatrix}Equations 3: A 4 x 4 Matrix A and the PART of the Methods to Calculate It’s Determinant. The one reason that I love the above is that it STRONGLY reminds me WHY I LOVE coding and symbolic math solvers! So, as the caption above says, the steps shown in Equations 3 merely help us get to the point where we can do the steps in Equations 2 for each submatrix of Equations 3, AND, as you’ve likely realized, Equations 2 actually include the steps of Equations 1 for each submatrix. Phew! I trust you to imagine what we’d do for n x n matrices where n > 4. Again, simple enough, but NOT easy! The CodeThanks to the power of recursive function calls (a function that cleverly calls itself at the right steps), we can code this method for any size square matrix in as few as 14 lines with a call to one additional function that is only 6 lines of code (white space and comments not included). Our recursive function is below. The repo version of this code is in LinearAlgebraPurePython.py. In that version, the function has MORE documentation and it’s formatted a bit differently. def determinant_recursive(A, total=0): # Section 1: store indices in list for row referencing indices = list(range(len(A))) # Section 2: when at 2x2 submatrices recursive calls end if len(A) == 2 and len(A[0]) == 2: val = A[0][0] * A[1][1] - A[1][0] * A[0][1] return val # Section 3: define submatrix for focus column and # call this function for fc in indices: # A) for each focus column, ... # find the submatrix ... As = copy_matrix(A) # B) make a copy, and ... As = As[1:] # ... C) remove the first row height = len(As) # D) for i in range(height): # E) for each remaining row of submatrix ... # remove the focus column elements As[i] = As[i][0:fc] + As[i][fc+1:] sign = (-1) ** (fc % 2) # F) # G) pass submatrix recursively sub_det = determinant_recursive(As) # H) total all returns from recursion total += sign * A[0][fc] * sub_det return total Let’s go through the code sections by number:
But wait Thom! You never explained the total = 0 default parameter in the initial call. I CONFESS – MORE LAZINESS! It could have been the first line of code actually, but I was just trying to save a line of code. Try it both ways. It works. As always, refactor to your liking. Now for testing. In the repo is a function that imports our LinearAlgebraPurePython.py module and numpy for checking this code (YES, my laziness DOES extend to using numpy as a gold standard check) and it’s called BasicToolsPractice.py. The lines applicable to our work in this post so far and the results applicable to these lines of code are shown below in the next two code blocks, respectively. Sorry if the 5×5 A matrix wraps on your screen. import LinearAlgebraPurePython as la import numpy as np A = [[-2,2,-3],[-1,1,3],[2,0,-1]] # Matrix from wiki Det = la.determinant_recursive(A) npDet = np.linalg.det(A) print("Determinant of A is", round(Det,9)) print("The Numpy Determinant of A is", round(npDet,9)) print() A = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] Det = la.determinant_recursive(A) npDet = np.linalg.det(A) print("Determinant of A is", Det) print("The Numpy Determinant of A is", npDet) print() A = [[1,2,3,4],[8,5,6,7],[9,12,10,11],[13,14,16,15]] Det = la.determinant_recursive(A) npDet = np.linalg.det(A) print("Determinant of A is", Det) print("The Numpy Determinant of A is", round(npDet,9)) print() A = [[1,2,3,4,1],[8,5,6,7,2],[9,12,10,11,3],[13,14,16,15,4],[10,8,6,4,2]] Det = la.determinant_recursive(A) npDet = np.linalg.det(A) print("Determinant of A is", Det) print("The Numpy Determinant of A is", round(npDet,9)) print() The next code block is output from the above: Determinant of A is 18 The Numpy Determinant of A is 18.0 Determinant of A is 0 The Numpy Determinant of A is 0.0 Determinant of A is -348 The Numpy Determinant of A is -348.0 Determinant of A is -240 The Numpy Determinant of A is -240.0 A More Efficient WayYou programmers that are into Big O thinking are cringing right now, and you should be! Yes, this gets expensive for ginormous matrices. There’s a much faster way for bigger matrices like I promised above. Please refer to my post on matrix inversion or solving a system of equations if you have not yet done so. To avoid offending Google and to help my early rankings to date, I wish to avoid repeating much of that material here. You needn’t read both posts; just read one. Or don’t. See if you first understand it from the little bit of math and code below and from the determinant wiki. The More Efficient MathPLEASE DON’T BE MAD AT ME! Why did I take us thru all that stuff above? One of many reasons was that showing the method above, besides possibly causing some of you recursive programming trauma, which is a right of programming passage, was to help you appreciate this method more! I can’t imagine that it didn’t work! A = \begin{bmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \end{bmatrix}, \,\,\,\,\, A_{M} = \begin{bmatrix} am_{11} & am_{12} & am_{13} & am_{14} \\ 0 & am_{22} & am_{23} & am_{24} \\ 0 & 0 & am_{33} & am_{34} \\ 0 & 0 & 0 & am_{44} \end{bmatrix} \vert A_{M} \vert = am_{11} \cdot am_{22} \cdot am_{33} \cdot am_{44}Equations 4: Matrix Determinant Method of First Creating an Upper Triangle Matrix thru Row Operations If we do row operations to put A (truly any size A) into upper triangle form, we need only calculate the product of the elements of the main diagonal to get the determinant. Geeks be excited! (Geek is a positive term in my vocabulary – be a Geek and be proud). Oh OH! In your technical textbooks, when the author would point out an important point and say that, “The proof is left as an exercise for the student?” MAN, DID I HATE THAT!!! If you visit the matrix inversion post or the solving a system of equations post, and then compare the math steps code below to the code from one of those posts, you’ll see how we’ve combined and simplified the steps, but I’ll still explain them here. Steps to Reduce Any Square Matrix to an Upper Triangle MatrixWe’ll move from left to right on the matrix columns, and each column will have an element from the main diagonal in it, of course, which we’ll call fd:
Once the matrix is in upper triangle form, the determinant is simply the product of all elements on the main diagonal. Is that easy to code? I hope that you think so. Here’s the code. Again, the documentation of the function in the module in the repo is more complete and formatted a little differently. def determinant_fast(A): # Section 1: Establish n parameter and copy A n = len(A) AM = copy_matrix(A) # Section 2: Row ops on A to get in upper triangle form for fd in range(n): # A) fd stands for focus diagonal for i in range(fd+1,n): # B) only use rows below fd row if AM[fd][fd] == 0: # C) if diagonal is zero ... AM[fd][fd] == 1.0e-18 # change to ~zero # D) cr stands for "current row" crScaler = AM[i][fd] / AM[fd][fd] # E) cr - crScaler * fdRow, one element at a time for j in range(n): AM[i][j] = AM[i][j] - crScaler * AM[fd][j] # Section 3: Once AM is in upper triangle form ... product = 1.0 for i in range(n): # ... product of diagonals is determinant product *= AM[i][i] return product No way! Yes. Let’s go through the numbered sections:
Now, let’s put this new determinant function into practice. Again, I am showing the applicable lines from the BasicToolsPractice.py file in the repo. import LinearAlgebraPurePython as la import numpy as np A = [[-2,2,-3],[-1,1,3],[2,0,-1]] # Matrix from wiki Det = la.determinant_fast(A) npDet = np.linalg.det(A) print("Determinant of A is", round(Det,9)) print("The Numpy Determinant of A is", round(npDet,9)) print() A = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] Det = la.determinant_fast(A) npDet = np.linalg.det(A) print("Determinant of A is", round(Det,9)+0) print("The Numpy Determinant of A is", round(npDet,9)) print() A = [[1,2,3,4],[8,5,6,7],[9,12,10,11],[13,14,16,15]] Det = la.determinant_fast(A) npDet = np.linalg.det(A) print("Determinant of A is", round(Det,9)) print("The Numpy Determinant of A is", round(npDet,9)) print() A = [[1,2,3,4,1],[8,5,6,7,2],[9,12,10,11,3],[13,14,16,15,4],[10,8,6,4,2]] Det = la.determinant_fast(A) npDet = np.linalg.det(A) print("Determinant of A is", round(Det,9)) print("The Numpy Determinant of A is", round(npDet,9)) print() And the results for those lines are … Determinant of A is 18.0 The Numpy Determinant of A is 18.0 Determinant of A is 0.0 The Numpy Determinant of A is 0.0 Determinant of A is -348.0 The Numpy Determinant of A is -348.0 Determinant of A is -240.0 The Numpy Determinant of A is -240.0 ClosingWith this post in place, and with all the previous posts (chronologically speaking that is and minus the MAD post), we finally have the tool set that we need to perform a Least Squares regression, which will be the next post. I really hope that you found some useful insights from this post. I believe the upcoming posts will begin to show the spirit of what we want to gain, insights wise, from this blog. And as always, please clone, refactor, and make the code your own! Until the next post … How do you find the rank of a matrix in Python?Step 1 - Loading Library. We have imported numpy which is needed. ... . Step 2 - Creating a Matrix. We have created a matrix by using np.array with different values in it. ... . Step 3 - Calculating Rank. We have calculated rank of the matrix by using numpy function np.linalg.matrix_rank and passing the matrix through it.. How do you find the rank of a matrix program?The rank of a unit matrix of order m is m. If A matrix is of order m×n, then ρ(A ) ≤ min{m, n } = minimum of m, n. If A is of order n×n and |A| ≠ 0, then the rank of A = n. If A is of order n×n and |A| = 0, then the rank of A will be less than n.
|