GeezerVison is showing github.com — Unexpected and unwanted behaviour of control.ctrb · Issue #1097 · python-control/python-control
Unexpected and unwanted behaviour of control.ctrb #1097DescriptionI have found some unexplainable and unwanted behavior of the control.ctrb functions, which returns a 'controllability matrix' with incorrect dimensions rather than returning an error/warning that the $B$ matrix is not dimensioned properly.
MWE:
import numpy as np
import control as ct
A = np.array([[1, 1], [0, 1]])
b = np.array([1, 1])
C = ct.ctrb(A, b) # Rather then 1) returning an error that b is not properly dimensioned, or 2) assuming that b is a columns vector, it instead returns a matrix with shape 2 x 4, which makes no sense for a controllability matrix
C_T = ct.ctrb(A, np.atleast_2d(b).T) # Explicitly specifying that b is a column vector fixes this and C_T is now a 2 x 2 matrix
I believe the behavior is incorrect, and it took me quite some time to understand what was going wrong; any (dis)agreement would be appreciated, thanks. Activityroryyorke commented on Jan 19, 2025 the arguments for ctrb and obsv aren't checked for size.
In [42]: ct.ctrb(np.eye(2), 0.5)
Out[42]:
array([[0.5, 0.5],
[0.5, 0.5]])
In [43]: ct.ctrb(0.3*np.eye(2), 0.5)
Out[43]:
array([[0.5 , 0.15],
[0.5 , 0.15]])
In [44]: ct.ctrb(0.1*np.eye(2), 1)
Out[44]:
array([[1. , 0.1],
[1. , 0.1]])
In [45]: ct.ctrb(0.1*np.eye(2), np.array([1,1]))
Out[45]:
array([[1. , 1. , 0.1, 0.1],
[1. , 1. , 0.1, 0.1]])
In [46]: ct.obsv(0.1*np.eye(2), 1)
Out[46]:
array([[1. , 1. ],
[0.1, 0.1]])
In [47]: ct.obsv(0.1*np.eye(2), [1, 1])
Out[47]:
array([[1. , 1. ],
[0.1, 0.1]])
In [48]: ct.obsv(0.1*np.eye(2), [1, 1, 1])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[48], line 1
----> 1 ct.obsv(0.1*np.eye(2), [1, 1, 1])
File ~/miniforge3/envs/work/lib/python3.12/site-packages/control/statefbk.py:1070, in obsv(A, C, t)
1068 # Construct the observability matrix
1069 obsv = np.zeros((t * p, n))
-> 1070 obsv[:p, :] = cmat
1072 for k in range(1, t):
1073 obsv[k * p:(k + 1) * p, :] = np.dot(obsv[(k - 1) * p:k * p, :], amat)
ValueError: could not broadcast input array from shape (1,3) into shape (1,2)
The fix seems straightforward -- adapt the _ssmatrix calls and size checks from the statesp.StateSpace.__init__. Reacted by Bart Wolleswinkel
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|