6060from scipy .signal import StateSpace as signalStateSpace
6161from warnings import warn
6262
63- from .exception import ControlSlycot
63+ from .exception import ControlSlycot , slycot_check
6464from .frdata import FrequencyResponseData
6565from .lti import LTI , _process_frequency_response
6666from .iosys import InputOutputSystem , common_timebase , isdtime , \
@@ -1615,10 +1615,13 @@ def ss(*args, **kwargs):
16151615 warn ("state labels specified for "
16161616 "non-unique state space realization" )
16171617
1618+ # Allow method to be specified (eg, tf2ss)
1619+ method = kwargs .pop ('method' , None )
1620+
16181621 # Create a state space system from an LTI system
16191622 sys = StateSpace (
16201623 _convert_to_statespace (
1621- sys ,
1624+ sys , method = method ,
16221625 use_prefix_suffix = not sys ._generic_name_check ()),
16231626 ** kwargs )
16241627
@@ -2189,7 +2192,7 @@ def _f2s(f):
21892192 return s
21902193
21912194
2192- def _convert_to_statespace (sys , use_prefix_suffix = False ):
2195+ def _convert_to_statespace (sys , use_prefix_suffix = False , method = None ):
21932196 """Convert a system to state space form (if needed).
21942197
21952198 If sys is already a state space, then it is returned. If sys is a
@@ -2213,13 +2216,17 @@ def _convert_to_statespace(sys, use_prefix_suffix=False):
22132216 raise ValueError ("transfer function is non-proper; can't "
22142217 "convert to StateSpace system" )
22152218
2216- try :
2219+ if method is None and slycot_check () or method == 'slycot' :
2220+ if not slycot_check ():
2221+ raise ValueError ("method='slycot' requires slycot" )
2222+
22172223 from slycot import td04ad
22182224
22192225 # Change the numerator and denominator arrays so that the transfer
22202226 # function matrix has a common denominator.
22212227 # matrices are also sized/padded to fit td04ad
22222228 num , den , denorder = sys .minreal ()._common_den ()
2229+ num , den , denorder = sys ._common_den ()
22232230
22242231 # transfer function to state space conversion now should work!
22252232 ssout = td04ad ('C' , sys .ninputs , sys .noutputs ,
@@ -2230,9 +2237,8 @@ def _convert_to_statespace(sys, use_prefix_suffix=False):
22302237 ssout [1 ][:states , :states ], ssout [2 ][:states , :sys .ninputs ],
22312238 ssout [3 ][:sys .noutputs , :states ], ssout [4 ], sys .dt )
22322239
2233- except ImportError :
2234- # No Slycot. Scipy tf->ss can't handle MIMO, but static
2235- # MIMO is an easy special case we can check for here
2240+ elif method in [None , 'scipy' ]:
2241+ # Scipy tf->ss can't handle MIMO, but SISO is OK
22362242 maxn = max (max (len (n ) for n in nrow )
22372243 for nrow in sys .num )
22382244 maxd = max (max (len (d ) for d in drow )
@@ -2250,6 +2256,8 @@ def _convert_to_statespace(sys, use_prefix_suffix=False):
22502256 A , B , C , D = \
22512257 sp .signal .tf2ss (squeeze (sys .num ), squeeze (sys .den ))
22522258 newsys = StateSpace (A , B , C , D , sys .dt )
2259+ else :
2260+ raise ValueError (f"unknown { method = } " )
22532261
22542262 # Copy over the signal (and system) names
22552263 newsys ._copy_names (
0 commit comments