Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
replace np.pi with math.pi (avoids Mock() issues) + docstring update …
…in margin
  • Loading branch information
murrayrm committed Dec 30, 2017
commit aa6e0dfc05fde5e70d48f1add3f89e01adb1e8d5
9 changes: 2 additions & 7 deletions control/ctrlutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,12 @@
# Packages that we need access to
from . import lti
import numpy as np
from numpy import pi

# Hack for sphinx.ext.autodoc: if numpy is a mock import, then numpy.pi
# will be assigned to _Mock() and this generates a type error
if not isinstance(pi, float):
pi = 3.14
import math

__all__ = ['unwrap', 'issys', 'db2mag', 'mag2db']

# Utility function to unwrap an angle measurement
def unwrap(angle, period=2*pi):
def unwrap(angle, period=2*math.pi):
"""Unwrap a phase angle to give a continuous curve

Parameters
Expand Down
23 changes: 12 additions & 11 deletions control/freqplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import matplotlib.pyplot as plt
import scipy as sp
import numpy as np
import math
from .ctrlutil import unwrap
from .bdalg import feedback

Expand Down Expand Up @@ -128,7 +129,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
else:
omega_limits = np.array(omega_limits)
if Hz:
omega_limits *= 2.*np.pi
omega_limits *= 2.*math.pi
if omega_num:
omega = sp.logspace(np.log10(omega_limits[0]), np.log10(omega_limits[1]), num=omega_num, endpoint=True)
else:
Expand All @@ -142,7 +143,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
else:
omega_sys = np.array(omega)
if sys.isdtime(True):
nyquistfrq = 2. * np.pi * 1. / sys.dt / 2.
nyquistfrq = 2. * math.pi * 1. / sys.dt / 2.
omega_sys = omega_sys[omega_sys < nyquistfrq]
# TODO: What distance to the Nyquist frequency is appropriate?
else:
Expand All @@ -154,9 +155,9 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
phase = unwrap(phase)
nyquistfrq_plot = None
if Hz:
omega_plot = omega_sys / (2. * np.pi)
omega_plot = omega_sys / (2. * math.pi)
if nyquistfrq:
nyquistfrq_plot = nyquistfrq / (2. * np.pi)
nyquistfrq_plot = nyquistfrq / (2. * math.pi)
else:
omega_plot = omega_sys
if nyquistfrq:
Expand Down Expand Up @@ -187,7 +188,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
# Phase plot
ax_phase = plt.subplot(212, sharex=ax_mag);
if deg:
phase_plot = phase * 180. / np.pi
phase_plot = phase * 180. / math.pi
else:
phase_plot = phase
ax_phase.semilogx(omega_plot, phase_plot, *args, **kwargs)
Expand All @@ -208,8 +209,8 @@ def genZeroCenteredSeries(val_min, val_max, period):
ax_phase.set_yticks(genZeroCenteredSeries(ylim[0], ylim[1], 15.), minor=True)
else:
ylim = ax_phase.get_ylim()
ax_phase.set_yticks(genZeroCenteredSeries(ylim[0], ylim[1], np.pi / 4.))
ax_phase.set_yticks(genZeroCenteredSeries(ylim[0], ylim[1], np.pi / 12.), minor=True)
ax_phase.set_yticks(genZeroCenteredSeries(ylim[0], ylim[1], math.pi / 4.))
ax_phase.set_yticks(genZeroCenteredSeries(ylim[0], ylim[1], math.pi / 12.), minor=True)
ax_phase.grid(True, which='both')
# ax_mag.grid(which='minor', alpha=0.3)
# ax_mag.grid(which='major', alpha=0.9)
Expand Down Expand Up @@ -449,7 +450,7 @@ def default_frequency_range(syslist, Hz=None, number_of_samples=None, feature_pe
features_ = features_[features_ != 0.0];
features = np.concatenate((features, features_))
elif sys.isdtime(strict=True):
fn = np.pi * 1. / sys.dt
fn = math.pi * 1. / sys.dt
# TODO: What distance to the Nyquist frequency is appropriate?
freq_interesting.append(fn * 0.9)

Expand All @@ -475,12 +476,12 @@ def default_frequency_range(syslist, Hz=None, number_of_samples=None, feature_pe
features = np.array([1.]);

if Hz:
features /= 2.*np.pi
features /= 2.*math.pi
features = np.log10(features)
lsp_min = np.floor(np.min(features) - feature_periphery_decade)
lsp_max = np.ceil(np.max(features) + feature_periphery_decade)
lsp_min += np.log10(2.*np.pi)
lsp_max += np.log10(2.*np.pi)
lsp_min += np.log10(2.*math.pi)
lsp_max += np.log10(2.*math.pi)
else:
features = np.log10(features)
lsp_min = np.floor(np.min(features) - feature_periphery_decade)
Expand Down
9 changes: 5 additions & 4 deletions control/margins.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@
$Id$
"""

import math
import numpy as np
import scipy as sp
from . import xferfcn
from .lti import issiso
from . import frdata
import scipy as sp

__all__ = ['stability_margins', 'phase_crossover_frequencies', 'margin']

Expand Down Expand Up @@ -140,7 +141,7 @@ def stability_margins(sysdata, returnall=False, epsw=0.0):
sys = sysdata
elif getattr(sysdata, '__iter__', False) and len(sysdata) == 3:
mag, phase, omega = sysdata
sys = frdata.FRD(mag * np.exp(1j * phase * np.pi/180),
sys = frdata.FRD(mag * np.exp(1j * phase * math.pi/180),
omega, smooth=True)
else:
sys = xferfcn._convertToTransferFunction(sysdata)
Expand Down Expand Up @@ -336,13 +337,13 @@ def phase_crossover_frequencies(sys):


def margin(*args):
"""margin(sys)
"""margin(sysdata)

Calculate gain and phase margins and associated crossover frequencies

Parameters
----------
sysdata: LTI system or (mag, phase, omega) sequence
sysdata : LTI system or (mag, phase, omega) sequence
sys : StateSpace or TransferFunction
Linear SISO system
mag, phase, omega : sequence of array_like
Expand Down
7 changes: 4 additions & 3 deletions control/statesp.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@
$Id$
"""

import math
import numpy as np
from numpy import all, angle, any, array, asarray, concatenate, cos, delete, \
dot, empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, \
dot, empty, exp, eye, matrix, ones, poly, poly1d, roots, shape, sin, \
zeros, squeeze
from numpy.random import rand, randn
from numpy.linalg import solve, eigvals, matrix_rank
Expand Down Expand Up @@ -367,7 +368,7 @@ def evalfr(self, omega):
if isdtime(self, strict=True):
dt = timebase(self)
s = exp(1.j * omega * dt)
if (omega * dt > pi):
if (omega * dt > math.pi):
warnings.warn("evalfr: frequency evaluation above Nyquist frequency")
else:
s = omega * 1.j
Expand Down Expand Up @@ -798,7 +799,7 @@ def _rss_generate(states, inputs, outputs, type):
poles[i] = complex(-exp(randn()), 3. * exp(randn()))
elif type == 'd':
mag = rand()
phase = 2. * pi * rand()
phase = 2. * math.pi * rand()
poles[i] = complex(mag * cos(phase),
mag * sin(phase))
poles[i+1] = complex(poles[i].real, -poles[i].imag)
Expand Down