JuliaControl / ControlSystems.jl

A Control Systems Toolbox for Julia
https://juliacontrol.github.io/ControlSystems.jl/stable/
Other
503 stars 85 forks source link

minreal returns system of order 21 instead of order 5. #890

Closed Johan-Gronqvist closed 9 months ago

Johan-Gronqvist commented 9 months ago

The following example works in Julia and Matlab, producing minimal representations of order four in both cases.

s = tf("s")
g = 1/(s-1)^3
g_tot = [ 1/s*g; g; s*g; s*s*g ]
g_tot = ss(g_tot)
@show size(g_tot.A)
g_tot = minreal(g_tot)
@show size(g_tot.A);

Increasing the order by one, Matlab produces a solution of order five, but the Julia result jumps to order 21.

s = tf("s")
g = 1/(s-1)^4
g_tot = [ 1/s*g; g; s*g; s*s*g; s*s*s*g ]
g_tot = ss(g_tot)
@show size(g_tot.A)
g_tot = minreal(g_tot)
@show size(g_tot.A);

(The corresponding lsminreal call using MatrixPencils.jl produces the same result, but I am creating an issue here in ControlSystems.jl, as I do not understand enough about matrix pencils to claim that that package has an issue.)

I used ControlSystems 1.8.1 and Julia 1.9.3.

The matlab code was identical, except for the @show and some ;:

s = tf("s");
g = 1/(s-1)^3
g_tot = [ 1/s*g; g; s*g; s*s*g ];
g_tot = ss(g_tot);
size(g_tot.A)
g_tot = minreal(g_tot);
size(g_tot.A)

and

s = tf("s");
g = 1/(s-1)^4
g_tot = [ 1/s*g; g; s*g; s*s*g; s*s*s*g ];
g_tot = ss(g_tot);
size(g_tot.A)
g_tot = minreal(g_tot);
size(g_tot.A)
baggepinnen commented 9 months ago

You can change the tolerance to minreal, for example:

julia> s = tf("s")
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Int64}}
s
-
1

Continuous-time transfer function model

julia> g = 1/(s-1)^4
TransferFunction{Continuous, ControlSystemsBase.SisoRational{Int64}}
            1
--------------------------
s^4 - 4s^3 + 6s^2 - 4s + 1

Continuous-time transfer function model

julia> g_tot_tf = [ 1/s*g; g; s*g; s*s*g; s*s*s*g ];

julia> g_tot = ss(g_tot_tf);

julia> g_tot.nx
21

julia> g_tot_m = minreal(g_tot);

julia> g_tot_m.nx
17

julia> g_tot_m = minreal(g_tot, 1e-12);

julia> g_tot_m.nx
5
Johan-Gronqvist commented 9 months ago

Thanks! Apologies for the noise.