Open baggepinnen opened 6 years ago
This makes a lot of sense. I think that this would be a very good thing to do.
Just recall the following
tf
<-> TransferFunction{SisoRational}
zpk
<-> TransferFunction{SisoZpk}
That both tf
and zpk
creates transfer functions is quite inconsequential, and in principle tf
should have a more specific name. Don't have any good suggestions, and I guess most people are used to this.
I guess that the flexibility of approach 1 would make things is a bit nicer, avoiding that constructors have to accept various system representations.
We should definetely get rid of internal calls to tf
, zpk
and ss
, but I'm not sure that there is an obvious way to create the user interface, although it would be nice to make it more in line with other packages.
One example is that we might want to throw warnings if the user calls e.g tf([a],[1 a])
with a complex a
as suggested by @olof3 since this is problably usually a mistake by the user. On the other hand, it seems worse to throwing a warning for a constructor like TransferFunction([a],[1,a])
or TransferFunction{SisoRational}([a],[1,a])
which would be caught by something like
TransferFunction(num::AbstractArray{T}, den::AbstractArray{T}, args...) =
TransferFunction{SisoRational{T}}(num, den, args...)
So I think that we should go by "1.", possibly making tf a bit more specialized. For example defaulting to Ts=0 in tf, but not TransferFunction, or throwing warnings in tf.
This could act as a bridge where we say "Use tf and it will work as most people expect, and will guide you if you do something weird, perfect for new users to julia such as many students (includes some MATLAB compatibility). Use the TransferFunction constructors if you know what you are doing, the type will either be specified by the user or inferred by the arguments, and you may accidentally get a ZPK system with k::Float64, z,p::Int32
as in TransferFunction{SisoZpk}([-1],[-2,-3], 1.5)
In julia, constructors are used to construct types and types and constructors share name.
convert
is used to convert an instance of one type to another type. InControlSystems/autodiff
we have the functionstf
andss
which do a bit of both. This is rather confusing and can be easily avoided.If we let all constructors be constructors, we can either
tf(args...;kwargs...) = TransferFunction(args...; kwargs...)
This allows more specific methods to create another, more specialized type of transfer function if one is added later.const tf = TransferFunction
tf
can now be used interchangeably withTransferFunction
, bot as constructor and as type. This is somewhat less flexible i believe.To be consistent with all other julia packages, I therefore propose that
tf
andss
only work as shorthands, contain little or no code, and only redirect to appropriate constructor or convert method.