QR
QR decomposition factors a matrix into an orthogonal (or unitary) component and an upper-triangular component. It is commonly used in least-squares solving and numerical linear algebra workflows.
For a matrix A, the decomposition is:
A = QR
where Q is orthogonal (or unitary) and R is upper triangular.
Excel Usage
=QR(a, return_type)
a(list[list], required): Matrix to decompose. Each row must have the same number of columns, and entries must be finite numeric values.return_type(str, optional, default: “Q”): Which matrix factor to return from the QR decomposition.
Returns (list[list]): 2D Q or R matrix, or error message string.
Example 1: Orthogonal factor of a 2x2 matrix
Inputs:
| a | return_type | |
|---|---|---|
| 1 | 2 | Q |
| 3 | 4 |
Excel formula:
=QR({1,2;3,4}, "Q")
Expected output:
| Result | |
|---|---|
| -0.316228 | -0.948683 |
| -0.948683 | 0.316228 |
Example 2: Upper-triangular factor of a 2x2 matrix
Inputs:
| a | return_type | |
|---|---|---|
| 1 | 2 | R |
| 3 | 4 |
Excel formula:
=QR({1,2;3,4}, "R")
Expected output:
| Result | |
|---|---|
| -3.16228 | -4.42719 |
| 0 | -0.632456 |
Example 3: Orthogonal factor of a 3x2 rectangular matrix
Inputs:
| a | return_type | |
|---|---|---|
| 1 | 2 | Q |
| 3 | 4 | |
| 5 | 6 |
Excel formula:
=QR({1,2;3,4;5,6}, "Q")
Expected output:
| Result | ||
|---|---|---|
| -0.169031 | 0.897085 | 0.408248 |
| -0.507093 | 0.276026 | -0.816497 |
| -0.845154 | -0.345033 | 0.408248 |
Example 4: Upper-triangular factor of a 3x2 rectangular matrix
Inputs:
| a | return_type | |
|---|---|---|
| 1 | 2 | R |
| 3 | 4 | |
| 5 | 6 |
Excel formula:
=QR({1,2;3,4;5,6}, "R")
Expected output:
| Result | |
|---|---|
| -5.91608 | -7.43736 |
| 0 | 0.828079 |
| 0 | 0 |
Python Code
import numpy as np
from scipy.linalg import qr as scipy_linalg_qr
def qr(a, return_type='Q'):
"""
Compute the QR decomposition of a matrix and return either Q or R.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.qr.html
This example function is provided as-is without any representation of accuracy.
Args:
a (list[list]): Matrix to decompose. Each row must have the same number of columns, and entries must be finite numeric values.
return_type (str, optional): Which matrix factor to return from the QR decomposition. Valid options: Q, R. Default is 'Q'.
Returns:
list[list]: 2D Q or R matrix, or error message string.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
# Normalize scalar inputs into a 2D list structure
a = to2d(a)
if not isinstance(a[0], list):
# Handle case where input was a 1D list like [1, 2, 3]
if all(not isinstance(item, list) for item in a):
try:
a = [[float(item)] for item in a]
except (TypeError, ValueError):
return "Error: Invalid input: a must contain only numeric values."
# Validate the 2D list structure and ensure consistent row lengths
if not a or not all(isinstance(row, list) for row in a):
return "Error: Invalid input: a must be a 2D list with at least one row."
if any(len(row) == 0 for row in a):
return "Error: Invalid input: rows in a must contain at least one value."
column_count = len(a[0])
if any(len(row) != column_count for row in a):
return "Error: Invalid input: all rows in a must have the same length."
# Convert entries to floats and check for finite values
numeric_rows = []
for row in a:
numeric_row = []
for value in row:
try:
numeric_value = float(value)
except Exception:
return "Error: Invalid input: a must contain only numeric values."
if not np.isfinite(numeric_value):
return "Error: Invalid input: a must contain only finite numbers."
numeric_row.append(numeric_value)
numeric_rows.append(numeric_row)
array = np.array(numeric_rows, dtype=float)
# Validate return_type and normalize casing
if not isinstance(return_type, str) or return_type.upper() not in ("Q", "R"):
return "Error: Invalid input: return_type must be 'Q' or 'R'."
normalized_return_type = return_type.upper()
# Compute the QR decomposition
try:
q_matrix, r_matrix = scipy_linalg_qr(array, mode="full")
except Exception as exc:
return f"Error: QR decomposition error: {exc}"
result = q_matrix if normalized_return_type == "Q" else r_matrix
# Ensure the result is finite before returning
if not np.all(np.isfinite(result)):
return "Error: QR decomposition error: result contains non-finite values."
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Matrix to decompose. Each row must have the same number of columns, and entries must be finite numeric values.
Which matrix factor to return from the QR decomposition.