From 4047a43539be76ad838f937051da5f701fcac0c4 Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 12:28:33 +0530 Subject: [PATCH 1/7] add QR Decomposition of matrix in linear algebra --- linear_algebra/qr_decomposition.py | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 linear_algebra/qr_decomposition.py diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py new file mode 100644 index 000000000000..a76408c0f4ae --- /dev/null +++ b/linear_algebra/qr_decomposition.py @@ -0,0 +1,92 @@ +""" +In linear algebra, a QR decomposition, also known as a QR factorization or QU factorization, +is a decomposition of a matrix A into a product A = QR +of an orthonormal matrix Q and an upper triangular matrix R. +QR decomposition is often used to solve the linear least squares (LLS) problem +and is the basis for a particular eigenvalue algorithm, the QR algorithm. + +This algorithm will simply attempt to perform QR decomposition on any square matrix. + +Reference: https://en.wikipedia.org/wiki/QR_decomposition +""" + +from __future__ import annotations +import numpy as np +from scipy.linalg import qr + +def qr_decomposition(A: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """ + Perform QR decomposition on a given matrix and raises an error if in + m×n matrix A if m is smaller than n or m,n is less than 2 + + >>> A = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) + >>> Q,R = qr_decomposition(A) + >>> Q + array([[-0.17, 0.9 , 0.41], + [-0.51, 0.28, -0.82], + [-0.85, -0.35, 0.41]]) + >>> R + array([[-17.75, -9.63, -8.11], + [ 0. , 0.41, -0.41], + [ 0. , 0. , 0. ]]) + >>> A = np.array([[1, 2], [4, 5], [7, 8]]) + >>> Q,R = qr_decomposition(A) + >>> Q + array([[-0.21, 0.89, 0.41], + [-0.52, 0.25, -0.82], + [-0.83, -0.38, 0.41]]) + >>> R + array([[-9.64, -8.09], + [ 0. , -0.76], + [ 0. , 0. ]]) + >>> A = np.array([[1, 2, 3], [4, 5, 6]]) + >>> Q,R = qr_decomposition(A) + Traceback (most recent call last): + ... + ValueError: row size should be greater than column size + >>> A = np.array([[1], [4]]) + >>> Q,R = qr_decomposition(A) + Traceback (most recent call last): + ... + ValueError: row size and column size should be greater than 2 + >>> A = np.array([[1,4]]) + >>> Q,R = qr_decomposition(A) + Traceback (most recent call last): + ... + ValueError: row size should be greater than column size + """ + + + rows, columns = np.shape(A) + if rows < columns: + msg = ( + "row size should be greater than column size" + ) + raise ValueError(msg) + if rows < 2 or columns < 2: + msg = ( + "row size and column size should be greater than 2" + ) + raise ValueError(msg) + # Perform QR decomposition with pivoting + # Q: Orthogonal matrix + # R: Upper triangular matrix + # P: Pivot indices (permutation vector) + + Q, R, P = qr(A, pivoting=True) + + # Note: The bottom row of R is all zeros because the matrix is rank-deficient. + # Verification: A[:, P] should equal Q @ R + AP = A[:, P] + if(np.allclose(AP, Q @ R)): + return np.round(Q,2), np.round(R,2) + else: + msg = ( + "No matrix found which decompose given matrix" + ) + raise ValueError(msg) + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 58596f354608d9e993138a1c43e981b42da7bdf5 Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 12:41:29 +0530 Subject: [PATCH 2/7] changes in description and variable --- linear_algebra/qr_decomposition.py | 49 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index a76408c0f4ae..b48fc29d3452 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -1,6 +1,7 @@ """ -In linear algebra, a QR decomposition, also known as a QR factorization or QU factorization, -is a decomposition of a matrix A into a product A = QR +In linear algebra, a QR decomposition, also known as a QR factorization +or Q factorization, +is a decomposition of a matrix a into a product a = QR of an orthonormal matrix Q and an upper triangular matrix R. QR decomposition is often used to solve the linear least squares (LLS) problem and is the basis for a particular eigenvalue algorithm, the QR algorithm. @@ -14,50 +15,50 @@ import numpy as np from scipy.linalg import qr -def qr_decomposition(A: np.ndarray) -> tuple[np.ndarray, np.ndarray]: +def qr_decomposition(a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ Perform QR decomposition on a given matrix and raises an error if in - m×n matrix A if m is smaller than n or m,n is less than 2 + m×n matrix a if m is smaller than n or m,n is less than 2 - >>> A = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) - >>> Q,R = qr_decomposition(A) - >>> Q + >>> a = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) + >>> q,r = qr_decomposition(a) + >>> q array([[-0.17, 0.9 , 0.41], [-0.51, 0.28, -0.82], [-0.85, -0.35, 0.41]]) - >>> R + >>> r array([[-17.75, -9.63, -8.11], [ 0. , 0.41, -0.41], [ 0. , 0. , 0. ]]) - >>> A = np.array([[1, 2], [4, 5], [7, 8]]) - >>> Q,R = qr_decomposition(A) - >>> Q + >>> a = np.array([[1, 2], [4, 5], [7, 8]]) + >>> q,r = qr_decomposition(a) + >>> q array([[-0.21, 0.89, 0.41], [-0.52, 0.25, -0.82], [-0.83, -0.38, 0.41]]) - >>> R + >>> r array([[-9.64, -8.09], [ 0. , -0.76], [ 0. , 0. ]]) - >>> A = np.array([[1, 2, 3], [4, 5, 6]]) - >>> Q,R = qr_decomposition(A) + >>> a = np.array([[1, 2, 3], [4, 5, 6]]) + >>> q,r = qr_decomposition(a) Traceback (most recent call last): ... ValueError: row size should be greater than column size - >>> A = np.array([[1], [4]]) - >>> Q,R = qr_decomposition(A) + >>> a = np.array([[1], [4]]) + >>> q,r = qr_decomposition(a) Traceback (most recent call last): ... ValueError: row size and column size should be greater than 2 - >>> A = np.array([[1,4]]) - >>> Q,R = qr_decomposition(A) + >>> a = np.array([[1,4]]) + >>> q,r = qr_decomposition(a) Traceback (most recent call last): ... ValueError: row size should be greater than column size """ - rows, columns = np.shape(A) + rows, columns = np.shape(a) if rows < columns: msg = ( "row size should be greater than column size" @@ -73,13 +74,13 @@ def qr_decomposition(A: np.ndarray) -> tuple[np.ndarray, np.ndarray]: # R: Upper triangular matrix # P: Pivot indices (permutation vector) - Q, R, P = qr(A, pivoting=True) + q, r, p = qr(a, pivoting=True) # Note: The bottom row of R is all zeros because the matrix is rank-deficient. - # Verification: A[:, P] should equal Q @ R - AP = A[:, P] - if(np.allclose(AP, Q @ R)): - return np.round(Q,2), np.round(R,2) + # Verification: a[:, P] should equal Q @ R + ap = a[:, p] + if(np.allclose(ap, q @ r)): + return np.round(q,2), np.round(r,2) else: msg = ( "No matrix found which decompose given matrix" From 2d8f805e0e7c768716a525737b5977bf8cdbcb3c Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 13:11:18 +0530 Subject: [PATCH 3/7] changes in description and variable --- linear_algebra/qr_decomposition.py | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index b48fc29d3452..128b4370e396 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -1,7 +1,7 @@ """ In linear algebra, a QR decomposition, also known as a QR factorization or Q factorization, -is a decomposition of a matrix a into a product a = QR +is a decomposition of a matrix a into a product matrix_a = QR of an orthonormal matrix Q and an upper triangular matrix R. QR decomposition is often used to solve the linear least squares (LLS) problem and is the basis for a particular eigenvalue algorithm, the QR algorithm. @@ -15,50 +15,50 @@ import numpy as np from scipy.linalg import qr -def qr_decomposition(a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: +def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ Perform QR decomposition on a given matrix and raises an error if in m×n matrix a if m is smaller than n or m,n is less than 2 - >>> a = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) - >>> q,r = qr_decomposition(a) - >>> q + >>> matrix_a = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) + >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) + >>> matrix_q array([[-0.17, 0.9 , 0.41], [-0.51, 0.28, -0.82], [-0.85, -0.35, 0.41]]) - >>> r + >>> matrix_r array([[-17.75, -9.63, -8.11], [ 0. , 0.41, -0.41], [ 0. , 0. , 0. ]]) - >>> a = np.array([[1, 2], [4, 5], [7, 8]]) - >>> q,r = qr_decomposition(a) - >>> q + >>> matrix_a = np.array([[1, 2], [4, 5], [7, 8]]) + >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) + >>> matrix_q array([[-0.21, 0.89, 0.41], [-0.52, 0.25, -0.82], [-0.83, -0.38, 0.41]]) - >>> r + >>> matrix_r array([[-9.64, -8.09], [ 0. , -0.76], [ 0. , 0. ]]) - >>> a = np.array([[1, 2, 3], [4, 5, 6]]) - >>> q,r = qr_decomposition(a) + >>> matrix_a = np.array([[1, 2, 3], [4, 5, 6]]) + >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) Traceback (most recent call last): ... ValueError: row size should be greater than column size - >>> a = np.array([[1], [4]]) - >>> q,r = qr_decomposition(a) + >>> matrix_a = np.array([[1], [4]]) + >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) Traceback (most recent call last): ... ValueError: row size and column size should be greater than 2 - >>> a = np.array([[1,4]]) - >>> q,r = qr_decomposition(a) + >>> matrix_a = np.array([[1,4]]) + >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) Traceback (most recent call last): ... ValueError: row size should be greater than column size """ - rows, columns = np.shape(a) + rows, columns = np.shape(matrix_a) if rows < columns: msg = ( "row size should be greater than column size" @@ -70,17 +70,17 @@ def qr_decomposition(a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: ) raise ValueError(msg) # Perform QR decomposition with pivoting - # Q: Orthogonal matrix - # R: Upper triangular matrix - # P: Pivot indices (permutation vector) + # matrix_q: Orthogonal matrix + # matrix_v: Upper triangular matrix + # pivot: Pivot indices (permutation vector) - q, r, p = qr(a, pivoting=True) + matrix_q, matrix_r, pivot = qr(matrix_a, pivoting=True) - # Note: The bottom row of R is all zeros because the matrix is rank-deficient. - # Verification: a[:, P] should equal Q @ R - ap = a[:, p] - if(np.allclose(ap, q @ r)): - return np.round(q,2), np.round(r,2) + # Note: The bottom row of matrix_r is all zeros because the matrix is rank-deficient. + # Verification: matrix_a[:, pivot] should equal matrix_q @ matrix_r + permute_matrix = matrix_a[:, pivot] + if(np.allclose(permute_matrix, matrix_q @ matrix_r)): + return np.round(matrix_q,2), np.round(matrix_r,2) else: msg = ( "No matrix found which decompose given matrix" From 28ac77ca85480081e4baa2f40342f98f1a0cc4c7 Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 13:19:37 +0530 Subject: [PATCH 4/7] changes in description and variable --- linear_algebra/qr_decomposition.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index 128b4370e396..c9e11830f988 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -10,15 +10,14 @@ Reference: https://en.wikipedia.org/wiki/QR_decomposition """ - -from __future__ import annotations import numpy as np +from __future__ import annotations from scipy.linalg import qr def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ Perform QR decomposition on a given matrix and raises an error if in - m×n matrix a if m is smaller than n or m,n is less than 2 + rowXcolumn matrix a if row is smaller than column or row,column is less than 2 >>> matrix_a = np.array([[1, 2, 3], [4, 5, 9], [7, 8, 15]]) >>> (matrix_q,matrix_r) = qr_decomposition(matrix_a) @@ -71,12 +70,11 @@ def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: raise ValueError(msg) # Perform QR decomposition with pivoting # matrix_q: Orthogonal matrix - # matrix_v: Upper triangular matrix + # matrix_r: Upper triangular matrix # pivot: Pivot indices (permutation vector) matrix_q, matrix_r, pivot = qr(matrix_a, pivoting=True) - # Note: The bottom row of matrix_r is all zeros because the matrix is rank-deficient. # Verification: matrix_a[:, pivot] should equal matrix_q @ matrix_r permute_matrix = matrix_a[:, pivot] if(np.allclose(permute_matrix, matrix_q @ matrix_r)): From c25b7c42bd57321801c00ad0d2b16646f4f0deeb Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 14:49:46 +0530 Subject: [PATCH 5/7] add QR Decomposition of matrix in linear algebra --- linear_algebra/qr_decomposition.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index c9e11830f988..2f1f8988c06d 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -1,18 +1,14 @@ -""" -In linear algebra, a QR decomposition, also known as a QR factorization +"""In linear algebra, a QR decomposition, also known as a QR factorization or Q factorization, is a decomposition of a matrix a into a product matrix_a = QR of an orthonormal matrix Q and an upper triangular matrix R. QR decomposition is often used to solve the linear least squares (LLS) problem and is the basis for a particular eigenvalue algorithm, the QR algorithm. - This algorithm will simply attempt to perform QR decomposition on any square matrix. - -Reference: https://en.wikipedia.org/wiki/QR_decomposition -""" -import numpy as np +Reference: https://en.wikipedia.org/wiki/QR_decomposition""" from __future__ import annotations from scipy.linalg import qr +import numpy as np def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ @@ -88,4 +84,4 @@ def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: if __name__ == "__main__": import doctest - doctest.testmod() + doctest.testmod() \ No newline at end of file From f1c0a255d37927efe6730b75c59dc80c83556cd3 Mon Sep 17 00:00:00 2001 From: BhaktiVagadia Date: Thu, 7 May 2026 15:03:24 +0530 Subject: [PATCH 6/7] formate import block --- linear_algebra/qr_decomposition.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index 2f1f8988c06d..a9f5f1344bfd 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -6,9 +6,8 @@ and is the basis for a particular eigenvalue algorithm, the QR algorithm. This algorithm will simply attempt to perform QR decomposition on any square matrix. Reference: https://en.wikipedia.org/wiki/QR_decomposition""" -from __future__ import annotations -from scipy.linalg import qr import numpy as np +from scipy.linalg import qr def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ From 23a01a65b34bf7e0df382e777776c419bbcfdef1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 09:35:15 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- linear_algebra/qr_decomposition.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/linear_algebra/qr_decomposition.py b/linear_algebra/qr_decomposition.py index a9f5f1344bfd..621bcb6600e9 100644 --- a/linear_algebra/qr_decomposition.py +++ b/linear_algebra/qr_decomposition.py @@ -6,9 +6,11 @@ and is the basis for a particular eigenvalue algorithm, the QR algorithm. This algorithm will simply attempt to perform QR decomposition on any square matrix. Reference: https://en.wikipedia.org/wiki/QR_decomposition""" + import numpy as np from scipy.linalg import qr + def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """ Perform QR decomposition on a given matrix and raises an error if in @@ -51,17 +53,12 @@ def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: ValueError: row size should be greater than column size """ - rows, columns = np.shape(matrix_a) if rows < columns: - msg = ( - "row size should be greater than column size" - ) + msg = "row size should be greater than column size" raise ValueError(msg) if rows < 2 or columns < 2: - msg = ( - "row size and column size should be greater than 2" - ) + msg = "row size and column size should be greater than 2" raise ValueError(msg) # Perform QR decomposition with pivoting # matrix_q: Orthogonal matrix @@ -72,15 +69,14 @@ def qr_decomposition(matrix_a: np.ndarray) -> tuple[np.ndarray, np.ndarray]: # Verification: matrix_a[:, pivot] should equal matrix_q @ matrix_r permute_matrix = matrix_a[:, pivot] - if(np.allclose(permute_matrix, matrix_q @ matrix_r)): - return np.round(matrix_q,2), np.round(matrix_r,2) + if np.allclose(permute_matrix, matrix_q @ matrix_r): + return np.round(matrix_q, 2), np.round(matrix_r, 2) else: - msg = ( - "No matrix found which decompose given matrix" - ) + msg = "No matrix found which decompose given matrix" raise ValueError(msg) + if __name__ == "__main__": import doctest - doctest.testmod() \ No newline at end of file + doctest.testmod()