# [CONTROL SYSTEMS] - MIMO system through array of SISO

Greetings.

I would like to know if it’s possible, in ControlSystems.jl, to reach an MIMO system through an array of TransferFunctions.

Let’s suppose that we have a matrix H, which is related to a Y = H*U, where Y is a vector of outputs, and U is a vector of inputs. If Y{2,1} and U{2,1},H is H{2,2} (assuming that curly brackets refers to dimension).

Therefore, H can be stated as 4 transfer functions, each one related to H11, H12, H21 and H22. In this way, my intent is to create a matrix that can be stated as a “transfer function matrix”, and later, be converted to a StateSpace system.

``````H11 = tf([1,0],[1,2,3,4])
H12 = tf([2,0],[1,2,3,4])
H21 = tf([3,0],[1,2,3,4])
H22 = tf([4,0],[1,2,3,4])

H = Matrix{TransferFunction}(undef,2,2)

H[1,1] = H11
H[1,2] = H12
H[2,1] = H21
H[2,2] = H22
``````

And then, i would like to do the following:

``````dampreport(H)
``````

And, then, finding the poles of the system. But dampreport dont understand H as a MIMO transfer function, and instead, as a matrix (which really is, but i expected that it would be automatic to be a MIMO).

I know the fact that documentation provides the reference that MIMO systems should be implemented as an array of vectors, but this didn’t worked for me. But idk if i understand what i should understand as an “array of vectors”. (Constructors · ControlSystems.jl) An example of MIMO TF would be very welcomed.

I should use Transfer Functions because i only have the coefficients for them.

However, i would like to complement this question: if it’s possible to use a z^-1 format for discrete transform, instead of the standard z.

This might be a noob question, and idk if i should post in “New in Julia”.

Hi, welcome to Julia community.

``````julia> using ControlSystems

julia> N = [[1,2],[3,4]]
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]

julia> D = [[5,6,7],[8,9,10]]
2-element Vector{Vector{Int64}}:
[5, 6, 7]
[8, 9, 10]

julia> G = tf(N,D)
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Int64}}
Input 1 to output 1
s + 2
-------------
5s^2 + 6s + 7

Input 1 to output 2
3s + 4
--------------
8s^2 + 9s + 10

Continuous-time transfer function model
``````

Hello and welcome!

https://juliacontrol.github.io/ControlSystems.jl/stable/man/creating_systems/#MIMO-systems-and-arrays-of-systems
in particular, the section on Converting an array of systems to a MIMO system

``````H_mimo = array2mimo(H)
``````

or by construction directly

``````julia> [H11 H12; H21 H22]
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Int64}}
Input 1 to output 1
s
-------------------
s^3 + 2s^2 + 3s + 4

Input 1 to output 2
3s
-------------------
s^3 + 2s^2 + 3s + 4

Input 2 to output 1
2s
-------------------
s^3 + 2s^2 + 3s + 4

Input 2 to output 2
4s
-------------------
s^3 + 2s^2 + 3s + 4

Continuous-time transfer function model
``````

If you convert this to a statespace system you will not get a minimal realization directly, use the function `minreal` if you want to obtain such a minimal realization:

``````julia> ss([H11 H12; H21 H22]).nx
12

julia> minreal(ss([H11 H12; H21 H22])).nx
6
``````

This is unfortunately not supported at the moment.

I took a read at this section, and i noticed that in the example given, the matrix is created through a fill, so the type of data is already defined by P. In my problem, i let it more generic, (i should have stated it here).

Due to the fact that i get the coefficients from a polynomial and put it in a TF. But in the way that i organized the problem, this procedural is made in a loop. Therefore, the first idea that you have to storage, is to initialize an array. But i didn’t knew how exactly this array. So i did as following:

``````H = Matrix{TransferFunction}(undef,ny,nu)
``````

Without specifying the type of TF. So, i wasn’t able to storage the TF’s to the array H.

``````G = Matrix{TransferFunction{Discrete{Float64}, ControlSystemsBase.SisoRational{Float64}}}(undef,ny,nu);
G = ss(array2mimo(G))
``````

And then, returning what i desired.

In this way, i would like to thank both, for providing an example and a path to a answer for a problem, which i should had stated it more clearly.

In many situations in which you are initializing an array before a loop, and then using the loop to populate it, you can make use of the `map` function instead. This saves you from having to figure out the type of the resulting array. Here’s an example

``````using ControlSystemsBase
w = 1:3
z = 0.1:0.2:0.7
H = map(Iterators.product(w, z)) do (ω, ζ)
tf(ω^2, [1, 2ζ*ω, ω^2])
end
array2mimo(H)
``````

You may also find the following functions useful when dealing with types

``````julia> typeof(tf(1.0, [1, 1])) # Get the type of something
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}

julia> eltype(H) # Get the element type of an array
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}

julia> typeof(H)
Matrix{TransferFunction{Continuous, SisoRational{Float64}}} (alias for Array{TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}, 2})

julia> Matrix{typeof(tf(1.0, [1, 1]))}(undef, 2,2) # Create an array with element type given by the transfer function
2×2 Matrix{TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}}:
#undef  #undef
#undef  #undef

julia> similar(H, 2, 1) # create a similar array of the same type as another array, but modify its size
2×1 Matrix{TransferFunction{Continuous, ControlSystemsBase.SisoRational{Float64}}}:
#undef
#undef
``````
1 Like