Equations

Overview

Systems of linear equations sit at the core of scientific computing, statistics, and engineering simulation because many models reduce to solving Ax=b or fitting Ax\approx b. In practical workflows, linear equation solving is less about one formula and more about choosing the right numerical method for matrix structure, noise, and constraints. This category focuses on robust computational approaches for exact solves, structured solves, and least-squares approximations. These methods matter because they directly affect runtime, stability, and solution quality in data pipelines.

The common foundation is balancing algebraic correctness with numerical conditioning. Exact solvers target square systems with unique solutions, while least-squares solvers minimize residual error when systems are overdetermined, inconsistent, or rank-deficient. A central objective is \min_x \|Ax-b\|_2 (or bounded variants), and specialized structure such as banded, Toeplitz, or triangular form reduces complexity compared with generic dense methods. In other words, the best routine depends on both the equation type and the matrix geometry.

These tools are implemented with SciPy, primarily through scipy.linalg and scipy.optimize. SciPy wraps optimized BLAS/LAPACK kernels and exposes stable APIs for dense and structured linear algebra, making it a standard choice for production numerical Python workflows.

For least-squares modeling, LSQ_LINEAR and LSTSQ cover two complementary use cases. LSQ_LINEAR solves bounded linear least-squares problems, so it is useful when parameters must respect physical or business limits (for example, nonnegative coefficients or capped allocations). LSTSQ solves unconstrained least-squares and can also report residual diagnostics, rank, and singular values for model assessment. Together they support regression-style fitting, calibration, and inverse problems where an exact equation solution is unavailable or undesirable.

For general dense square systems, SOLVE is the direct workhorse. It computes x from Ax=b using matrix factorizations appropriate to the input assumptions, and it is typically the first choice when the system is well-posed and not highly structured. Typical applications include network balance equations, discretized physical models, and repeated solves in optimization loops. When matrix structure is unknown or mixed, SOLVE provides the most broadly applicable baseline.

For structure-exploiting workflows, SOLVE_BANDED, SOLVE_TOEPLITZ, and SOLVE_TRIANGULAR improve efficiency and numerical behavior by avoiding unnecessary dense operations. SOLVE_BANDED targets matrices with narrow diagonals, common in finite-difference and time-stepping discretizations. SOLVE_TOEPLITZ uses constant-diagonal structure that appears in signal processing, autocorrelation systems, and some convolution-based models. SOLVE_TRIANGULAR performs forward/back substitution on triangular factors and is a key inner step after decompositions such as LU or Cholesky.

LSQ_LINEAR

This function solves a linear least-squares optimization problem with optional lower and upper bounds on the decision variables. It finds the vector that minimizes squared residual error while respecting variable limits.

The optimization problem is:

\min_x \; \frac{1}{2}\lVert Ax - b \rVert_2^2 \quad \text{subject to} \quad l \le x \le u

where A is the coefficient matrix, b is the observation vector, and l,u are optional bounds.

Excel Usage

=LSQ_LINEAR(a_matrix, b_vector, bounds_lower, bounds_upper, lsq_linear_method, tol, max_iter)
  • a_matrix (list[list], required): Coefficient matrix A (m x n) with one row per equation.
  • b_vector (list[list], required): Observation vector b (m x 1) with one entry per row of A.
  • bounds_lower (list[list], optional, default: null): Lower bounds for each variable (1 x n row vector).
  • bounds_upper (list[list], optional, default: null): Upper bounds for each variable (1 x n row vector).
  • lsq_linear_method (str, optional, default: “trf”): Solver method to use for optimization.
  • tol (float, optional, default: 1e-10): Tolerance for termination (must be positive).
  • max_iter (int, optional, default: null): Maximum number of iterations for the solver.

Returns (list[list]): 2D list [[x1, x2, …, cost]], or error message string.

Example 1: Identity matrix with exact solution

Inputs:

a_matrix b_vector
1 0 1
0 1 2

Excel formula:

=LSQ_LINEAR({1,0;0,1}, {1;2})

Expected output:

Result
1 2 0
Example 2: Bounded solution with constraints

Inputs:

a_matrix b_vector bounds_lower bounds_upper
1 0 5 0 -2 3 0
0 1 -1

Excel formula:

=LSQ_LINEAR({1,0;0,1}, {5;-1}, {0,-2}, {3,0})

Expected output:

Result
3 -1 2
Example 3: Overdetermined system with BVLS solver

Inputs:

a_matrix b_vector lsq_linear_method
1 1 1 bvls
1 2 2
1 3 2

Excel formula:

=LSQ_LINEAR({1,1;1,2;1,3}, {1;2;2}, "bvls")

Expected output:

Result
0.666667 0.5 0.0833333
Example 4: Custom tolerance and max iterations

Inputs:

a_matrix b_vector bounds_lower bounds_upper tol max_iter
2 -1 1 -1 -1 2 2 1e-8 200
1 1 3
1 -1 0

Excel formula:

=LSQ_LINEAR({2,-1;1,1;1,-1}, {1;3;0}, {-1,-1}, {2,2}, 1e-8, 200)

Expected output:

Result
1.35714 1.57143 0.0357143

Python Code

Show Code
import numpy as np
from scipy.optimize import lsq_linear as scipy_lsq_linear

def lsq_linear(a_matrix, b_vector, bounds_lower=None, bounds_upper=None, lsq_linear_method='trf', tol=1e-10, max_iter=None):
    """
    Solve a bounded linear least-squares problem.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.lsq_linear.html

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

    Args:
        a_matrix (list[list]): Coefficient matrix A (m x n) with one row per equation.
        b_vector (list[list]): Observation vector b (m x 1) with one entry per row of A.
        bounds_lower (list[list], optional): Lower bounds for each variable (1 x n row vector). Default is None.
        bounds_upper (list[list], optional): Upper bounds for each variable (1 x n row vector). Default is None.
        lsq_linear_method (str, optional): Solver method to use for optimization. Valid options: Trust Region Reflective, Bounded Variable Least Squares. Default is 'trf'.
        tol (float, optional): Tolerance for termination (must be positive). Default is 1e-10.
        max_iter (int, optional): Maximum number of iterations for the solver. Default is None.

    Returns:
        list[list]: 2D list [[x1, x2, ..., cost]], or error message string.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        # Normalize 2D list inputs
        a_matrix = to2d(a_matrix)
        b_vector = to2d(b_vector)

        # Validate coefficient matrix
        try:
            a_mat = np.array(a_matrix, dtype=float)
        except Exception:
            return "Error: Invalid input: a_matrix must be a 2D list of numeric values."
        if a_mat.ndim != 2:
            return "Error: Invalid input: a_matrix must be two-dimensional."

        # Validate observation vector
        try:
            b_vec = np.array(b_vector, dtype=float).flatten()
        except Exception:
            return "Error: Invalid input: b_vector must be a 2D list of numeric values."
        if b_vec.size != a_mat.shape[0]:
            return "Error: Invalid input: Length of b_vector must equal number of rows in a_matrix."

        n_vars = a_mat.shape[1]

        # Process bounds
        lower = None
        upper = None
        if bounds_lower is not None:
            bounds_lower = to2d(bounds_lower)
            try:
                lower_array = np.array(bounds_lower, dtype=float)
                lower = lower_array.flatten() if lower_array.ndim > 1 else lower_array
            except Exception:
                return "Error: Invalid input: bounds_lower must contain numeric values."
            if lower.size != n_vars:
                return "Error: Invalid input: bounds_lower must have one value per variable."
        if bounds_upper is not None:
            bounds_upper = to2d(bounds_upper)
            try:
                upper_array = np.array(bounds_upper, dtype=float)
                upper = upper_array.flatten() if upper_array.ndim > 1 else upper_array
            except Exception:
                return "Error: Invalid input: bounds_upper must contain numeric values."
            if upper.size != n_vars:
                return "Error: Invalid input: bounds_upper must have one value per variable."

        if lower is not None and upper is not None:
            if np.any(lower > upper):
                return "Error: Invalid input: Each lower bound must be less than or equal to the corresponding upper bound."

        if lower is None:
            lower = np.full(n_vars, -np.inf)
        if upper is None:
            upper = np.full(n_vars, np.inf)

        bounds = (lower, upper)

        # Validate method
        valid_methods = {'trf', 'bvls'}
        if lsq_linear_method not in valid_methods:
            return f"Error: Invalid method: {lsq_linear_method}. Must be one of: {', '.join(sorted(valid_methods))}"

        # Validate tolerance and max_iter
        try:
            tol = float(tol)
        except (TypeError, ValueError):
            return "Error: Invalid input: tol must be a float."
        if tol <= 0:
            return "Error: Invalid input: tol must be positive."

        max_iter_param = None
        if max_iter is not None:
            try:
                max_iter_param = int(max_iter)
            except (TypeError, ValueError):
                return "Error: Invalid input: max_iter must be an integer."
            if max_iter_param <= 0:
                return "Error: Invalid input: max_iter must be positive."

        try:
            result = scipy_lsq_linear(
                a_mat,
                b_vec,
                bounds=bounds,
                method=lsq_linear_method,
                tol=tol,
                max_iter=max_iter_param,
            )
        except ValueError as exc:
            return f"Error during lsq_linear: {exc}"
        except Exception as exc:
            return f"Error during lsq_linear: {exc}"

        if not result.success:
            return f"Error: lsq_linear failed: {result.message}"

        try:
            solution_vector = [float(val) for val in result.x]
        except (TypeError, ValueError):
            return "Error: Error converting solution vector to floats."

        cost = float(result.cost) if result.cost is not None else float(np.sum((a_mat @ result.x - b_vec) ** 2) / 2.0)

        return [solution_vector + [cost]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Coefficient matrix A (m x n) with one row per equation.
Observation vector b (m x 1) with one entry per row of A.
Lower bounds for each variable (1 x n row vector).
Upper bounds for each variable (1 x n row vector).
Solver method to use for optimization.
Tolerance for termination (must be positive).
Maximum number of iterations for the solver.

LSTSQ

Least squares finds an approximate solution to an overdetermined or inconsistent linear system by minimizing residual error between observed values and model predictions.

The objective is:

\min_x \; \lVert Ax - b \rVert_2

This function uses SciPy’s LAPACK-backed solver and can return the solution, residual norm data, effective rank, or singular values of the coefficient matrix.

Excel Usage

=LSTSQ(a, b, cond, lstsq_driver, lstsq_return)
  • a (list[list], required): Coefficient matrix (M x N) for the linear equation system
  • b (list[list], required): Right-hand side matrix (M x K) with same number of rows as a
  • cond (float, optional, default: null): Cutoff for small singular values; values below cond * largest_singular_value are treated as zero
  • lstsq_driver (str, optional, default: “gelsd”): LAPACK driver to use for the computation
  • lstsq_return (str, optional, default: “solution”): The type of result to return from the computation

Returns (list[list]): 2D list of least squares result, or error message string.

Example 1: Least-squares solution using GELSD driver

Inputs:

a b cond lstsq_driver lstsq_return
1 1 0 2 1e-10 gelsd solution
1 0 1 2
1 1 1 3
1 0 0 1

Excel formula:

=LSTSQ({1,1,0;1,0,1;1,1,1;1,0,0}, {2;2;3;1}, 1e-10, "gelsd", "solution")

Expected output:

Result
1
1
1
Example 2: Sum of squared residuals for overdetermined system

Inputs:

a b cond lstsq_driver lstsq_return
1 1 0 2 1e-10 gelsd residuals
1 0 1 2
1 1 1 3
1 0 0 1

Excel formula:

=LSTSQ({1,1,0;1,0,1;1,1,1;1,0,0}, {2;2;3;1}, 1e-10, "gelsd", "residuals")

Expected output:

1.2326e-32

Example 3: Effective rank of coefficient matrix

Inputs:

a b cond lstsq_driver lstsq_return
1 1 0 2 1e-10 gelsd rank
1 0 1 2
1 1 1 3
1 0 0 1

Excel formula:

=LSTSQ({1,1,0;1,0,1;1,1,1;1,0,0}, {2;2;3;1}, 1e-10, "gelsd", "rank")

Expected output:

3

Example 4: Singular values of coefficient matrix

Inputs:

a b cond lstsq_driver lstsq_return
1 1 0 2 1e-10 gelsd singular_values
1 0 1 2
1 1 1 3
1 0 0 1

Excel formula:

=LSTSQ({1,1,0;1,0,1;1,1,1;1,0,0}, {2;2;3;1}, 1e-10, "gelsd", "singular_values")

Expected output:

Result
2.52434 1 0.792287

Python Code

Show Code
import numpy as np
from scipy.linalg import lstsq as scipy_linalg_lstsq

def lstsq(a, b, cond=None, lstsq_driver='gelsd', lstsq_return='solution'):
    """
    Compute the least-squares solution to Ax = B using scipy.linalg.lstsq.

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

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

    Args:
        a (list[list]): Coefficient matrix (M x N) for the linear equation system
        b (list[list]): Right-hand side matrix (M x K) with same number of rows as a
        cond (float, optional): Cutoff for small singular values; values below cond * largest_singular_value are treated as zero Default is None.
        lstsq_driver (str, optional): LAPACK driver to use for the computation Valid options: GELSD, GELSY, GELSS. Default is 'gelsd'.
        lstsq_return (str, optional): The type of result to return from the computation Valid options: Solution, Residuals, Rank, Singular Values. Default is 'solution'.

    Returns:
        list[list]: 2D list of least squares result, or error message string.
    """
    try:
        # Helper to normalize scalar/single-element inputs to 2D lists
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        # Wrap scalar inputs coming from Excel into 2D lists
        a = to2d(a)
        b = to2d(b)

        # Validate matrix structure for a and b
        for name, matrix in (("a", a), ("b", b)):
            if not isinstance(matrix, list) or len(matrix) == 0:
                return f"Error: Invalid input: {name} must be a 2D list with at least one row."
            row_length = len(matrix[0]) if isinstance(matrix[0], list) else 0
            if row_length == 0:
                return f"Error: Invalid input: {name} must be a 2D list with at least one column."
            for row in matrix:
                if not isinstance(row, list):
                    return f"Error: Invalid input: {name} must be a 2D list with rows represented as lists."
                if len(row) != row_length:
                    return f"Error: Invalid input: each row in {name} must have the same length."

        if len(a) != len(b):
            return "Error: Invalid input: a and b must have the same number of rows."

        # Convert matrices to numeric numpy arrays
        try:
            a_arr = np.array([[float(value) for value in row] for row in a], dtype=float)
            b_arr = np.array([[float(value) for value in row] for row in b], dtype=float)
        except Exception:
            return "Error: Invalid input: a and b must contain numeric values."

        # Validate optional parameters
        if cond is not None:
            try:
                cond = float(cond)
            except Exception:
                return "Error: Invalid input: cond must be a float or None."

        driver = str(lstsq_driver).strip().lower()
        if driver not in {"gelsd", "gelsy", "gelss"}:
            return "Error: Invalid input: lstsq_driver must be 'gelsd', 'gelsy', or 'gelss'."

        result_type = str(lstsq_return).strip().lower()
        if result_type not in {"solution", "residuals", "rank", "singular_values"}:
            return "Error: Invalid input: lstsq_return must be one of 'solution', 'residuals', 'rank', 'singular_values'."

        # Execute SciPy least-squares solver
        try:
            solution, residuals, effective_rank, singular_values = scipy_linalg_lstsq(
                a_arr,
                b_arr,
                cond=cond,
                lapack_driver=driver,
            )
        except Exception as exc:
            return f"Error: scipy.linalg.lstsq error: {exc}"

        # Helper to ensure outputs are finite and 2D
        def finite_matrix(values, as_column=False):
            array = np.asarray(values, dtype=float)
            if array.ndim == 0:
                array = array.reshape(1, 1)
            elif array.ndim == 1:
                if as_column:
                    array = array.reshape(-1, 1)
                else:
                    array = array.reshape(1, -1)
            if array.size == 0:
                return [[]]
            if not np.isfinite(array).all():
                return "Error: scipy.linalg.lstsq error: non-finite result encountered."
            return array.tolist()

        if result_type == "solution":
            return finite_matrix(solution, as_column=True)
        if result_type == "residuals":
            return finite_matrix(residuals)
        if result_type == "rank":
            return finite_matrix(float(effective_rank))
        if result_type == "singular_values":
            if singular_values is None:
                return "Error: Invalid input: singular values are unavailable for the selected LAPACK driver."
            return finite_matrix(singular_values)
        return "Error: Invalid input: lstsq_return must be one of 'solution', 'residuals', 'rank', 'singular_values'."
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Coefficient matrix (M x N) for the linear equation system
Right-hand side matrix (M x K) with same number of rows as a
Cutoff for small singular values; values below cond * largest_singular_value are treated as zero
LAPACK driver to use for the computation
The type of result to return from the computation

SOLVE

Computes the exact solution of the linear system Ax = b for the unknown x. The matrix A must be square and non-singular. The function supports various matrix types (general, symmetric, Hermitian, positive definite) which can be specified to use optimized solvers.

Excel Usage

=SOLVE(a_matrix, b_vector, assume_a)
  • a_matrix (list[list], required): Square 2D array of numeric coefficients.
  • b_vector (list[list], required): 2D array representing the right-hand side (can be a vector or matrix).
  • assume_a (str, optional, default: “gen”): Type of matrix A to assume (allows using optimized solvers).

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

Example 1: Solve 2x2 system

Inputs:

a_matrix b_vector
3 1 9
1 2 8

Excel formula:

=SOLVE({3,1;1,2}, {9;8})

Expected output:

Result
2
3
Example 2: Solve with positive definite assumption

Inputs:

a_matrix b_vector assume_a
2 -1 0 1 pos
-1 2 -1 0
0 -1 2 1

Excel formula:

=SOLVE({2,-1,0;-1,2,-1;0,-1,2}, {1;0;1}, "pos")

Expected output:

Result
1
1
1
Example 3: Solve with matrix right-hand side

Inputs:

a_matrix b_vector
1 2 5 6
3 4 7 8

Excel formula:

=SOLVE({1,2;3,4}, {5,6;7,8})

Expected output:

Result
-3 -4
4 5

Python Code

Show Code
import numpy as np
from scipy.linalg import solve as scipy_solve

def solve(a_matrix, b_vector, assume_a='gen'):
    """
    Solve a linear matrix equation, or system of linear scalar equations.

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

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

    Args:
        a_matrix (list[list]): Square 2D array of numeric coefficients.
        b_vector (list[list]): 2D array representing the right-hand side (can be a vector or matrix).
        assume_a (str, optional): Type of matrix $A$ to assume (allows using optimized solvers). Valid options: General, Symmetric, Hermitian, Positive Definite. Default is 'gen'.

    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(a, b, assume_a=assume_a.lower())
        except np.linalg.LinAlgError as e:
            return f"Error: Linear algebra solver failed: {str(e)}"
        except Exception as e:
            return f"Error: {str(e)}"

        return x.tolist()

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

