EXPM
Overview
The EXPM function computes the matrix exponential of a square matrix. The matrix exponential is a fundamental operation in linear algebra, with applications in solving systems of linear differential equations, quantum mechanics, control theory, and more. The matrix exponential of a square matrix is defined as:
This function uses the algorithm from Awad H. Al-Mohy and Nicholas J. Higham (2009), which is a scaling and squaring method with a variable-order Padé approximation, as implemented in scipy.linalg.expm . For more details, see the SciPy documentation .
This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=EXPM(matrix)matrix(2D list, required): Square table of numbers convertible to complex values. Provide each row as a separate row in the range. The matrix must have at least one row and the same number of columns as rows; a single-cell input is treated as a 1×1 matrix.
The function returns a 2D list with the same dimensions as the input matrix. Real-valued results are returned as floats. Entries with non-zero imaginary parts are returned as strings formatted like real±imagj. Invalid inputs return a 2D list containing an error message string.
Examples
Example 1: Exponential of the Zero Matrix (2×2)
Inputs:
| matrix | |
|---|---|
| 0 | 0 |
| 0 | 0 |
Excel formula:
=EXPM({0,0;0,0})Expected output:
| Result | |
|---|---|
| 1.000 | 0.000 |
| 0.000 | 1.000 |
Example 2: Nilpotent Upper-Triangular Matrix
Inputs:
| matrix | |
|---|---|
| 0 | 1 |
| 0 | 0 |
Excel formula:
=EXPM({0,1;0,0})Expected output:
| Result | |
|---|---|
| 1.000 | 1.000 |
| 0.000 | 1.000 |
Example 3: Zero Matrix (3×3)
Inputs:
| matrix | ||
|---|---|---|
| 0 | 0 | 0 |
| 0 | 0 | 0 |
| 0 | 0 | 0 |
Excel formula:
=EXPM({0,0,0;0,0,0;0,0,0})Expected output:
| Result | ||
|---|---|---|
| 1.000 | 0.000 | 0.000 |
| 0.000 | 1.000 | 0.000 |
| 0.000 | 0.000 | 1.000 |
Example 4: General 2×2 Real Matrix
Inputs:
| matrix | |
|---|---|
| 1 | 2 |
| -1 | 3 |
Excel formula:
=EXPM({1,2;-1,3})Expected output:
| Result | |
|---|---|
| -2.225 | 12.435 |
| -6.218 | 10.210 |
Python Code
from typing import List, Union
import numpy as np
from scipy.linalg import expm as scipy_expm
MatrixInputValue = Union[float, int, bool, str, None]
MatrixInput = Union[List[List[MatrixInputValue]], MatrixInputValue]
MatrixOutputValue = Union[float, str]
def expm(matrix: MatrixInput) -> List[List[MatrixOutputValue]]:
"""
Compute the matrix exponential of a square matrix.
Args:
matrix: 2D list (n x n) of values convertible to complex numbers. A single-cell input is treated as a 1x1 matrix.
Returns:
2D list (n x n) representing the matrix exponential, or a 2D list of strings with an error message if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Excel may provide a single-cell 2D range as a scalar; wrap it into a 1x1 matrix
if isinstance(matrix, (float, int, bool, str)) or matrix is None:
matrix = [[matrix]]
# Validate that matrix is a non-empty 2D list of rows with consistent length
if not isinstance(matrix, list) or not matrix:
return [["Invalid input: matrix must be a 2D list with at least one row."]]
if any(not isinstance(row, list) for row in matrix):
return [["Invalid input: matrix must be a 2D list with at least one row."]]
size = len(matrix)
if any(len(row) != size for row in matrix):
return [["Invalid input: matrix must be square."]]
# Convert to a numeric numpy array, rejecting values that cannot form complex numbers
numeric_rows: List[List[complex]] = []
for row in matrix:
numeric_row: List[complex] = []
for value in row:
try:
numeric_row.append(complex(value))
except Exception:
return [["Invalid input: matrix entries must be numeric values."]]
numeric_rows.append(numeric_row)
arr = np.array(numeric_rows, dtype=np.complex128)
if not np.isfinite(arr.real).all() or not np.isfinite(arr.imag).all():
return [["Invalid input: matrix entries must be finite numbers."]]
# Delegate matrix exponential to SciPy and capture runtime errors
try:
result = scipy_expm(arr)
except Exception as exc:
return [[f"scipy.linalg.expm error: {exc}"]]
# Convert result matrix into Excel-friendly values without altering precision
output: List[List[MatrixOutputValue]] = []
for row in result:
output_row: List[MatrixOutputValue] = []
for value in row:
real_part = float(value.real)
imag_part = float(value.imag)
if not np.isfinite(real_part) or not np.isfinite(imag_part):
return [["scipy.linalg.expm error: non-finite result encountered."]]
if abs(imag_part) <= 1e-12:
output_row.append(real_part)
elif abs(real_part) <= 1e-12:
output_row.append(f"{imag_part}j")
else:
sign = "+" if imag_part >= 0 else "-"
imag_value = imag_part if imag_part >= 0 else -imag_part
output_row.append(f"{real_part}{sign}{imag_value}j")
output.append(output_row)
return output