# Basic operations on system models

Inversion of a system.`inv`

Left division for two systems (also overloaded with`ldiv`

).`\`

Right division for two systems (also overloaded with`rdiv`

).`/`

Building the dual of a descriptor system (also overloaded with`gdual`

)`transpose`

Building the conjugate transpose of a system (also overloaded with`ctranspose`

and`adjoint`

).`'`

Building the adjoint of a system.`adjoint`

`Base.inv`

— Function`sysinv = inv(sys; atol = 0, atol1 = atol, atol2 = atol, rtol, checkinv = true)`

Compute for a descriptor system `sys = (A-λE,B,C,D)`

with the transfer function matrix `G(λ)`

, a descriptor realization of its inverse system `sysinv = (Ai-λEi,Bi,Ci,Di)`

, such that the transfer function matrix `Ginv(λ)`

of `sysinv`

is the inverse of `G(λ)`

(i.e., `G(λ)*Ginv(λ) = I`

). The realization of `sysinv`

is determined using inversion-free formulas and the invertibility condition is checked, unless `checkinv = false`

.

The keyword arguments `atol1`

, `atol2`

and `rtol`

specify, respectively, the absolute tolerance for the nonzero elements of `A`

, `B`

, `C`

, `D`

, the absolute tolerance for the nonzero elements of `E`

, and the relative tolerance for the nonzero elements of `A`

, `B`

, `C`

, `D`

and `E`

. The default relative tolerance is `n*ϵ`

, where `n`

is the order of the square matrices `A`

and `E`

, and `ϵ`

is the working machine epsilon. The keyword argument `atol`

can be used to simultaneously set `atol1 = atol`

and `atol2 = atol`

.

`DescriptorSystems.ldiv`

— Function```
sysldiv = ldiv(sys1, sys2; atol = 0, atol1 = atol, atol2 = atol, rtol = n*ϵ, checkinv = true)
sysldiv = sys1 \ sys2
```

Compute for the descriptor systems `sys1 = (A1-λE1,B1,C1,D1)`

with the transfer function matrix `G1(λ)`

and `sys2 = (A2-λE2,B2,C2,D2)`

with the transfer function matrix `G2(λ)`

, a descriptor realization `sysldiv = (Ai-λEi,Bi,Ci,Di)`

of `sysldiv = inv(sys1)*sys2`

, whose transfer-function matrix `Gli(λ)`

represents the result of the left division `Gli(λ) = inv(G1(λ))*G2(λ)`

. The realization of `sysldiv`

is determined using inversion-free formulas and the invertibility condition for `sys1`

is checked, unless `checkinv = false`

.

The keyword arguments `atol1`

, `atol2`

and `rtol`

specify, respectively, the absolute tolerance for the nonzero elements of `A1`

, `B1`

, `C1`

, `D1`

, `A2`

, `B2`

, `C2`

, `D2`

, the absolute tolerance for the nonzero elements of `E1`

and `E2`

, and the relative tolerance for the nonzero elements of `A1`

, `B1`

, `C1`

, `D1`

, `A2`

, `B2`

, `C2`

, `D2`

, `E1`

and `E2`

. The default relative tolerance is `n*ϵ`

, where `n`

is the maximum of orders of the square matrices `A1`

and `A2`

, and `ϵ`

is the working machine epsilon. The keyword argument `atol`

can be used to simultaneously set `atol1 = atol`

and `atol2 = atol`

.

`DescriptorSystems.rdiv`

— Function```
sysrdiv = rdiv(sys1, sys2; atol = 0, atol1 = atol, atol2 = atol, rtol = n*ϵ, checkinv = true)
sysrdiv = sys1 / sys2
```

Compute for the descriptor systems `sys1 = (A1-λE1,B1,C1,D1)`

with the transfer function matrix `G1(λ)`

and `sys2 = (A2-λE2,B2,C2,D2)`

with the transfer function matrix `G2(λ)`

, a descriptor realization `sysrdiv = (Ai-λEi,Bi,Ci,Di)`

of `sysrdiv = sys1*inv(sys2)`

, whose transfer-function matrix `Gri(λ)`

represents the result of the right division `Gri(λ) = G1(λ)*inv(G2(λ))`

. The realization of `sysrdiv`

is determined using inversion-free formulas and the invertibility condition for `sys2`

is checked, unless `checkinv = false`

.

The keyword arguments `atol1`

, `atol2`

and `rtol`

specify, respectively, the absolute tolerance for the nonzero elements of `A1`

, `B1`

, `C1`

, `D1`

, `A2`

, `B2`

, `C2`

, `D2`

, the absolute tolerance for the nonzero elements of `E1`

and `E2`

, and the relative tolerance for the nonzero elements of `A1`

, `B1`

, `C1`

, `D1`

, `A2`

, `B2`

, `C2`

, `D2`

, `E1`

and `E2`

. The default relative tolerance is `n*ϵ`

, where `n`

is the maximum of orders of the square matrices `A1`

and `A2`

, and `ϵ`

is the working machine epsilon. The keyword argument `atol`

can be used to simultaneously set `atol1 = atol`

and `atol2 = atol`

.

`DescriptorSystems.gdual`

— Function```
sysdual = gdual(sys, rev = false)
sysdual = transpose(sys, rev = false)
```

Compute for a descriptor system `sys = (A-λE,B,C,D)`

with the transfer function matrix `G(λ)`

, the descriptor system realization of its dual system `sysdual = (Ad-λEd,Bd,Cd,Dd)`

, where `Ad = transpose(A)`

, `Ed = transpose(E)`

, `Bd = transpose(C)`

, `Cd = transpose(B)`

and `Dd = transpose(D)`

, such that the transfer function matrix `Gdual(λ)`

of `sysdual`

is the transpose of `G(λ)`

(i.e., `Gdual(λ) = transpose(G(λ))`

).

If `rev = true`

, the tranposition is combined with the reverse permutation of the state variables, such that `sysdual = (P*Ad*P-λP*Ed*P,P*Bd,Cd*P,Dd)`

, where `P`

is the permutation matrix with ones down the second diagonal.

`DescriptorSystems.ctranspose`

— Function```
sysconj = ctranspose(sys)
sysconj = sys'
```

Compute the conjugate transpose (or adjoint) of a descriptor system (see `adjoint`

).

`Base.adjoint`

— Function` rt = adjoint(r)`

Compute the adjoint `rt(λ)`

of the rational transfer function `r(λ)`

such that for `r(λ) = num(λ)/den(λ)`

we have:

```
(1) `rt(λ) = conj(num(-λ))/conj(num(-λ))`, if `r.Ts = 0`;
(2) `rt(λ) = conj(num(1/λ))/conj(num(1/λ))`, if `r.Ts = -1` or `r.Ts > 0`.
```

```
sysconj = adjoint(sys)
sysconj = sys'
```

Compute for a descriptor system `sys = (A-λE,B,C,D)`

with the transfer function matrix `G(λ)`

, the descriptor system realization of its adjoint (also called *conjugate transpose*) system `sysconj = (Ac-λEc,Bc,Cc,Dc)`

, such that the transfer function matrix `Gconj(λ)`

of `sysconj`

is the appropriate conjugate transpose of `G(λ)`

, as follows: for a continuous-time system with `λ = s`

, `Gconj(s) := transpose(G(-s))`

, while for a discrete-time system with `λ = z`

, `Gconj(z) := transpose(G(1/z))`

.