Skip to content

Commit 8bfb6c9

Browse files
authored
Merge pull request #108 from JuliaControl/merge_nonunique
refactor merging of non-unique inputs
2 parents c189302 + 89bd51c commit 8bfb6c9

File tree

1 file changed

+51
-21
lines changed

1 file changed

+51
-21
lines changed

src/named_systems2.jl

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,56 @@ function measure(s::NamedStateSpace, names)
338338
sminreal(named_ss(s2; s.x, s.u, y=names, name=s.name))
339339
end
340340

341+
"""
342+
merge_nonunique_inputs(sys)
343+
344+
Take a system where one or more input names are appearing more than once, and return a system where the columns of the ``B`` and ``D` matrices corresponding to multiple repeated inputs have been summed together. The resulting system have unique input signal names.
345+
346+
To avoid accidental misuse, a warning is issued if two added colums contain non-zero entries in the same row.
347+
348+
# Example
349+
350+
A system with ``B`` matrix and input names given by
351+
```
352+
B = [1 0 0
353+
0 2 0
354+
0 0 3]
355+
356+
u = [:u1, :u2, :u1] # Input names
357+
```
358+
where the input name `:u1` appears more than once, will be reduced to
359+
```
360+
B = [1 0
361+
0 2
362+
3 0]
363+
u = [:u1, :u2]
364+
```
365+
"""
366+
function merge_nonunique_inputs(sys)
367+
i = 0
368+
inputnames = copy(sys.u)
369+
while i < length(inputnames)
370+
i += 1
371+
inds = findall(n == inputnames[i] for n in inputnames)
372+
length(inds) == 1 && continue
373+
# Check that the B-matrix entries are non-overlapping
374+
Bi = sys.B[:, inds]
375+
Di = sys.D[:, inds]
376+
any(>(1), sum(.! iszero.(Bi), dims=2)) && @warn("Input names are not unique and the multiple B-matrix columns associated with the name $(u[i]) have a non-empty intersection of non-zero entries.")
377+
any(>(1), sum(.! iszero.(Di), dims=2)) && @warn("Input names are not unique and the multiple D-matrix columns associated with the name $(u[i]) have a non-empty intersection of non-zero entries.")
378+
B = copy(sys.B)
379+
D = copy(sys.D)
380+
B[:, inds[1]] = sum(Bi, dims=2)
381+
D[:, inds[1]] = sum(Di, dims=2)
382+
kept_inds = setdiff(1:size(B, 2), inds[2:end])
383+
B = B[:, kept_inds]
384+
D = D[:, kept_inds]
385+
deleteat!(inputnames, inds[2:end])
386+
sys = named_ss(ControlSystemsBase.basetype(sys.sys)(sys.A, B, sys.C, D, sys.timeevol); x=sys.x, u=inputnames, y=sys.y, name=sys.name, unique=false)
387+
end
388+
sys
389+
end
390+
341391
"""
342392
feedback(s1::NamedStateSpace, s2::NamedStateSpace;
343393
w1 = [], u1 = (:), z1 = (:), y1 = (:),
@@ -353,27 +403,7 @@ To simplify creating complicated feedback interconnections, see `connect`.
353403
function ControlSystemsBase.feedback(s1::NamedStateSpace{T}, s2::NamedStateSpace{T};
354404
u1=:, w1=:,z1=:,y1=:,u2=:,y2=:,w2=[],z2=[], unique = true, kwargs...) where {T <: CS.TimeEvolution}
355405
if !unique
356-
i = 0
357-
s1u = copy(s1.u)
358-
while i < length(s1u)
359-
i += 1
360-
inds = findall(n == s1u[i] for n in s1u)
361-
length(inds) == 1 && continue
362-
# Check that the B-matrix entries are non-overlapping
363-
Bi = s1.B[:, inds]
364-
Di = s1.D[:, inds]
365-
any(>(1), sum(.! iszero.(Bi), dims=2)) && error("Input names are not unique and the multiple B-matrix columns associated with the name $(u[i]) have a non-empty intersection of non-zero entries.")
366-
any(>(1), sum(.! iszero.(Di), dims=2)) && error("Input names are not unique and the multiple D-matrix columns associated with the name $(u[i]) have a non-empty intersection of non-zero entries.")
367-
B = copy(s1.B)
368-
D = copy(s1.D)
369-
B[:, inds[1]] = sum(Bi, dims=2)
370-
D[:, inds[1]] = sum(Di, dims=2)
371-
kept_inds = setdiff(1:size(B, 2), inds[2:end])
372-
B = B[:, kept_inds]
373-
D = D[:, kept_inds]
374-
deleteat!(s1u, inds[2:end])
375-
s1 = named_ss(ControlSystemsBase.basetype(s1.sys)(s1.A, B, s1.C, D, s1.timeevol); x=s1.x, u=s1u, y=s1.y, name=s1.name, unique)
376-
end
406+
s1 = merge_nonunique_inputs(s1)
377407
end
378408

379409
W1 = names2indices(w1, s1.u)

0 commit comments

Comments
 (0)