{"action":"created","issue":{"url":"https://api.github.com/repos/scipy/scipy/issues/5753","repository_url":"https://api.github.com/repos/scipy/scipy","labels_url":"https://api.github.com/repos/scipy/scipy/issues/5753/labels{/name}","comments_url":"https://api.github.com/repos/scipy/scipy/issues/5753/comments","events_url":"https://api.github.com/repos/scipy/scipy/issues/5753/events","html_url":"https://github.com/scipy/scipy/issues/5753","id":128074326,"number":5753,"title":"signal.tf2ss doesn't handle SIMO transfer functions","user":{"login":"arvoelke","id":5420057,"avatar_url":"https://avatars.githubusercontent.com/u/5420057?v=3","gravatar_id":"","url":"https://api.github.com/users/arvoelke","html_url":"https://github.com/arvoelke","followers_url":"https://api.github.com/users/arvoelke/followers","following_url":"https://api.github.com/users/arvoelke/following{/other_user}","gists_url":"https://api.github.com/users/arvoelke/gists{/gist_id}","starred_url":"https://api.github.com/users/arvoelke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arvoelke/subscriptions","organizations_url":"https://api.github.com/users/arvoelke/orgs","repos_url":"https://api.github.com/users/arvoelke/repos","events_url":"https://api.github.com/users/arvoelke/events{/privacy}","received_events_url":"https://api.github.com/users/arvoelke/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-01-22T03:21:21Z","updated_at":"2016-02-12T04:49:34Z","closed_at":null,"body":"The routine `signal.ss2tf` will return a list of numerator polynomials, one for each output in the state-space representation. However, `signal.tf2ss` is unable to invert this in 0.17.0rc2, although it seems to attempt to do so in the codebase.\r\n\r\nThis problem is immediately visible when discretizing a SIMO transfer function:\r\n\r\n```\r\ntf = ([[1, 0], [1, 1]], [1, 1])\r\nprint scipy.signal.cont2discrete(tf, 0.01)\r\n```\r\n\r\n```\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-32-d3238586ff06> in <module>()\r\n      1 tf = ([[1, 0], [1, 1]], [1, 1])\r\n      2 #ss = scipy.signal.tf2ss(*tf)\r\n----> 3 print scipy.signal.cont2discrete(tf, 0.01)\r\n      4 \r\n      5 ss = scipy.signal.tf2ss(*tf)\r\n\r\nc:\\users\\aaron\\appdata\\local\\enthought\\canopy\\user\\lib\\site-packages\\scipy\\signal\\cont2discrete.pyc in cont2discrete(sys, dt, method, alpha)\r\n     78         sysd = cont2discrete(tf2ss(sys[0], sys[1]), dt, method=method,\r\n     79                              alpha=alpha)\r\n---> 80         return ss2tf(sysd[0], sysd[1], sysd[2], sysd[3]) + (dt,)\r\n     81     elif len(sys) == 3:\r\n     82         sysd = cont2discrete(zpk2ss(sys[0], sys[1], sys[2]), dt, method=method,\r\n\r\nc:\\users\\aaron\\appdata\\local\\enthought\\canopy\\user\\lib\\site-packages\\scipy\\signal\\ltisys.pyc in ss2tf(A, B, C, D, input)\r\n    272 \r\n    273     # Check consistency and make them all rank-2 arrays\r\n--> 274     A, B, C, D = abcd_normalize(A, B, C, D)\r\n    275 \r\n    276     nout, nin = D.shape\r\n\r\nc:\\users\\aaron\\appdata\\local\\enthought\\canopy\\user\\lib\\site-packages\\scipy\\signal\\ltisys.pyc in abcd_normalize(A, B, C, D)\r\n    208     A = _restore(A, (p, p))\r\n    209     B = _restore(B, (p, q))\r\n--> 210     C = _restore(C, (r, p))\r\n    211     D = _restore(D, (r, q))\r\n    212 \r\n\r\nc:\\users\\aaron\\appdata\\local\\enthought\\canopy\\user\\lib\\site-packages\\scipy\\signal\\ltisys.pyc in _restore(M, shape)\r\n    163     else:\r\n    164         if M.shape != shape:\r\n--> 165             raise ValueError(\"The input arrays have incompatible shapes.\")\r\n    166         return M\r\n    167 \r\n\r\nValueError: The input arrays have incompatible shapes.\r\n```\r\n\r\nFor transfer functions, `signal.cont2discrete` converts the system to state-space, discretizes it, and then converts it back. The first step in particular is the issue, since there seem be a number of issues with `t2fss` when given a SIMO transfer function :\r\n - tf2ss incorreclty squeezes the D matrix (and this mistake was actually acknowledged on [this line of test code](https://github.com/scipy/scipy/blame/master/scipy/signal/tests/test_ltisys.py#L260))\r\n    ```\r\n    >>> tf = ([[1, 2], [1, 1]], [1, 2])\r\n    >>> print scipy.signal.tf2ss(*tf)[3].shape\r\n    (2L,)\r\n    ```\r\n\r\n - For larger orders, the resulting system has wrong dimensionality\r\n    ```\r\n    >>> tf = ([[1, 0, 1], [1, 1, 1]], [1, 1, 1])\r\n    >>> print [s.shape for s in scipy.signal.tf2ss(*tf)]\r\n    [(2L, 2L), (2L, 1L), (2L, 2L), (2L,)]\r\n    ```\r\n\r\n - And in some cases, it fails:\r\n   ```\r\n    >>> tf = ([[1, 2, 3], [1, 2, 3]], [1, 2, 3, 4])\r\n    >>> print scipy.signal.tf2ss(*tf)\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-73-efb39b6e8c65> in <module>()\r\n      6 \r\n      7 tf = ([[1, 2, 3], [1, 2, 3]], [1, 2, 3, 4])\r\n----> 8 print scipy.signal.tf2ss(*tf)\r\n      9 \r\n     10 #print scipy.signal.cont2discrete(tf, 0.01)\r\n\r\nc:\\users\\aaron\\appdata\\local\\enthought\\canopy\\user\\lib\\site-packages\\scipy\\signal\\ltisys.pyc in tf2ss(num, den)\r\n    129     A = r_[frow, eye(K - 2, K - 1)]\r\n    130     B = eye(K - 1, 1)\r\n--> 131     C = num[:, 1:] - num[:, 0] * den[1:]\r\n    132     return A, B, C, D\r\n    133 \r\n\r\nValueError: operands could not be broadcast together with shapes (2,) (3,) \r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/scipy/scipy/issues/comments/183179156","html_url":"https://github.com/scipy/scipy/issues/5753#issuecomment-183179156","issue_url":"https://api.github.com/repos/scipy/scipy/issues/5753","id":183179156,"user":{"login":"gfyoung","id":9273653,"avatar_url":"https://avatars.githubusercontent.com/u/9273653?v=3","gravatar_id":"","url":"https://api.github.com/users/gfyoung","html_url":"https://github.com/gfyoung","followers_url":"https://api.github.com/users/gfyoung/followers","following_url":"https://api.github.com/users/gfyoung/following{/other_user}","gists_url":"https://api.github.com/users/gfyoung/gists{/gist_id}","starred_url":"https://api.github.com/users/gfyoung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gfyoung/subscriptions","organizations_url":"https://api.github.com/users/gfyoung/orgs","repos_url":"https://api.github.com/users/gfyoung/repos","events_url":"https://api.github.com/users/gfyoung/events{/privacy}","received_events_url":"https://api.github.com/users/gfyoung/received_events","type":"User","site_admin":false},"created_at":"2016-02-12T04:49:34Z","updated_at":"2016-02-12T04:49:34Z","body":"A little too late.  I just got it too work :)"}}