@@ -668,7 +668,7 @@ def __rdiv__(self, other):
668668 raise NotImplementedError (
669669 "StateSpace.__rdiv__ is not implemented yet." )
670670
671- def __call__ (self , x , squeeze = None ):
671+ def __call__ (self , x , squeeze = None , warn_infinite = True ):
672672 """Evaluate system's transfer function at complex frequency.
673673
674674 Returns the complex frequency response `sys(x)` where `x` is `s` for
@@ -689,6 +689,8 @@ def __call__(self, x, squeeze=None):
689689 keep all indices (output, input and, if omega is array_like,
690690 frequency) even if the system is SISO. The default value can be
691691 set using config.defaults['control.squeeze_frequency_response'].
692+ warn_infinite : bool, optional
693+ If set to `False`, don't warn if frequency response is infinite.
692694
693695 Returns
694696 -------
@@ -702,7 +704,7 @@ def __call__(self, x, squeeze=None):
702704
703705 """
704706 # Use Slycot if available
705- out = self .horner (x )
707+ out = self .horner (x , warn_infinite = warn_infinite )
706708 return _process_frequency_response (self , x , out , squeeze = squeeze )
707709
708710 def slycot_laub (self , x ):
@@ -758,7 +760,7 @@ def slycot_laub(self, x):
758760 out [:, :, kk + 1 ] = result [0 ] + self .D
759761 return out
760762
761- def horner (self , x ):
763+ def horner (self , x , warn_infinite = True ):
762764 """Evaluate system's transfer function at complex frequency
763765 using Laub's or Horner's method.
764766
@@ -795,14 +797,22 @@ def horner(self, x):
795797 raise ValueError ("input list must be 1D" )
796798
797799 # Preallocate
798- out = empty ((self .noutputs , self .ninputs , len (x_arr )), dtype = complex )
800+ out = empty ((self .noutputs , self .ninputs , len (x_arr )),
801+ dtype = complex )
799802
800803 #TODO: can this be vectorized?
801804 for idx , x_idx in enumerate (x_arr ):
802- out [:,:,idx ] = \
803- np .dot (self .C ,
805+ try :
806+ out [:,:,idx ] = np .dot (
807+ self .C ,
804808 solve (x_idx * eye (self .nstates ) - self .A , self .B )) \
805- + self .D
809+ + self .D
810+ except LinAlgError :
811+ if warn_infinite :
812+ warn ("frequency response is not finite" ,
813+ RuntimeWarning )
814+ # TODO: check for nan cases
815+ out [:,:,idx ] = np .inf
806816 return out
807817
808818 def freqresp (self , omega ):
@@ -1200,7 +1210,7 @@ def dcgain(self):
12001210 gain : ndarray
12011211 An array of shape (outputs,inputs); the array will either
12021212 be the zero-frequency (or DC) gain, or, if the frequency
1203- response is singular, the array will be filled with np.nan .
1213+ response is singular, the array will be filled with np.inf .
12041214 """
12051215 try :
12061216 if self .isctime ():
@@ -1210,7 +1220,7 @@ def dcgain(self):
12101220 gain = np .squeeze (self .horner (1 ))
12111221 except LinAlgError :
12121222 # eigenvalue at DC
1213- gain = np .tile (np .nan , (self .noutputs , self .ninputs ))
1223+ gain = np .tile (np .inf , (self .noutputs , self .ninputs ))
12141224 return np .squeeze (gain )
12151225
12161226 def _isstatic (self ):
0 commit comments