Skip to Content

LSTSQ

Overview

The LSTSQ function computes the least-squares solution to the linear matrix equation Ax=bAx = b, minimizing the 2-norm bAx2\lVert b - Ax \rVert_2. This wrapper around scipy.linalg.lstsq exposes the most frequently used arguments (A, B, cond, lapack_driver, and return_type) while keeping advanced options such as overwrite_a, overwrite_b, and check_finite at their SciPy defaults for simplicity. Least-squares fitting is widely used for solving overdetermined systems, linear regression, and model calibration.

The solution minimizes the squared error:

minxbAx2\min_x \lVert b - Ax \rVert_2

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

Usage

To use the function in Excel:

=LSTSQ(A, B, [cond], [lapack_driver], [return_type])
  • A (2D list, required): Coefficient matrix with at least one row and column. Single scalars are treated as a 1×1 matrix.
  • B (2D list, required): Right-hand side matrix with the same number of rows as A. Single scalars are treated as a 1×1 matrix.
  • cond (float, optional, default=None): Cutoff for small singular values; values below cond * largest_singular_value are treated as zero.
  • lapack_driver (str, optional, default="gelsd"): LAPACK driver used by SciPy. Accepts "gelsd", "gelsy", or "gelss".
  • return_type (str, optional, default="solution"): Specifies the value to return. Options are "solution", "residuals", "rank", or "singular_values".

The function returns a 2D list containing the requested value or a 2D list with an error message string if the input is invalid.

Examples

Example 1: Solution Vector

Inputs:

ABcondlapack_driverreturn_type
11021e-10gelsdsolution
1012
1113
1001

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.000
1.000
1.000

Example 2: Residual Sum of Squares

Inputs:

ABcondlapack_driverreturn_type
11021e-10gelsdresiduals
1012
1113
1001

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:

Result
0.000

Example 3: Matrix Rank

Inputs:

ABcondlapack_driverreturn_type
11021e-10gelsdrank
1012
1113
1001

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:

Result
3.000

Example 4: Singular Values

Inputs:

ABcondlapack_driverreturn_type
11021e-10gelsdsingular_values
1012
1113
1001

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

Python Code

from typing import List, Optional, Union import numpy as np from scipy.linalg import lstsq as scipy_lstsq MatrixScalar = Union[float, int, bool, str, None] MatrixInput = Union[List[List[MatrixScalar]], MatrixScalar] MatrixReturn = List[List[Union[float, int, str, None]]] def lstsq(A: MatrixInput, B: MatrixInput, cond: Optional[float] = None, lapack_driver: str = "gelsd", return_type: str = "solution") -> MatrixReturn: """ Compute the least-squares solution to Ax = B using scipy.linalg.lstsq. Args: A: 2D list (M x N) coefficient matrix. Single scalars are treated as 1x1 matrices. B: 2D list (M x K) right-hand side matrix. Single scalars are treated as 1x1 matrices. cond: Optional float cutoff for small singular values. Defaults to None. lapack_driver: String identifying the LAPACK driver ("gelsd", "gelsy", "gelss"). Defaults to "gelsd". return_type: String specifying the value to return: "solution", "residuals", "rank", or "singular_values". Defaults to "solution". Returns: 2D list containing the requested result, or a 2D list with an error message string if the input is invalid. This example function is provided as-is without any representation of accuracy. """ # Wrap scalar inputs coming from Excel into 2D lists if not isinstance(A, list): A = [[A]] if not isinstance(B, list): B = [[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"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"Invalid input: {name} must be a 2D list with at least one column."]] for row in matrix: if not isinstance(row, list): return [[f"Invalid input: {name} must be a 2D list with rows represented as lists."]] if len(row) != row_length: return [[f"Invalid input: each row in {name} must have the same length."]] if len(A) != len(B): return [["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 [["Invalid input: A and B must contain numeric values."]] # Validate optional parameters if cond is not None: try: cond = float(cond) except Exception: return [["Invalid input: cond must be a float or None."]] driver = str(lapack_driver).strip().lower() if driver not in {"gelsd", "gelsy", "gelss"}: return [["Invalid input: lapack_driver must be 'gelsd', 'gelsy', or 'gelss'."]] result_type = str(return_type).strip().lower() if result_type not in {"solution", "residuals", "rank", "singular_values"}: return [["Invalid input: return_type must be one of 'solution', 'residuals', 'rank', 'singular_values'."]] # Execute SciPy least-squares solver try: solution, residuals, effective_rank, singular_values = scipy_lstsq( A_arr, B_arr, cond=cond, lapack_driver=driver, ) except Exception as exc: return [[f"scipy.linalg.lstsq error: {exc}"]] # Prepare helper to ensure outputs are finite and 2D def finite_matrix(values: Union[np.ndarray, float, int]) -> MatrixReturn: array = np.asarray(values, dtype=float) if array.ndim == 0: array = array.reshape(1, 1) elif array.ndim == 1: array = array.reshape(1, -1) if array.size == 0: return [[]] if not np.isfinite(array).all(): return [["scipy.linalg.lstsq error: non-finite result encountered."]] return array.tolist() if result_type == "solution": return finite_matrix(solution) if result_type == "residuals": return finite_matrix(residuals) if result_type == "rank": rank_matrix = finite_matrix(float(effective_rank)) return rank_matrix if singular_values is None: return [["Invalid input: singular values are unavailable for the selected LAPACK driver."]] singular_values_matrix = finite_matrix(singular_values) return singular_values_matrix

Example Workbook

Link to Workbook 

Last updated on