ArgumentError: u names not unique. Repeated names:

Hi,

I’m getting this error when using connect. The error is pretty self-explanatory and the solution is workable.

However, every time I’m getting that error, I actually have two inputs that have the same name because they are intended to receive the same input signal. So connect might as well merge them, rather than me having to rename them to in1 and in2 and add a splitter for the name in.

Is there any way to get such behavior? I might also consider submitting a patch, but I’m not really blessed with much free time these days.

I’m not sure I fully understand the circumstances you’re getting those errors in - do you have a small example showcasing the error?

sys_1=named_ss(ssrand(1,2,2), u=[:in_x, :in_y], y=:out_z, x=[:x1, :x2])
sys_2=named_ss(ssrand(1,2,2), u=[:in_y, :in_z], y=:out, x = [:x3, :x4])
sys_connect = connect([sys_1, sys_2], [:out_z => :in_z]; w1 = [:in_x, :in_y], z1 = :out)

sys_1 and sys_2 both take the input in_y. I would like those two inputs to appear as a single input in sys_connect. Currently, I would do this is by renaming the inputs to in_y1 and in_y2, then creating a splitter for in_y and connect the outputs of the splitter to the respective inputs of each system. I was wondering if there is a way to skip that step, because for me, the logical consequence of two inputs being named the same is to treat them as being the same. The same may or may not make sense for outputs, but that requires addition and it’s also not my current problem, so I don’t want to discuss that here.

Sorry, what package is connect from? This does not seem to be from Base, so I think you’ll want to direct that feature request to the package in question.

I’m afraid it is very difficult to understand what you are asking about. What packages are you using? Please include fully runnable code with all the necessary using or import statements.

I’m afraid the thread title itself is far from self-explanatory. In general, it is recommended to read the following post, which can help write questions in a clear way:

The connect in question comes from RobustAndOptimalControl.jl and I agree that it can be somewhat hard to use.

The relevant code that throws the error even contains the following comment

# TODO: If some name below is repeated, perhaps the B matrix can be reduced in width?
# This could be optional, i.e., unique_names=true

I’ll try to think about a way of supporting this without introducing a footgun.

@maltee1 please try out this branch and see if it makes the connection experience smoother in this case

@Sukera @DNF Apologies, I was too focused on control theory, so I forgot that you can do other things with julia…

@baggepinnen That appears to be what I’m looking for, however, it only seems to work on continuous systems. For a discrete system, it prints the new Error, despite unique = false being set.
I really appreciate your outstanding “customer” service, is there somewhere I can donate to you?

1 Like

Would you mind sharing an example that exposes this? I tried the following and it works fine

# Discrete
s1 = ssrand(1,2,2, Ts=1)
s2 = ssrand(1,2,2, Ts=1)
sys_1 = named_ss(s1, u=[:in_x, :in_y], y=:out_z, x=[:x1, :x2])
sys_2 = named_ss(s2, u=[:in_y, :in_z], y=:out, x = [:x3, :x4])

@test_throws "u names not unique. Repeated names: [:in_y] To allow connecting a single input signal to several inputs with the same name, pass `unique = false`." connect([sys_1, sys_2], [:out_z => :in_z]; w1 = [:in_x, :in_y], z1 = :out)

sys_connect = connect( # Works fine
    [sys_1, sys_2],
    [:out_z => :in_z];
    w1 = [:in_x, :in_y],
    z1 = :out,
    unique=false
)

Thanks! User feedback and detailed error reports is plenty sufficient :wink:

I wrongly believed it was due to the system being discrete, but apparently that has nothing to do with it. I can’t really tell what exactly triggers it, but here’s an example I’ve reduced as much as I could:

using RobustAndOptimalControl

