You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Signal names do not propagate through algebraic scalar/matrix operations #902
When a system with named signals is combined with a constant system represented by a scalar or matrix, the signal names are lost. For example
ctrl = ct.rss(2, 1, 1, input='e', output='u') * 2
would be expected (by me) to have input 'e' and output 'u'. But what you get instead is
<LinearICSystem:sys[4]:['u[0]']->['y[0]']>
This is happening because scaling by a factor of 2 is internally handled by converting the number `2' into an input/output system then creating a new system that is the series composition of the two systems. But in doing that, you lose the signal names.
There is a similar problem using the series function, which also loses signal names (I would expect the input and output signal names to be preserved).
I encountered this issue last quarter (multiplying by a scalar loses signal names) and initially thought it was a bug before I realized that multiplying by a scalar is technically creating a new system.
It also would be very convenient to be able do this in python when you are constructing a transfer function in which you want to scale all coefficients in the numerator by a constant. ct.tf(2*[1,2,3],[1,1,1]) does not do that! (I think it gives the numerator polynomial list six elements!).
Maybe operations with a constant/matrix should be a special case that preserves signal names?
Relatedly, I am not sure if the operations * and + preserve input and output signal names if both are systems.
I started to work on an implementation, but I'm not actually sure what I think the right behavior should be:
For P3 = P1 * P2, it seems clear that inputs should be the names of the signals in P2 and outputs should be the names of the signals in P1.
For P3 = P1 + P2, if the inputs and outputs have the same names then they should be preserved, but if they have different names then ???
For P2 = -P1, it seems odd that the inputs and outputs would have the same signal names, but perhaps that is the natural choice?
If we sort out rules for these cases, we can propagate those to series and parallel, while also allowing names to be overridden using the inputs and outputs parameters.
The feedback function is also a bit odd: for feedback(P1, P2) the outputs should be those of P1, but are the inputs those of P1 as well (since really they will be added/subtracted from the output of P2, depending on the sign of the gain).
That seems reasonable and straightforward for series and negation connections.
As far as adding two systems with incompatible names, i think signal names should be seen as a convenience feature that can get overridden if the connection is directly specified by e.g. + or * or series rather than interconnect. And therefore if signal names are not the default and do not match, the systems should still get connected as long as their ninputs and noutputs are compatible. New (default) signal names should be created for incompatible names, and the user should get a warning about mismatched signal names.
There should probably be a similar warning for series connections if the signal names do not match, but the systems should still get combined.
As for feedback, I think the input should always get a new default name. Should r be the default instead of u?
Activity
sawyerbfuller commentedon Jun 3, 2023
I encountered this issue last quarter (multiplying by a scalar loses signal names) and initially thought it was a bug before I realized that multiplying by a scalar is technically creating a new system.
It also would be very convenient to be able do this in python when you are constructing a transfer function in which you want to scale all coefficients in the numerator by a constant.
ct.tf(2*[1,2,3],[1,1,1])does not do that! (I think it gives the numerator polynomial list six elements!).Maybe operations with a constant/matrix should be a special case that preserves signal names?
Relatedly, I am not sure if the operations * and + preserve input and output signal names if both are systems.
murrayrm commentedon Jun 3, 2023
I started to work on an implementation, but I'm not actually sure what I think the right behavior should be:
P3 = P1 * P2, it seems clear that inputs should be the names of the signals inP2and outputs should be the names of the signals inP1.P3 = P1 + P2, if the inputs and outputs have the same names then they should be preserved, but if they have different names then ???P2 = -P1, it seems odd that the inputs and outputs would have the same signal names, but perhaps that is the natural choice?If we sort out rules for these cases, we can propagate those to
seriesandparallel, while also allowing names to be overridden using theinputsandoutputsparameters.The
feedbackfunction is also a bit odd: forfeedback(P1, P2)the outputs should be those ofP1, but are the inputs those ofP1as well (since really they will be added/subtracted from the output ofP2, depending on the sign of the gain).sawyerbfuller commentedon Jun 5, 2023
That seems reasonable and straightforward for series and negation connections.
As far as adding two systems with incompatible names, i think signal names should be seen as a convenience feature that can get overridden if the connection is directly specified by e.g. + or * or
seriesrather thaninterconnect. And therefore if signal names are not the default and do not match, the systems should still get connected as long as their ninputs and noutputs are compatible. New (default) signal names should be created for incompatible names, and the user should get a warning about mismatched signal names.There should probably be a similar warning for series connections if the signal names do not match, but the systems should still get combined.
As for feedback, I think the input should always get a new default name. Should
rbe the default instead ofu?