SOLVE_TRIANGULAR

Efficiently solves a linear system where the coefficient matrix A is either lower or upper triangular. This is much faster than the general solver and is routinely used in other algorithms after an LU or Cholesky decomposition.

Excel Usage

=SOLVE_TRIANGULAR(a_matrix, b_vector, lower, unit_diag)
  • a_matrix (list[list], required): Square triangular 2D array of numeric coefficients.
  • b_vector (list[list], required): 2D array representing the right-hand side.
  • lower (bool, optional, default: false): Whether A is a lower triangular matrix (TRUE) or upper triangular (FALSE).
  • unit_diag (bool, optional, default: false): If TRUE, diagonal elements of A are assumed to be 1 and are not referenced.

Returns (list[list]): 2D array representing the solution x.

Example 1: Solve upper triangular system

Inputs:

a_matrix b_vector lower
2 1 3 false
0 1 1

Excel formula:

=SOLVE_TRIANGULAR({2,1;0,1}, {3;1}, FALSE)

Expected output:

Result
1
1
Example 2: Solve lower triangular system

Inputs:

a_matrix b_vector lower
1 0 1 true
2 1 4

Excel formula:

=SOLVE_TRIANGULAR({1,0;2,1}, {1;4}, TRUE)

Expected output:

Result
1
2
Example 3: Solve upper triangular system with two right-hand sides

Inputs:

a_matrix b_vector lower
3 1 7 4 false
0 2 4 6

Excel formula:

=SOLVE_TRIANGULAR({3,1;0,2}, {7,4;4,6}, FALSE)

Expected output:

Result
1.66667 0.333333
2 3
Example 4: Solve lower triangular system with unit diagonal assumption

Inputs:

a_matrix b_vector lower unit_diag
1 0 0 1 true true
2 1 0 3
3 4 1 8

Excel formula:

=SOLVE_TRIANGULAR({1,0,0;2,1,0;3,4,1}, {1;3;8}, TRUE, TRUE)

Expected output:

Result
1
1
1

Python Code

import numpy as np
from scipy.linalg import solve_triangular as scipy_solve_triangular

def solve_triangular(a_matrix, b_vector, lower=False, unit_diag=False):
    """
    Solve the equation Ax = b for x, assuming A is a triangular matrix.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.solve_triangular.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        a_matrix (list[list]): Square triangular 2D array of numeric coefficients.
        b_vector (list[list]): 2D array representing the right-hand side.
        lower (bool, optional): Whether $A$ is a lower triangular matrix (TRUE) or upper triangular (FALSE). Default is False.
        unit_diag (bool, optional): If TRUE, diagonal elements of $A$ are assumed to be 1 and are not referenced. Default is False.

    Returns:
        list[list]: 2D array representing the solution x.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        a_matrix = to2d(a_matrix)
        b_vector = to2d(b_vector)

        if not isinstance(a_matrix, list) or not a_matrix or not all(isinstance(row, list) for row in a_matrix):
            return "Error: a_matrix must be a non-empty 2D list"

        n = len(a_matrix)
        if any(len(row) != n for row in a_matrix):
            return "Error: a_matrix must be square (n x n)"

        try:
            a = np.array(a_matrix, dtype=float)
            b = np.array(b_vector, dtype=float)
        except (ValueError, TypeError):
            return "Error: matrix entries must contain numeric values"

        if not np.all(np.isfinite(a)) or not np.all(np.isfinite(b)):
            return "Error: Input must contain only finite numbers"

        try:
            x = scipy_solve_triangular(a, b, lower=lower, unit_diagonal=unit_diag)
        except Exception as e:
            return f"Error: {str(e)}"

        return x.tolist()

    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Square triangular 2D array of numeric coefficients.
2D array representing the right-hand side.
Whether $A$ is a lower triangular matrix (TRUE) or upper triangular (FALSE).
If TRUE, diagonal elements of $A$ are assumed to be 1 and are not referenced.