sys_1 = named_ss(ssrand(1,3,2), u=[:in_a, :in_b, :in_c], y=[:ui_ref], x=[:x1, :x2])
sys_2 = named_ss(ssrand(1,3,2), u=[:in_e, :in_c, :in_d], y=:out_a, x=[:x3, :x4]);
sys_3 = named_ss(ssrand(1,1,1), u=:in_d, y=:out_e, x=:x5);
sys_ctrl = connect([sys_1, sys_2, sys_3],
    [:out_a => :in_a, :out_e => :in_e ];
    w1 = [:in_b, :in_c, :in_d],
    z1 = :ui_ref,
    unique = false)

fails with:

ERROR: ArgumentError: u names not unique. Repeated names: [:in_d] To allow connecting a single input signal to several inputs with the same name, pass `unique = false`.

append with the three systems still seems to work.
I assume my code is calling this method, which doesn’t have the unique argument.

I can’t tell why this particular example would call that method, but maybe you can.

Thanks for the example! The fix turned out to be simple, I’ve pushed a fix to the PR branch

1 Like

I thought I tested multiple nonunique inputs because I suspected that to be the issue, turns out I didn’t test properly.

It works. Wonderful!

1 Like

@baggepinnen Now I’m trying to combine two systems using append and am hoping to have their nonunique outputs merged as well, which it doesn’t do. connect apparently requires me to specify at least one connection. If you get the chance, do you think you could extend the behavior of unique = false to the append function?

I’m not sure if this sounds correct, you are talking about the function append which performs block-diagonal concatenation, i.e., the operation below

 u1 ┌───┐ y1
───►│ P1├──►         u1  ┌─────┐ y1
    └───┘             ──►│     ├──►
              ────►   ──►│  P12├──►
 u2 ┌───┐ y2         u2  └─────┘ y2
───►│ P2├──►
    └───┘

but you’re asking for it to behave like vertical concatenation P12 = [P1; P2]

 u  ┌───┐ y1
───►│ P1├──►             ┌─────┐ y1
    └───┘             ──►│     ├──►
              ────►   u  │  P12├──►
 u  ┌───┐ y2             └─────┘ y2
───►│ P2├──►
    └───┘

Can’t what you’re asking for be realized using the connect function?

s1 = ssrand(1,2,2)
s2 = ssrand(1,2,2)
sys1 = named_ss(s1, "A", u=[:u1, :u2]) # Input u2 appears in both systems
sys2 = named_ss(s2, "B", u=[:u2, :u3])

sys12 = connect(
    [sys1, sys2],
    Pair{Symbol, Symbol}[]; # Empty connection vector of the correct type
    w1 = [:u1, :u2, :u3],
    z1 = [sys1.y; sys2.y],
    unique = false
)

The resulting system has the input u2 merged.

julia> sys12 = connect([sys1, sys2], Pair{Symbol, Symbol}[], w1 = [:u1, :u2, :u3], z1 = [sys1.y; sys2.y], unique=false)
NamedStateSpace{Continuous, Float64}
A = 
 -0.06812632965152318   0.5720015099467834  0.0                   0.0
 -0.9590957208034123   -1.2581734396885567  0.0                   0.0
  0.0                   0.0                 0.20021007961714576  -0.7677092543034114
  0.0                   0.0                 0.6655398066449922   -1.8810324473875886
B = 
 -0.5285225476394938  -1.3112160323503186   0.0
 -0.6058648756516474  -1.1713675813478548   0.0
  0.0                 -0.3626155828058133   1.6492509268100324
  0.0                  1.1480210367263297  -0.4767449301439349
C = 
 0.8695036855393466  -0.8001568554043171   0.0                  0.0
 0.0                  0.0                 -0.8301044609973323  -0.6223243969601403
D = 
 0.5287883123468724   1.3107581033813325   0.0
 0.0                 -0.37456658050500763  3.507504356656879

Continuous-time state-space model
With state  names: Ax1##feedback#226 Ax2##feedback#226 Bx1##feedback#226 Bx2##feedback#226
     input  names: u1 u2 u3
     output names: Ay By

Apologies… I tried that, but apparently I got the syntax wrong and assumed it didn’t work. Thanks a lot!

1 Like