ControlSystems.jl icon indicating copy to clipboard operation
ControlSystems.jl copied to clipboard

Function tf and ss

Open baggepinnen opened this issue 6 years ago • 2 comments

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. In ControlSystems/autodiff we have the functions tf and ss 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

  1. Define 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.
  2. Define const tf = TransferFunction tf can now be used interchangeably with TransferFunction, 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 and ss only work as shorthands, contain little or no code, and only redirect to appropriate constructor or convert method.

baggepinnen avatar Jun 26 '18 15:06 baggepinnen

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.

olof3 avatar Jun 26 '18 16:06 olof3

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)

mfalt avatar Jun 26 '18 18:06 mfalt