4949"""
5050
5151# External function declarations
52+ import numpy as np
5253from numpy import angle , array , empty , ones , \
5354 real , imag , matrix , absolute , eye , linalg , where , dot
5455from scipy .interpolate import splprep , splev
5758__all__ = ['FRD' , 'frd' ]
5859
5960class FRD (LTI ):
60- """A class for models defined by Frequency Response Data (FRD)
61+ """FRD(d, w)
62+
63+ A class for models defined by frequency response data (FRD)
6164
6265 The FRD class is used to represent systems in frequency response data form.
6366
@@ -80,7 +83,9 @@ class FRD(LTI):
8083 epsw = 1e-8
8184
8285 def __init__ (self , * args , ** kwargs ):
83- """Construct an FRD object
86+ """FRD(d, w)
87+
88+ Construct an FRD object
8489
8590 The default constructor is FRD(d, w), where w is an iterable of
8691 frequency points, and d is the matching frequency data.
@@ -111,7 +116,7 @@ def __init__(self, *args, **kwargs):
111116 (otherlti .outputs , otherlti .inputs , numfreq ),
112117 dtype = complex )
113118 for k , w in enumerate (self .omega ):
114- self .fresp [:, :, k ] = otherlti .evalfr (w )
119+ self .fresp [:, :, k ] = otherlti ._evalfr (w )
115120
116121 else :
117122 # The user provided a response and a freq vector
@@ -219,7 +224,7 @@ def __mul__(self, other):
219224 """Multiply two LTI objects (serial connection)."""
220225
221226 # Convert the second argument to a transfer function.
222- if isinstance (other , (int , float , complex )):
227+ if isinstance (other , (int , float , complex , np . number )):
223228 return FRD (self .fresp * other , self .omega ,
224229 smooth = (self .ifunc is not None ))
225230 else :
@@ -245,7 +250,7 @@ def __rmul__(self, other):
245250 """Right Multiply two LTI objects (serial connection)."""
246251
247252 # Convert the second argument to an frd function.
248- if isinstance (other , (int , float , complex )):
253+ if isinstance (other , (int , float , complex , np . number )):
249254 return FRD (self .fresp * other , self .omega ,
250255 smooth = (self .ifunc is not None ))
251256 else :
@@ -272,7 +277,7 @@ def __rmul__(self, other):
272277 def __truediv__ (self , other ):
273278 """Divide two LTI objects."""
274279
275- if isinstance (other , (int , float , complex )):
280+ if isinstance (other , (int , float , complex , np . number )):
276281 return FRD (self .fresp * (1 / other ), self .omega ,
277282 smooth = (self .ifunc is not None ))
278283 else :
@@ -295,7 +300,7 @@ def __div__(self, other):
295300 # TODO: Division of MIMO transfer function objects is not written yet.
296301 def __rtruediv__ (self , other ):
297302 """Right divide two LTI objects."""
298- if isinstance (other , (int , float , complex )):
303+ if isinstance (other , (int , float , complex , np . number )):
299304 return FRD (other / self .fresp , self .omega ,
300305 smooth = (self .ifunc is not None ))
301306 else :
@@ -324,19 +329,42 @@ def __pow__(self,other):
324329 return (FRD (ones (self .fresp .shape ), self .omega ) / self ) * \
325330 (self ** (other + 1 ))
326331
327-
328332 def evalfr (self , omega ):
329333 """Evaluate a transfer function at a single angular frequency.
330334
331- self.evalfr(omega) returns the value of the frequency response
335+ self._evalfr(omega) returns the value of the frequency response
336+ at frequency omega.
337+
338+ Note that a "normal" FRD only returns values for which there is an
339+ entry in the omega vector. An interpolating FRD can return
340+ intermediate values.
341+
342+ """
343+ warn ("FRD.evalfr(omega) will be deprecated in a future release of python-control; use sys.eval(omega) instead" ,
344+ PendingDeprecationWarning )
345+ return self ._evalfr (omega )
346+
347+ # Define the `eval` function to evaluate an FRD at a given (real)
348+ # frequency. Note that we choose to use `eval` instead of `evalfr` to
349+ # avoid confusion with :func:`evalfr`, which takes a complex number as its
350+ # argument. Similarly, we don't use `__call__` to avoid confusion between
351+ # G(s) for a transfer function and G(omega) for an FRD object.
352+ def eval (self , omega ):
353+ """Evaluate a transfer function at a single angular frequency.
354+
355+ self._evalfr(omega) returns the value of the frequency response
332356 at frequency omega.
333357
334358 Note that a "normal" FRD only returns values for which there is an
335359 entry in the omega vector. An interpolating FRD can return
336360 intermediate values.
337361
338362 """
363+ return self ._evalfr (omega )
339364
365+ # Internal function to evaluate the frequency responses
366+ def _evalfr (self , omega ):
367+ """Evaluate a transfer function at a single angular frequency."""
340368 # Preallocate the output.
341369 if getattr (omega , '__iter__' , False ):
342370 out = empty ((self .outputs , self .inputs , len (omega )), dtype = complex )
@@ -385,7 +413,7 @@ def freqresp(self, omega):
385413 omega .sort ()
386414
387415 for k , w in enumerate (omega ):
388- fresp = self .evalfr (w )
416+ fresp = self ._evalfr (w )
389417 mag [:, :, k ] = abs (fresp )
390418 phase [:, :, k ] = angle (fresp )
391419
@@ -445,11 +473,11 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1):
445473 omega .sort ()
446474 fresp = empty ((sys .outputs , sys .inputs , len (omega )), dtype = complex )
447475 for k , w in enumerate (omega ):
448- fresp [:, :, k ] = sys .evalfr (w )
476+ fresp [:, :, k ] = sys ._evalfr (w )
449477
450478 return FRD (fresp , omega , smooth = True )
451479
452- elif isinstance (sys , (int , float , complex )):
480+ elif isinstance (sys , (int , float , complex , np . number )):
453481 fresp = ones ((outputs , inputs , len (omega )), dtype = float )* sys
454482 return FRD (fresp , omega , smooth = True )
455483
@@ -469,8 +497,9 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1):
469497 sys .__class__ )
470498
471499def frd (* args ):
472- """
473- Construct a Frequency Response Data model, or convert a system
500+ """frd(d, w)
501+
502+ Construct a frequency response data model
474503
475504 frd models store the (measured) frequency response of a system.
476505
@@ -500,6 +529,6 @@ def frd(*args):
500529
501530 See Also
502531 --------
503- ss, tf
532+ FRD, ss, tf
504533 """
505534 return FRD (* args )
0 commit comments