1010
1111# Python 3 compatibility (needs to go here)
1212from __future__ import print_function
13+ from __future__ import division # for _convertToStateSpace
1314
1415"""Copyright (c) 2010 by California Institute of Technology
1516All rights reserved.
@@ -638,6 +639,7 @@ def _convertToStateSpace(sys, **kw):
638639 """
639640
640641 from .xferfcn import TransferFunction
642+ import itertools
641643 if isinstance (sys , StateSpace ):
642644 if len (kw ):
643645 raise TypeError ("If sys is a StateSpace, _convertToStateSpace \
@@ -657,18 +659,45 @@ def _convertToStateSpace(sys, **kw):
657659 num , den = sys ._common_den ()
658660 # Make a list of the orders of the denominator polynomials.
659661 index = [len (den ) - 1 for i in range (sys .outputs )]
660- # Repeat the common denominator along the rows.
661- den = array ([den for i in range (sys .outputs )])
662- #! TODO: transfer function to state space conversion is still buggy!
663- #print num
664- #print shape(num)
665- ssout = td04ad ('R' ,sys .inputs , sys .outputs , index , den , num ,tol = 0.0 )
666-
667- states = ssout [0 ]
668- return StateSpace (ssout [1 ][:states , :states ],
669- ssout [2 ][:states , :sys .inputs ],
670- ssout [3 ][:sys .outputs , :states ],
671- ssout [4 ], sys .dt )
662+
663+ if index .count (0 ):
664+ # all TFM entries are static gains
665+ # if any entry in index is 0, td0ad raises:
666+ # ValueError: failed to create
667+ # intent(cache|hide)|optional array-- must have
668+ # defined dimensions but got (*,0,)
669+ # (where "*" varies according to the system size). This
670+ # suggests it's a problem in Slycot rather than
671+ # SLICOT.
672+ # Regardless, as of 2017-01-01 (commit 32f13bc), all
673+ # entries of index have the same value. The check
674+ # immediately below is in case this ever changes,
675+ # e.g., common denominator found per row or per column
676+ # (which seems like the right thing to do). If such a
677+ # change *IS* made, then we might have a row (or
678+ # column) of static gains, and either some SS assembly
679+ # gymnastics will be required here, or td0ad must be
680+ # fixed.
681+ if index .count (0 ) != len (index ):
682+ raise RuntimeError ("require all or no index entries to be 0" )
683+
684+ D = empty ((sys .outputs ,sys .inputs ),dtype = float )
685+ for i ,j in itertools .product (range (sys .outputs ),range (sys .inputs )):
686+ D [i ,j ] = sys .num [i ][j ][0 ] / sys .den [i ][j ][0 ]
687+ return StateSpace ([], [], [], D , sys .dt )
688+ else :
689+ # Repeat the common denominator along the rows.
690+ den = array ([den for i in range (sys .outputs )])
691+ #! TODO: transfer function to state space conversion is still buggy!
692+ #print num
693+ #print shape(num)
694+ ssout = td04ad ('R' ,sys .inputs , sys .outputs , index , den , num ,tol = 0.0 )
695+
696+ states = ssout [0 ]
697+ return StateSpace (ssout [1 ][:states , :states ],
698+ ssout [2 ][:states , :sys .inputs ],
699+ ssout [3 ][:sys .outputs , :states ],
700+ ssout [4 ], sys .dt )
672701 except ImportError :
673702 # If slycot is not available, use signal.lti (SISO only)
674703 if (sys .inputs != 1 or sys .outputs != 1 ):
0 commit comments