@@ -523,6 +523,7 @@ def gen_zero_centered_series(val_min, val_max, period):
523
523
'nyquist.mirror_style' : ['--' , ':' ], # style for mirror curve
524
524
'nyquist.arrows' : 2 , # number of arrors around curve
525
525
'nyquist.arrow_size' : 8 , # pixel size for arrows
526
+ 'nyquist.encirclement_threshold' : 0.05 , # warning threshold
526
527
'nyquist.indent_radius' : 1e-4 , # indentation radius
527
528
'nyquist.indent_direction' : 'right' , # indentation direction
528
529
'nyquist.indent_points' : 50 , # number of points to insert
@@ -611,6 +612,11 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
611
612
arrow_style : matplotlib.patches.ArrowStyle, optional
612
613
Define style used for Nyquist curve arrows (overrides `arrow_size`).
613
614
615
+ encirclement_threshold : float, optional
616
+ Define the threshold for generating a warning if the number of net
617
+ encirclements is a non-integer value. Default value is 0.05 and can
618
+ be set using config.defaults['nyquist.encirclement_threshold'].
619
+
614
620
indent_direction : str, optional
615
621
For poles on the imaginary axis, set the direction of indentation to
616
622
be 'right' (default), 'left', or 'none'.
@@ -717,6 +723,9 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
717
723
arrow_style = config ._get_param ('nyquist' , 'arrow_style' , kwargs , None )
718
724
indent_radius = config ._get_param (
719
725
'nyquist' , 'indent_radius' , kwargs , _nyquist_defaults , pop = True )
726
+ encirclement_threshold = config ._get_param (
727
+ 'nyquist' , 'encirclement_threshold' , kwargs ,
728
+ _nyquist_defaults , pop = True )
720
729
indent_direction = config ._get_param (
721
730
'nyquist' , 'indent_direction' , kwargs , _nyquist_defaults , pop = True )
722
731
indent_points = config ._get_param (
@@ -750,8 +759,11 @@ def _parse_linestyle(style_name, allow_false=False):
750
759
if not isinstance (syslist , (list , tuple )):
751
760
syslist = (syslist ,)
752
761
762
+ # Determine the range of frequencies to use, based on args/features
753
763
omega , omega_range_given = _determine_omega_vector (
754
764
syslist , omega , omega_limits , omega_num )
765
+
766
+ # If omega was not specified explicitly, start at omega = 0
755
767
if not omega_range_given :
756
768
if omega_num_given :
757
769
# Just reset the starting point
@@ -852,6 +864,7 @@ def _parse_linestyle(style_name, allow_false=False):
852
864
first_point = 0
853
865
start_freq = 0
854
866
867
+ # Find the frequencies after the pole frequency
855
868
above_points = np .argwhere (
856
869
splane_contour .imag - abs (p .imag ) > indent_radius )
857
870
last_point = above_points [0 ].item ()
@@ -900,7 +913,15 @@ def _parse_linestyle(style_name, allow_false=False):
900
913
901
914
# Compute CW encirclements of -1 by integrating the (unwrapped) angle
902
915
phase = - unwrap (np .angle (resp + 1 ))
903
- count = int (np .round (np .sum (np .diff (phase )) / np .pi , 0 ))
916
+ encirclements = np .sum (np .diff (phase )) / np .pi
917
+ count = int (np .round (encirclements , 0 ))
918
+
919
+ # Let the user know if the count might not make sense
920
+ if abs (encirclements - count ) > encirclement_threshold :
921
+ warnings .warn (
922
+ "number of encirclements was a non-integer value; this can"
923
+ " happen is contour is not closed, possibly based on a"
924
+ " frequency range that does not include zero." )
904
925
905
926
#
906
927
# Make sure that the enciriclements match the Nyquist criterion
@@ -1534,6 +1555,7 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num,
1534
1555
num = omega_num , endpoint = True )
1535
1556
else :
1536
1557
omega_out = np .copy (omega_in )
1558
+
1537
1559
return omega_out , omega_range_given
1538
1560
1539
1561
0 commit comments