Skip to content

Fix forced_response time inference for transposed inputs - #1229

Open
marko1olo wants to merge 1 commit into
python-control:mainfrom
marko1olo:fix-forced-response-transpose-inputs
Open

Fix forced_response time inference for transposed inputs#1229
marko1olo wants to merge 1 commit into
python-control:mainfrom
marko1olo:fix-forced-response-transpose-inputs

Conversation

@marko1olo

@marko1olo marko1olo commented Jun 7, 2026

Copy link
Copy Markdown

Summary

Fixes #931.

When forced_response() is called for a discrete-time system with timepts=None, it infers the generated time vector length from inputs. With transpose=True, 2D input data is supplied in (time, input) order, but the current code still reads U.shape[1], treating the input count as the number of time steps.

This changes the inference to use U.shape[0] for 2D inputs when transpose=True, matching the later _check_convert_array(..., transpose=True) conversion.

Validation

  • Red repro before the fix: forced_response(sys, inputs=U, transpose=True) with U.shape == (5, 2) failed with ValueError: Parameter U: Wrong shape ... Expected: (2, 2).
  • python -m pytest control/tests/timeresp_test.py -k forced_response_transpose_without_time_vector -q passed.
  • python -m pytest control/tests/timeresp_test.py -q -p no:cacheprovider passed: 253 passed, 46 skipped.
  • python -m ruff check --no-cache control\timeresp.py control\tests\timeresp_test.py passed.
  • PYTHONPYCACHEPREFIX=C:\tmp\pycache-python-control-931 python -m compileall -q control\timeresp.py control\tests\timeresp_test.py passed.
  • git diff --check passed.

AI Disclosure: Codex (ChatGPT 5.5) was used during code navigation, initial drafting, and PR text preparation. All logic, code changes, and test cases have been manually reviewed, verified, and tested locally by the author in accordance with the NumPy AI Policy.

Comment thread control/timeresp.py Outdated
# Set T to equally spaced samples with same length as U
if U.ndim == 1:
n_steps = U.shape[0]
elif transpose:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add another branch here instead of or with the above? I.e.,

if U.ndim == 1 or transpose:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good point. I simplified this in d12d4896 to use if U.ndim == 1 or transpose: since both cases use U.shape[0].

Rechecked locally:

  • python -m pytest control\tests\timeresp_test.py::TestTimeresp::test_forced_response_transpose_without_time_vector -q
  • python -m pytest control\tests\timeresp_test.py -q
  • python -m ruff check control\timeresp.py control\tests\timeresp_test.py
  • python -m compileall -q control\timeresp.py control\tests\timeresp_test.py
  • git diff --check

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — you're right, the or is cleaner. Updated.

@murrayrm

murrayrm commented Aug 9, 2026

Copy link
Copy Markdown
Member

@marko1olo Please rebase off of main to trigger updated CI checks from PR #1243.

@coveralls

coveralls commented Aug 13, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 94.757%. remained the same — marko1olo:fix-forced-response-transpose-inputs into python-control:main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

forced_response transpose bug

4 participants