1. Transfer function matrices

Let’s say we have two inputs and two outputs. We can write the linearised effect as follows:

\begin{align} y_1 &= G_{11} u_1 + G_{12} u_2 \\ y_2 &= G_{21} u_1 + G_{22} u_2 \end{align}

Which is equivalent to a matrix expression

\[\mathbf{y} = G \mathbf{u}\]

with

\[\begin{split}\mathbf{y} = \begin{bmatrix}y_1\\y_2\end{bmatrix} \quad G = \begin{bmatrix}G_{11} & G_{12} \\ G_{21} & G_{22} \end{bmatrix} \quad \mathbf{u} = \begin{bmatrix}u_1\\u_2\end{bmatrix}\end{split}\]

I find it useful to picture the input going into the top of the matrix and the output coming out of the side

1.1. Representing matrices in SymPy

[1]:
import sympy
sympy.init_printing()
[2]:
s = sympy.Symbol('s')
[3]:
G11 = (s + 1)/(s + 2)
G12 = 1/(2*s + 1)
G21 = 1/(3*s + 1)
G22 = 1/(4*s + 1)

row1 = [G11, G12]
row2 = [G21, G22]
list_of_lists = [row1,
                 row2]
[4]:
G = sympy.Matrix(list_of_lists)
[5]:
G[0, 0]
[5]:
$\displaystyle \frac{s + 1}{s + 2}$
[6]:
sympy.simplify(G.inv())
[6]:
$\displaystyle \left[\begin{matrix}\frac{6 s^{3} + 17 s^{2} + 11 s + 2}{6 s^{3} + 7 s^{2} - 3 s - 1} & - \frac{12 s^{3} + 31 s^{2} + 15 s + 2}{6 s^{3} + 7 s^{2} - 3 s - 1}\\- \frac{8 s^{3} + 22 s^{2} + 13 s + 2}{6 s^{3} + 7 s^{2} - 3 s - 1} & \frac{24 s^{4} + 50 s^{3} + 35 s^{2} + 10 s + 1}{6 s^{3} + 7 s^{2} - 3 s - 1}\end{matrix}\right]$
[7]:
G + G
[7]:
$\displaystyle \left[\begin{matrix}\frac{2 \left(s + 1\right)}{s + 2} & \frac{2}{2 s + 1}\\\frac{2}{3 s + 1} & \frac{2}{4 s + 1}\end{matrix}\right]$

1.2. Representing matrices using the control library

[8]:
import control
[9]:
control.tf([0, 1], [1, 2])
[9]:
$$\frac{1}{s + 2}$$
[10]:
s = control.tf([1, 0], 1)
[11]:
s
[11]:
$$\frac{s}{1}$$
[12]:
G = 1/(s + 1)
[13]:
num11 = [1, 2]
num12 = [2]
num21 = [3]
num22 = [4]

row1 = [num11, num12]
row2 = [num21, num22]
numerator = [row1,
             row2]


denominator = [[[1, 1], [2, 1]],
               [[3, 1], [4, 1]]]
Gmatrix = control.tf(numerator,
           denominator)
[14]:
Gmatrix
[14]:
$$\begin{bmatrix}\frac{s + 2}{s + 1}&\frac{2}{2 s + 1}\\\frac{3}{3 s + 1}&\frac{4}{4 s + 1}\\ \end{bmatrix}$$

2. Conversion to state space

See the state space notebook for more information about conversion between state space and transfer function form. The examples in that notebook are for SISO transfer functions.

There are no tools in scipy.signal to deal with mutlivariable transfer functions. However, the control library can do the conversion from a transfer function matrix to a state space form if you have the `slycot <>`__ library installed.

You can try to install slycot using this command:

[15]:
#!conda install -c conda-forge control slycot
[16]:
control.ss(Gmatrix)
[16]:
\[ \left( \begin{array}{rllrllrllrll|rllrll} -1.&\hspace{-1em}33&\hspace{-1em}\phantom{\cdot}&-1.&\hspace{-1em}11&\hspace{-1em}\cdot10^{-16}&-1.&\hspace{-1em}67&\hspace{-1em}\cdot10^{-16}&-0.&\hspace{-1em}333&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&-1.&\hspace{-1em}11&\hspace{-1em}\cdot10^{-16}\\ -3.&\hspace{-1em}33&\hspace{-1em}\cdot10^{-16}&-0.&\hspace{-1em}75&\hspace{-1em}\phantom{\cdot}&-0.&\hspace{-1em}125&\hspace{-1em}\phantom{\cdot}&6.&\hspace{-1em}94&\hspace{-1em}\cdot10^{-17}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}\\ 1.&\hspace{-1em}11&\hspace{-1em}\cdot10^{-16}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&-2.&\hspace{-1em}1&\hspace{-1em}\cdot10^{-16}&-3.&\hspace{-1em}41&\hspace{-1em}\cdot10^{-16}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}\\ 1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&1.&\hspace{-1em}31&\hspace{-1em}\cdot10^{-16}&-9.&\hspace{-1em}52&\hspace{-1em}\cdot10^{-17}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}\\ \hline 1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0.&\hspace{-1em}25&\hspace{-1em}\phantom{\cdot}&0.&\hspace{-1em}333&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}\\ 1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0.&\hspace{-1em}5&\hspace{-1em}\phantom{\cdot}&1\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}&0\phantom{.}&\hspace{-1em}&\hspace{-1em}\phantom{\cdot}\\ \end{array}\right) \]

What are the true values of those small (10\(^{-16}\)) values?