Skip to content

Possible bug: control.interconnect fails to construct a extended system with zero input and one output (D matrix shape mismatch) #1176

Closed

Description

@yuu5g0g0

About the problem

Summary

I attempted to simulate a control system with an output-feedback controller, defining a plant and a controller as subsystems.
When using control.interconnect to connect these subsystems, an error occurs because an extended system obtained by connecting subsystems has zero input and one output.
Is it impossible to define a system with zero input and one output using the control.interconnect function?

Error message

control.exception.ControlDimension: Incompatible dimensions of D matrix; expected (1, 0) but found (0, 0)

System information

  • OS: macOS Sonoma 14.3.1
  • Python: 3.12.2
  • python-control: 0.10.2

Cause of this problem

When we set the inputs and outputs of the extended system as zero input and one input, the D matrix of the extended system has (1, 0) dimension.
However, the dimension of D matrix is converted to (0, 0) dimension by _ssmatrix function at line 218 of statesp.py.
As a result, the mismatch of the dimensions occurs.
(When we set both inputs and outputs to zero, the error does not occur.)

To reproduce the error

import numpy as np
import control as ct

def main():

    # Define the coefficient matrices of plant P
    A = np.array(
        [
            [1.00, 1.00],
            [0.00, -2.0],
        ]
    )
    B = np.array(
        [
            [0.00],
            [1.00]
        ]
    )
    C = np.array(
        [
            [1.00, 0.00]
        ]
    )

    # Define the coefficient matrices of controller C
    A_c = np.array(
        [
            [2.25, 1.00],
            [-5.0, -0.5]
        ]
    )
    B_c = np.array(
        [
            [-1.25],
            [4.500]
        ]
    )
    C_c = np.array(
        [
            [-0.50, 1.500]
        ]
    )

    # Define the subsystems
    P = ct.ss(
        A,
        B,
        C,
        np.zeros([C.shape[0], B.shape[1]]),
        inputs=[f'u_p{i}' for i in range(B.shape[1])],
        outputs=[f'y_p{i}' for i in range(C.shape[0])],
        name='P',
        dt=True
    )
    C = ct.ss(
        A_c,
        B_c,
        C_c,
        np.zeros([C_c.shape[0], B_c.shape[1]]),
        inputs=[f'y_p{i}' for i in range(B_c.shape[1])],
        outputs=[f'u_p{i}' for i in range(C_c.shape[0])],
        name='C',
        dt=True
    )

    sys = ct.interconnect(
        [P, C],
        inplist=None,
        outlist=[f'y_p{i}' for i in range(P.C.shape[0])]
    )

if __name__ == '__main__':
    main()

Activity

  1. murrayrm commented on Jul 27, 2025

    @murrayrm
    Member

    I took a quick look and the problem is not with interconnect, but rather with the way StateSpace systems are initialized.

    For whoever picks this one up, there is some code in _ssmatrix (used to preprocess state space matrices) that is converting the shape of the D matrix incorrectly:

        elif (ndim == 2 and shape == (1, 0)) or \
             (ndim == 1 and shape == (0, )):
            # Passed an empty matrix or empty vector; change shape to (0, 0)
            shape = (0, 0)
    

    What is happening is that the D matrix for this example has shape (1, 0) [1 output, 0 inputs)] and it gets converted to shape (0, 0), causing an error. I think the fix is to also check the size of the array, so that [] and [[]] both get converted to an empty array (which is later cast to the correct shape in StateSpace.__init__).

  2. added theissue type on Jul 27, 2025
  3. added this to the 0.10.3 milestone on Jul 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions