MATLAB and Python/NumPy functions to solve the generalized Sylvester equation
for the matrix
See K. E. Chu, "The Solution of the Matrix Equations AXB - CXD = E and (YA - DZ, YC - BZ) = (E, F)," Linear Algebra and its Applications 93 (1987): 93-105, for example.
MATLAB contains the function sylvester which solves a matrix equation of the form
A Python implementation using the NumPy framework is also included.
Consider matrices
and
The associated generalized Sylvester equation has the solution
To solve this in Python, ensure the directory 'generalized_sylvester' ('.\Python\generalized_sylvester' in this repo) is found in your Python search path, make sure that NumPy is installed (see '.\Python\env\generalized-sylvester-environment.yml' for a conda environment that can be imported), and run the script
import numpy as np
import generalized_sylvester as gs
import generalized_sylvester.error as gs_error
A = np.array([[1, 2, 3],[0, 2, 1],[0, 0, 1]])
B = np.array([[1, 0],[2, 1]])
C = np.array([[2, 0, 0],[1, 1, 0],[3, 2, 1]])
D = np.array([[1, 2],[0, 2]])
E = np.array([[4, 1],[0, 0],[1, -2]])
X = gs.solve(A, B, C, D, E) # solve the generalized sylvester equation AXB + CXD = E for the unknown X
matrices = [A, B, C, D, E, X]
print(gs_error.eqn_error_matrix(*matrices)) # equation error matrix, A @ X @ B + C @ X @ D - E
print(gs_error.eqn_error_norm(*matrices)) # frobenius norm of the equation error, ~3.1244445429724018e-15
To solve this in MATLAB, ensure the directory '+fn_matrix_eqns' ('.\MATLAB+fn_matrix_eqns' in this repo) is found in your MATLAB path and run
A = [1 2 3; 0 2 1; 0 0 1];
B = [1 0; 2 1];
C = [2 0 0; 1 1 0; 3 2 1];
D = [1 2; 0 2];
E = [4, 1; 0, 0; 1, -2];
X = fn_matrix_eqns.generalized_sylvester(A, B, C, D, E);
norm(A*X*B + C*X*D - E, 2) % ~1.6140e-15
The Python implementation contains a YML file to generate a conda environment, along with some batch files for running unit tests and type checking. The implemented module is in ".\Python\generalized_sylvester". Example usage can be found in ".\Python\example_usage.py".
To use the Python implementation as a module, you only need the directory tree at ".\Python\generalized_sylvester". Simply make sure this is in a location that can be found by the Python interpreter, and then you can import the functions via something like
import generalized_sylvester as gs
and/or
import generalized_sylvester.error as gs_error
The functions in the generalized_sylvester namespace are
# Solve the generalized Sylvester equations.
generalized_sylvester.solve(A: _np.ndarray, B: _np.ndarray, C: _np.ndarray, D: _np.ndarray, E: _np.ndarray) -> _np.ndarray
# Get the equation error matrix, AXB + CXD - E.
generalized_sylvester.error.eqn_error_matrix(A: _np.ndarray, B: _np.ndarray, C: _np.ndarray, D: _np.ndarray, E: _np.ndarray, X: _np.ndarray) -> _np.ndarray
# Get the Frobenius norm of the equation error matrix, AXB + CXD - E.
generalized_sylvester.error.eqn_error_norm(A: _np.ndarray, B: _np.ndarray, C: _np.ndarray, D: _np.ndarray, E: _np.ndarray, X: _np.ndarray) -> _np.ndarray
There are a number of pytest unit test cases in '.\Python\generalized_sylvester\test\test_generalized_sylvester.py'.
All included MATLAB functions and scripts have been included under the namespaces fn_matrix_eqns, fn_matrix_eqns.examples, and fn_matrix_eqns.tests to avoid possible namespace conflicts in the future.
% The function for solving the generalized Sylvester equation.
fn_matrix_eqns.generalized_sylvester.m
% A simple script demonstrating usage of fn_matrix_eqns.generalized_sylvester.m.
fn_matrix_eqns.examples.example_generalized_sylvester.m
% A function that runs a variety of unit test cases on fn_matrix_eqns.generalized_sylvester.m.
fn_matrix_eqns.tests.run_tests_generalized_sylvester.m
% A script that runs test cases for included functions.
fn_matrix_eqns.tests.run_all_tests.m