SciPy - expm_cond() Function



The method, scipy.linalg.expm_cond(), computes the condition number for matrix exponential expm(A). This number shows how sensitive the output result expm(A) to small changes in the input matrix A. This way we can know the numerical accuracy of the matrix exponential computation.

This method is essential in determining the reliability of the matrix exponential obtained from the computation, especially for cases involving ill-conditioned matrices.

Errors may occur if the input matrix A is not square because the matrix exponential is only defined for square matrices. Furthermore, providing matrices with NaNs or infinite values may lead to wrong computations unless check_finite=False is explicitly set.

This function can be used with expm() to test the accuracy of your matrix exponential calculations, and it also might be used with expm_frechet() if you need to test the sensitivity in the dynamic systems with respect to changes.

Syntax

The syntax for the SciPy expm_cond() method is as follows −

.expm_cond(A, check_finite=True)

Parameters

This method accepts the following parameters −

  • A (2-D array_like) − Input square matrix (nn), real or complex.

  • check_finite (bool, optional) − If True, checks if the input matrix contains only finite numbers (no NaNs or infinities).

Return Value

cond (float) − The condition number of the matrix exponential expm(A), representing its sensitivity to changes in A.

Example 1: Basic Condition Number Computation

The scipy.linalg.expm_cond() method returns the condition number of the matrix exponential, meaning how sensitive the result is to small changes in the input matrix.

The following code, takes a 22 matrix 'A' as input and computes the condition number of expm(A). The condition number measures how changes in 'A' effect the computed exponential. Low condition number means stability, while a high value means that the result is numerically sensitive.

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Basic 2x2 matrix
A = np.array([[1, 2], 
              [3, 4]])

# Compute the condition number
cond = scipy.linalg.expm_cond(A)
print("Condition Number of expm(A):", cond)

When we run above program, it produces following result

Condition Number of expm(A): 5.511586677311222

Example 2: Stable Computation with a Diagonal Matrix

When diagonal matrices are used, the condition number is often predictable and stable since diagonal members contribute independently to matrix exponential.

In the below code we will create a diagonal matrix of size 33 denoted as 'A' with the diagonal elements [1, 2, 3]. The expm_cond() method was applied to compute the condition number for the matrix exponential expm(A). The condition number is a measure that specifies how sensitive expm(A) is to slightly changed A. The results show that diagonal matrices are stable, which means that small changes in A have a minimal effect on expm(A).

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Diagonal matrix
A = np.diag([1, 2, 3])
cond = expm_cond(A)
print("Condition Number of expm(A):", cond)

Following is an output of the above code

Condition Number of expm(A): 3.483588186161316

Example 3: Ill-Conditioned Matrix with expm_cond

Ill-conditioned matrices will have extremely large condition numbers, indicating that the matrix exponential is unstable.

In the example below, we will create a nearly singular 22 matrix 'A' and use expm_cond method t0=o compute conditional number. The condition number will be large, suggesting that expm(A) will be numerically unstable and very sensitive to small perturbations of A.

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Ill-conditioned matrix
A = np.array([[1e-5, 1], 
              [1, 1e-5]])
cond = expm_cond(A)
print("Condition Number of expm(A):", cond)

Output of the above code is as follows

Condition Number of expm(A): 1.4014376833353026

Example 4: Condition Number for Sparse Matrices Using expm_cond

Sparse matrices with big dimensions usually possess moderate condition numbers for stable computation.

Below is an example of code using the 44 sparse matrix 'A', where most of its entries are zero's except the diagonal elements as follows [1, 2, 3, 4]. The expm_cond() method is used to compute the condition number for expm(A). The output shows the reasonable condition number, indicates that sparse matrices can produce reliable and efficient matrix exponential calculations.

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Sparse matrix
A = np.array([[1, 0, 0, 0], 
              [0, 2, 0, 0], 
              [0, 0, 3, 0], 
              [0, 0, 0, 4]])
cond = expm_cond(A)
print("Condition Number of expm(A):", cond)

Output of the above code is as follows

Condition Number of expm(A): 5.0939813804117176

Example 5: Complex-Valued Matrices with expm_cond

Complex-valued matrices frequently have greater condition numbers, indicating increased sensitivity. Increased sensitivity means that small changes in the input matrix A may lead to significant changes in the computed expm(A), making the result less reliable and may be prone to numerical instability.

In the below code, we use a a 33 complex matrix. Compute the condition number using expm_cond() method to examine how the imaginary components make expm(A) more sensitive.

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Complex matrix
A = np.array([[1+1j, 2, 0], 
              [0, 2+2j, 1], 
              [1, 0, 3+3j]])
cond = expm_cond(A)
print("Condition Number of expm(A):", cond)

Output of the above code is as follows

Condition Number of expm(A): 5.706538956534122

Example 6: Identity Matrix with expm_cond

The identity matrix has a condition number of 1, representing perfect stability in the matrix exponential.

In the below code, we used np.eye() to create an identity matrix A with all diagonal elements equal to 1. Here, expm_cond() method calculates the condition number for expm(A). This is one, and it implies that the exponential for the identity matrix would be insensitive to variations and ensuring maximum stability.

import numpy as np
import scipy.linalg
from scipy.linalg import expm_cond

# Input: Identity matrix
A = np.eye(3)
cond = expm_cond(A)
print("Condition Number of expm(A):", cond)

Output of the above code is as follows

Condition Number of expm(A): 1.0

Example 7: Handling NaN and Inf Values in expm_cond

If the input matrix A contains NaNs or infinite values, expm_cond can be inaccurate unless check_finite=False is specified explicitly.

This example uses a 22 matrix with np.nan and np.inf values. The default behavior is to check for invalid values and raise an error. Setting check_finite=False will disable this check but likely returns inaccurate or undefined results.

import numpy as np
from scipy.linalg import expm_cond

# Input: Matrix with NaN and infinite values
A = np.array([[np.nan, 1], 
              [2, np.inf]])

# Replace NaN and Inf values with valid numbers (e.g., 0) for computation
A_cleaned = np.nan_to_num(A, nan=0.0, posinf=1.0, neginf=-1.0)

# Compute the condition number with cleaned matrix
cond = expm_cond(A_cleaned, check_finite=False)
print("Condition Number with cleaned matrix:", cond)

try:
  cond = expm_cond(A)
except ValueError as e:
    print("Error with original matrix:", e)

Output of the above code is as follows

Condition Number with cleaned matrix: 2.4657654355134513
Error with original matrix: array must not contain infs or NaNs
scipy_linalg.htm
Advertisements