-
Notifications
You must be signed in to change notification settings - Fork 86
Type system suggestion for the toolbox 2
Based on ideas from the discussion thread, discussions with @mfalt, and this
struct Continuous end
struct Discrete end
struct Siso end
struct Mimo end
abstract type AbstractRationalFunction end
type PolynomialRatio <: AbstractRationalFunction
# ...
end
type Zpk <: AbstractRationalFunction
# ...
end
LinearSystem{CoD<:Union{Continuous,Discrete}, T<:Number, SoM<:Union{Siso,Mimo}}
| \
| --------------> GeneralTransferFunction{CoD, T, SoM}
V
AbstractDelayLtiSystem{CoD, T, SoM}
| \
| ------------> DelayLtiSystem{SysType::RationalLtiSystem{CoD, T, SoM}}
V
RationalLtiSystem{CoD, T, SoM}
| \
| -------->---------
V \
StateSpace{CoD, T, SoM} RationalTransferFunction{SysType, T, R::AbstractRationalFunction, SoM}
struct DelayLtiSystem{CoD, T, SoM} <: DelayLtiSystem{SysType::RationalLtiSystem{CoD, T, SoM}}
P::SysType
Tau::Vector{Float64}
end
struct StateSpace{CoD, T, SoM} <: RationalLtiSystem{CoD, T, SoM}
A::Matrix{T}
B::Matrix{T}
C::Matrix{T}
D::Matrix{T}
Ts::Float64
end
struct RationalTransferFunction{CoD, T, R<:TfRepresentation, SoM} <: RationalLtiSystem{CoD, T, SoM}
G::Matrix{R{T}}
Ts::Float64
#end
AbstractDelayLtiSystem
could be left out if we don't need to have functions acting on rational systems with delays, which do not work for general linear systems. Perhaps it is nice to include it to get a more consistent structure.
The name of the type parameters CoD
and SoM
are arguably not super good, however, they are not used in the type definitions and will probably be very rarely in the code.
For represent discrete systems with long time-delays it could be beneficial to use the same lower fractional transformation that is typically used for continuous time delay systems. However then we would probably want to have an Int vector rather than a float vector, however we can probably ignore this use case for now.
As discussed by @ma-laforge in the discussion thread it would probably be a good idea if polynomial ratios where defined in the Polynomials package.
Ordering of type arguments, perhaps it makes more sense to have the argument for SISO/MIMO before the argument for the numeric type, since systems for SISO/MIMO will be treated slightly differently, and thus one would be able to just write for example StateSpace{Continuous, Siso}
. However right know we see the Siso/Mimo parameter simply as an indicator of whether to drop dimensions, an as such it is quite unimportant and could be put last.
The suggestion is that there are no fields nx, nu, ny, rather the types are immutable, and getter methods are used. I.e., getNx(sys) = size(sys.A, 1)
.
System types always have a field Ts::Float64
, and type arguments are used to indicate the system type (discrete or continuous)
Ts is put to NaN in the case of continuous time systems.
struct Continuous <: SystemType end
struct Discrete <: SystemType end
struct StateSpace{CoD, T, SoM}
...
Ts::Float64
end
Pros: Very straight-forward
Cons: For continuous systems there will be a field Ts, and memory will be allocated for it
abstract SystemTimeType
immutable ContinuousTime <: SystemTimeType; end
immutable DiscreteTime <: SystemTimeType
Ts::Float64
end
type StateSpace{S<:SystemTimeType, T, SoM}
...
time::S
end
Pros Clear weather it is a discrete or continuous system There will be no field Ts for continuous systems
Cons To reach in and get the sample time requires something like sys.time.Ts or to use a wrapper Conceptually a bit more involved than approach (1) There will be some memory usage also for Continuous Systems (I guess)
const Continuous = Void
struct StateSpace{TsType<:Union{Continuous, Float64}, T, IsSiso}
...
Ts::TsType
end
Pros: No memory allocation for Ts for continuous systems Easy to allow different types for Ts (Float64 --> Real)
Cons: A bit hard to read and non-transparent There will be a field Ts for continuous systems, altough no memory is allocated
Is there any need to have discrete systems with sampling times of another type than Float64? I can't really come up with anything.. Symbolic computations of discrete system frequency response, is the only thing that I can really come up with.
I would say that for approach 1, due to its extreme simplicity.
A long list of pros and cons was provided by @mfalt HERE
After some discussion with @mfalt we came to the conclusion that although there is no fundamental difference between SISO and MIMO systems, it is inconvenient having to drop extra dimensions from the output of lsim, freqresp, etc, when working with SISO systems. Since much control design only involves SISO systems, we found this reason alone to be sufficient to motivate a SISO type. Having to bother about dropping extra dimensions is also something which would put off new users.
In principle we're thinking that the type definitions for SISO and MIMO could be the same, and that only wrappers for the SISO case are added for freqresp, lsim, etc.
There are already quite many type parameters to keep track of, so although there is quite a small cost of adding this feature, I would advocate to wait until there is clear demand for it.
While this seems like a nice feature, it does not seemed to actually be used much in practice, the only place where we have seen it being used is in the MathWorks documentation. @mfalt proposes that we drop this feature, and possibly introduce new type NamedSystems
to which wraps an LTISystem
and provides the signal names.