def plot_stability_region(self,N=100,N2=1000,color='r',filled=True, alpha=1.): r""" The region of absolute stability of a linear multistep method is the set `\{ z \in C : \rho(\zeta) - z \sigma(zeta) \text{ satisfies the root condition} \}` where `\rho(zeta)` and `\sigma(zeta)` are the characteristic functions of the method. Also plots the boundary locus, which is given by the set of points z: `\{z | z=\rho(\exp(i\theta))/\sigma(\exp(i\theta)), 0\le \theta \le 2*\pi \}` Here `\rho` and `\sigma` are the characteristic polynomials of the method. References: [leveque2007]_ section 7.6.1 **Input**: (all optional) - N -- Number of gridpoints to use in each direction - bounds -- limits of plotting region - color -- color to use for this plot - filled -- if true, stability region is filled in (solid); otherwise it is outlined """ import matplotlib.pyplot as plt from utils import find_plot_bounds numself = self.__num__() rho, sigma = self.__num__().characteristic_polynomials() mag = lambda z : _root_condition(rho-z*sigma) vmag = np.vectorize(mag) bounds = find_plot_bounds(vmag,guess=(-10,1,-5,5),N=101) y=np.linspace(bounds[2],bounds[3],N) Y=np.tile(y[:,np.newaxis],(1,N)) x=np.linspace(bounds[0],bounds[1],N) X=np.tile(x,(N,1)) Z=X+Y*1j R=1.5-vmag(Z) z = self._boundary_locus() if filled: plt.contourf(X,Y,R,[0,1],colors=color,alpha=alpha) else: plt.contour(X,Y,R,[0,1],colors=color,alpha=alpha) plt.title('Absolute Stability Region for '+self.name) plt.hold(True) plt.plot([0,0],[bounds[2],bounds[3]],'--k',linewidth=2) plt.plot([bounds[0],bounds[1]],[0,0],'--k',linewidth=2) plt.plot(np.real(z),np.imag(z),color='k',linewidth=3) plt.axis(bounds) plt.hold(False) plt.draw()
def plot_stability_region(self,N=50,bounds=None, color='r',filled=True,scaled=False): r""" Plot the region of absolute stability of a Two-step Runge-Kutta method, i.e. the set `\{ z \in C : M(z) is power bounded \}` where $M(z)$ is the stability matrix of the method. **Input**: (all optional) - N -- Number of gridpoints to use in each direction - bounds -- limits of plotting region - color -- color to use for this plot - filled -- if true, stability region is filled in (solid); otherwise it is outlined """ method = self.__num__() # Use floating-point coefficients for efficiency import matplotlib.pyplot as plt if bounds is None: from utils import find_plot_bounds stable = lambda z : max(abs(np.linalg.eigvals(method.stability_matrix(z))))<=1.0 bounds = find_plot_bounds(np.vectorize(stable),guess=(-10,1,-5,5)) if np.min(np.abs(np.array(bounds)))<1.e-14: print 'No stable region found; is this method zero-stable?' x=np.linspace(bounds[0],bounds[1],N) y=np.linspace(bounds[2],bounds[3],N) X=np.tile(x,(N,1)) Y=np.tile(y[:,np.newaxis],(1,N)) Z=X+Y*1j maxroot = lambda z : max(abs(np.linalg.eigvals(method.stability_matrix(z)))) Mroot = np.vectorize(maxroot) R = Mroot(Z) if filled: plt.contourf(X,Y,R,[0,1],colors=color) else: plt.contour(X,Y,R,[0,1],colors=color) plt.title('Absolute Stability Region for '+self.name) plt.hold(True) plt.plot([0,0],[bounds[2],bounds[3]],'--k',linewidth=2) plt.plot([bounds[0],bounds[1]],[0,0],'--k',linewidth=2) plt.axis('Image') plt.hold(False)
def plot_stability_region(p,q,N=200,color='r',filled=True,bounds=None, plotroots=False,alpha=1.,scalefac=1.,fignum=None): r""" Plot the region of absolute stability of a rational function; i.e. the set `\{ z \in C : |\phi (z)|\le 1 \}` Unless specified explicitly, the plot bounds are determined automatically, attempting to include the entire region. A check is performed beforehand for methods with unbounded stability regions. Note that this function is not responsible for actually drawing the figure to the screen (or saving it to file). **Inputs**: - p, q -- Numerator and denominator of the stability function - N -- Number of gridpoints to use in each direction - color -- color to use for this plot - filled -- if true, stability region is filled in (solid); otherwise it is outlined - plotroots -- if True, plot the roots and poles of the function - alpha -- transparency of contour plot - scalefac -- factor by which to scale region (often used to normalize for stage number) - fignum -- number of existing figure to use for plot """ import matplotlib.pyplot as plt # Convert coefficients to floats for speed if p.coeffs.dtype=='object': p = np.poly1d([float(c) for c in p.coeffs]) if q.coeffs.dtype=='object': q = np.poly1d([float(c) for c in q.coeffs]) if bounds is None: from utils import find_plot_bounds # Check if the stability region is bounded or not m,n = p.order,q.order if (m < n) or ((m == n) and (abs(p[m])<abs(q[n]))): print 'The stability region is unbounded' bounds = (-10*m,m,-5*m,5*m) else: stable = lambda z : np.abs(p(z)/q(z))<=1.0 bounds = find_plot_bounds(stable,guess=(-10,1,-5,5)) if np.min(np.abs(np.array(bounds)))<1.e-14: print 'No stable region found; is this method zero-stable?' if (m == n) and (abs(p[m])==abs(q[n])): print 'The stability region may be unbounded' # Evaluate the stability function over a grid x=np.linspace(bounds[0],bounds[1],N) y=np.linspace(bounds[2],bounds[3],N) X=np.tile(x,(N,1)) Y=np.tile(y[:,np.newaxis],(1,N)) Z=X+Y*1j R=np.abs(p(Z*scalefac)/q(Z*scalefac)) # Plot h = plt.figure(fignum) plt.hold(True) if filled: plt.contourf(X,Y,R,[0,1],colors=color,alpha=alpha) else: plt.contour(X,Y,R,[0,1],colors=color,alpha=alpha,linewidths=3) if plotroots: plt.plot(np.real(p.r),np.imag(p.r),'ok') if len(q)>1: plt.plot(np.real(q.r),np.imag(q.r),'xk') plt.plot([0,0],[bounds[2],bounds[3]],'--k',linewidth=2) plt.plot([bounds[0],bounds[1]],[0,0],'--k',linewidth=2) plt.axis('Image') plt.hold(False) return h
def plot_stability_region(p, q, N=200, color='r', filled=True, bounds=None, plotroots=False, alpha=1., scalefac=1., fignum=None): r""" Plot the region of absolute stability of a rational function; i.e. the set `\{ z \in C : |\phi (z)|\le 1 \}` Unless specified explicitly, the plot bounds are determined automatically, attempting to include the entire region. A check is performed beforehand for methods with unbounded stability regions. Note that this function is not responsible for actually drawing the figure to the screen (or saving it to file). **Inputs**: - p, q -- Numerator and denominator of the stability function - N -- Number of gridpoints to use in each direction - color -- color to use for this plot - filled -- if true, stability region is filled in (solid); otherwise it is outlined - plotroots -- if True, plot the roots and poles of the function - alpha -- transparency of contour plot - scalefac -- factor by which to scale region (often used to normalize for stage number) - fignum -- number of existing figure to use for plot """ import matplotlib.pyplot as plt # Convert coefficients to floats for speed if p.coeffs.dtype == 'object': p = np.poly1d([float(c) for c in p.coeffs]) if q.coeffs.dtype == 'object': q = np.poly1d([float(c) for c in q.coeffs]) if bounds is None: from utils import find_plot_bounds # Check if the stability region is bounded or not m, n = p.order, q.order if (m < n) or ((m == n) and (abs(p[m]) < abs(q[n]))): print 'The stability region is unbounded' bounds = (-10 * m, m, -5 * m, 5 * m) else: stable = lambda z: np.abs(p(z) / q(z)) <= 1.0 bounds = find_plot_bounds(stable, guess=(-10, 1, -5, 5)) if np.min(np.abs(np.array(bounds))) < 1.e-14: print 'No stable region found; is this method zero-stable?' if (m == n) and (abs(p[m]) == abs(q[n])): print 'The stability region may be unbounded' # Evaluate the stability function over a grid x = np.linspace(bounds[0], bounds[1], N) y = np.linspace(bounds[2], bounds[3], N) X = np.tile(x, (N, 1)) Y = np.tile(y[:, np.newaxis], (1, N)) Z = X + Y * 1j R = np.abs(p(Z * scalefac) / q(Z * scalefac)) # Plot h = plt.figure(fignum) plt.hold(True) if filled: plt.contourf(X, Y, R, [0, 1], colors=color, alpha=alpha) else: plt.contour(X, Y, R, [0, 1], colors=color, alpha=alpha, linewidths=3) if plotroots: plt.plot(np.real(p.r), np.imag(p.r), 'ok') if len(q) > 1: plt.plot(np.real(q.r), np.imag(q.r), 'xk') plt.plot([0, 0], [bounds[2], bounds[3]], '--k', linewidth=2) plt.plot([bounds[0], bounds[1]], [0, 0], '--k', linewidth=2) plt.axis('Image') plt.hold(False) return h