Skip to content

Commit fa5e62e

Browse files
baggepinnenclaude
andcommitted
Fix input-derivative column pairing in causal simplification call sites
MTK's linearize with allow_input_derivatives = true returns B with 2nu columns where column nu + i is the derivative of input i. The pairing passed to causal_simplification was derived by broadcasting 1:nu against the set of NONZERO derivative columns, which silently pairs every input to the same derivative channel when exactly one column is nonzero (and errors for other partial subsets). This produced wrong linearizations whenever inputs enter retained algebraic equations, e.g. through the numerical (non-inlined) linear-SCC reassembly: on a planar two-joint robot the input complementary sensitivity collapsed to a rank-1 projector instead of I at low frequency. The pairing is now positional over all inputs; all-zero derivative columns contribute nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4JdEEqr6ifdSbp6MvbrU8
1 parent 55107fc commit fa5e62e

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

src/ode_system.jl

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,12 @@ function RobustAndOptimalControl.named_ss(
114114
unames = symstr.(inputs)
115115
if nu > 0 && size(matrices.B, 2) == 2nu
116116
# This indicates that input derivatives are present
117-
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end]))) .+ nu
118-
u2du = (1:nu) .=> duinds # This maps inputs to their derivatives
117+
# Derivative column nu + i is the derivative of input i (see the MTK docs for
118+
# `linearize` with `allow_input_derivatives = true`), so the pairing is positional.
119+
# All-zero derivative columns contribute nothing and are included for simplicity;
120+
# a pairing derived from the set of nonzero columns mispairs inputs when only a
121+
# subset of the derivative columns is nonzero.
122+
u2du = [i => i + nu for i in 1:nu] # This maps inputs to their derivatives
119123
lsys = causal_simplification(matrices, u2du; descriptor, simple_infeigs, big, balance)
120124
else
121125
lsys = ss(matrices...)
@@ -154,8 +158,12 @@ function RobustAndOptimalControl.named_ss(
154158
unames = symstr.(inputs)
155159
if nu > 0 && size(matrices.B, 2) == 2nu
156160
# This indicates that input derivatives are present
157-
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end]))) .+ nu
158-
u2du = (1:nu) .=> duinds # This maps inputs to their derivatives
161+
# Derivative column nu + i is the derivative of input i (see the MTK docs for
162+
# `linearize` with `allow_input_derivatives = true`), so the pairing is positional.
163+
# All-zero derivative columns contribute nothing and are included for simplicity;
164+
# a pairing derived from the set of nonzero columns mispairs inputs when only a
165+
# subset of the derivative columns is nonzero.
166+
u2du = [i => i + nu for i in 1:nu] # This maps inputs to their derivatives
159167
lsys = causal_simplification(matrices, u2du; descriptor, simple_infeigs, big, balance, verbose=false)
160168
else
161169
lsys = ss(matrices...)
@@ -307,8 +315,12 @@ function named_sensitivity_function(
307315
fm(x) = convert(Matrix{Float64}, x)
308316
if nu > 0 && size(matrices.B, 2) == 2nu
309317
# This indicates that input derivatives are present
310-
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end]))) .+ nu
311-
u2du = (1:nu) .=> duinds # This maps inputs to their derivatives
318+
# Derivative column nu + i is the derivative of input i (see the MTK docs for
319+
# `linearize` with `allow_input_derivatives = true`), so the pairing is positional.
320+
# All-zero derivative columns contribute nothing and are included for simplicity;
321+
# a pairing derived from the set of nonzero columns mispairs inputs when only a
322+
# subset of the derivative columns is nonzero.
323+
u2du = [i => i + nu for i in 1:nu] # This maps inputs to their derivatives
312324
lsys = causal_simplification(matrices, u2du; descriptor, simple_infeigs, big, balance)
313325
else
314326
lsys = ss(matrices...)

0 commit comments

Comments
 (0)