Online Calculator

Square 2D array of numeric coefficients.
2D array representing the right-hand side (can be a vector or matrix).
Type of matrix $A$ to assume (allows using optimized solvers).

SOLVE_BANDED

Solves a linear system where the coefficient matrix A is banded. Banded matrices only have non-zero elements in a few diagonals around the main diagonal, which allows for significantly reduced storage and computation time. The matrix must be provided in the ‘ab’ format used by LAPACK.

Excel Usage

=SOLVE_BANDED(l_diags, u_diags, ab_matrix, b_vector)
  • l_diags (int, required): Number of non-zero lower diagonals.
  • u_diags (int, required): Number of non-zero upper diagonals.
  • ab_matrix (list[list], required): The banded matrix in ‘ab’ format (shape is l + u + 1 by M).
  • b_vector (list[list], required): 2D array representing the right-hand side.

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

Example 1: Solve diagonal matrix (special case of banded)

Inputs:

l_diags u_diags ab_matrix b_vector
0 0 2 3 4
9

Excel formula:

=SOLVE_BANDED(0, 0, {2,3}, {4;9})

Expected output:

Result
2
3
Example 2: Solve banded system (1 lower, 1 upper)

Inputs:

l_diags u_diags ab_matrix b_vector
1 1 0 1 1 1
2 2 2 1
1 1 0 1

Excel formula:

=SOLVE_BANDED(1, 1, {0,1,1;2,2,2;1,1,0}, {1;1;1})

Expected output:

Result
0.5
0
0.5

Python Code

Show Code
import numpy as np
from scipy.linalg import solve_banded as scipy_solve_banded

def solve_banded(l_diags, u_diags, ab_matrix, b_vector):
    """
    Solve the equation Ax = b for x, assuming A is a banded matrix.

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

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

    Args:
        l_diags (int): Number of non-zero lower diagonals.
        u_diags (int): Number of non-zero upper diagonals.
        ab_matrix (list[list]): The banded matrix in 'ab' format (shape is l + u + 1 by M).
        b_vector (list[list]): 2D array representing the right-hand side.

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

        ab_matrix = to2d(ab_matrix)
        b_vector = to2d(b_vector)

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

        try:
            x = scipy_solve_banded((int(l_diags), int(u_diags)), ab, b)
        except Exception as e:
            return f"Error: {str(e)}"

        return x.tolist()

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

Online Calculator

Number of non-zero lower diagonals.
Number of non-zero upper diagonals.
The banded matrix in 'ab' format (shape is l + u + 1 by M).
2D array representing the right-hand side.

SOLVE_TOEPLITZ

Solves the linear system Tx = b where T is a Toeplitz matrix. This implementation uses the Levinson-Durbin recursion algorithm.

Excel Usage

=SOLVE_TOEPLITZ(column, b_vector, row)
  • column (list[list], required): First column of the Toeplitz matrix.
  • b_vector (list[list], required): 2D array representing the right-hand side.
  • row (list[list], optional, default: null): First row of the Toeplitz matrix. If omitted, T is assumed symmetric/Hermitian based on the column.

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

Example 1: Solve symmetric Toeplitz system

Inputs:

column b_vector
1 0.5 0.2 1 2 3

Excel formula:

=SOLVE_TOEPLITZ({1,0.5,0.2}, {1,2,3})
Example 2: Solve asymmetric Toeplitz system

Inputs:

column b_vector row
1 2 3 1 1 1 1 4 5

Excel formula:

=SOLVE_TOEPLITZ({1,2,3}, {1,1,1}, {1,4,5})

Python Code

Show Code
import numpy as np
from scipy.linalg import solve_toeplitz as scipy_solve_toeplitz

def solve_toeplitz(column, b_vector, row=None):
    """
    Solve a Toeplitz system using Levinson Recursion.

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

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

    Args:
        column (list[list]): First column of the Toeplitz matrix.
        b_vector (list[list]): 2D array representing the right-hand side.
        row (list[list], optional): First row of the Toeplitz matrix. If omitted, T is assumed symmetric/Hermitian based on the column. Default is None.

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

        c = np.array(to2d(column), dtype=float).flatten()
        b = np.array(to2d(b_vector), dtype=float)

        if row is not None:
            r = np.array(to2d(row), dtype=float).flatten()
            c_or_cr = (c, r)
        else:
            c_or_cr = c

        try:
            x = scipy_solve_toeplitz(c_or_cr, b)
        except Exception as e:
            return f"Error: {str(e)}"

        return x.tolist()

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

Online Calculator

First column of the Toeplitz matrix.
2D array representing the right-hand side.
First row of the Toeplitz matrix. If omitted, T is assumed symmetric/Hermitian based on the column.

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

Python Code

Show 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.