示例#1
1
def comparison_plot(f, u, Omega, filename='tmp.pdf',
                    plot_title='', ymin=None, ymax=None,
                    u_legend='approximation'):
    """Compare f(x) and u(x) for x in Omega in a plot."""
    x = sm.Symbol('x')
    print 'f:', f

    f = sm.lambdify([x], f, modules="numpy")
    u = sm.lambdify([x], u, modules="numpy")
    if len(Omega) != 2:
        raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega))
    # When doing symbolics, Omega can easily contain symbolic expressions,
    # assume .evalf() will work in that case to obtain numerical
    # expressions, which then must be converted to float before calling
    # linspace below
    if not isinstance(Omega[0], (int,float)):
        Omega[0] = float(Omega[0].evalf())
    if not isinstance(Omega[1], (int,float)):
        Omega[1] = float(Omega[1].evalf())

    resolution = 401  # no of points in plot
    xcoor = linspace(Omega[0], Omega[1], resolution)
    # Vectorized functions expressions does not work with
    # lambdify'ed functions without the modules="numpy"
    exact  = f(xcoor)
    approx = u(xcoor)
    plot(xcoor, approx, '-')
    hold('on')
    plot(xcoor, exact, '-')
    legend([u_legend, 'exact'])
    title(plot_title)
    xlabel('x')
    if ymin is not None and ymax is not None:
        axis([xcoor[0], xcoor[-1], ymin, ymax])
    savefig(filename)
示例#2
0
def run_solvers_and_check_amplitudes(solvers, timesteps_per_period=20,
                                     num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)

    file_name = 'Amplitudes'   # initialize filename for plot
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([0, I])
        u, t = solver.solve(t_mesh)

        solver_name = \
               'CrankNicolson' if solver.__class__.__name__ == \
               'MidpointImplicit' else solver.__class__.__name__
        file_name = file_name + '_' + solver_name

        minima, maxima = minmax(t, u[:,0])
        a = amplitudes(minima, maxima)
        plt.plot(range(len(a)), a, '-', label=solver_name)
        plt.hold('on')

    plt.xlabel('Number of periods')
    plt.ylabel('Amplitude (absolute value)')
    plt.legend(loc='upper left')
    plt.savefig(file_name + '.png')
    plt.savefig(file_name + '.pdf')
    plt.show()
示例#3
0
    def plot(self, include_exact=True, plt=None):
        """
        Add solver.u curve to the plotting object plt,
        and include the exact solution if include_exact is True.
        This plot function can be called several times (if
        the solver object has computed new solutions).
        """
        if plt is None:
            import scitools.std  as plt # can use matplotlib as well

        plt.plot(self.solver.t, self.solver.u, '--o')
        plt.hold('on')
        theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'}
        name = theta2name.get(self.solver.theta, '')
        legends = ['numerical %s' % name]
        if include_exact:
            t_e = linspace(0, self.problem.T, 1001)
            u_e = self.problem.exact_solution(t_e)
            plt.plot(t_e, u_e, 'b-')
            legends.append('exact')
        plt.legend(legends)
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('theta=%g, dt=%g' %
                  (self.solver.theta, self.solver.dt))
        plt.savefig('%s_%g.png' % (name, self.solver.dt))
        return plt
示例#4
0
def comparison_plot(u, Omega, u_e=None, filename='tmp.eps',
                    plot_title='', ymin=None, ymax=None):
    x = sp.Symbol('x')
    u = sp.lambdify([x], u, modules="numpy")
    if len(Omega) != 2:
        raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega))
    # When doing symbolics, Omega can easily contain symbolic expressions,
    # assume .evalf() will work in that case to obtain numerical
    # expressions, which then must be converted to float before calling
    # linspace below
    if not isinstance(Omega[0], (int,float)):
        Omega[0] = float(Omega[0].evalf())
    if not isinstance(Omega[1], (int,float)):
        Omega[1] = float(Omega[1].evalf())

    resolution = 401  # no of points in plot
    xcoor = linspace(Omega[0], Omega[1], resolution)
    # Vectorized functions expressions does not work with
    # lambdify'ed functions without the modules="numpy"
    approx = u(xcoor)
    plot(xcoor, approx)
    legends = ['approximation']
    if u_e is not None:
        exact  = u_e(xcoor)
        hold('on')
        plot(xcoor, exact)
        legends = ['exact']
    legend(legends)
    title(plot_title)
    xlabel('x')
    if ymin is not None and ymax is not None:
        axis([xcoor[0], xcoor[-1], ymin, ymax])
    savefig(filename)
示例#5
0
def non_physical_behavior(I, a, T, dt, theta):
    """
    Given lists/arrays a and dt, and numbers I, dt, and theta,
    make a two-dimensional contour line B=0.5, where B=1>0.5
    means oscillatory (unstable) solution, and B=0<0.5 means
    monotone solution of u'=-au.
    """
    a = np.asarray(a); dt = np.asarray(dt)  # must be arrays
    B = np.zeros((len(a), len(dt)))         # results
    for i in range(len(a)):
        for j in range(len(dt)):
            u, t = solver(I, a[i], T, dt[j], theta)
            # Does u have the right monotone decay properties?
            correct_qualitative_behavior = True
            for n in range(1, len(u)):
                if u[n] > u[n-1]:  # Not decaying?
                    correct_qualitative_behavior = False
                    break  # Jump out of loop
            B[i,j] = float(correct_qualitative_behavior)
    a_, dt_ = st.ndgrid(a, dt)  # make mesh of a and dt values
    st.contour(a_, dt_, B, 1)
    st.grid('on')
    st.title('theta=%g' % theta)
    st.xlabel('a'); st.ylabel('dt')
    st.savefig('osc_region_theta_%s.png' % theta)
    st.savefig('osc_region_theta_%s.pdf' % theta)
示例#6
0
def run_solvers_and_plot(solvers, rhs, T, dt, title=''):
    Nt = int(round(T / float(dt)))
    t_mesh = np.linspace(0, T, Nt + 1)
    t_fine = np.linspace(0, T, 8 * Nt + 1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(rhs)

    for solver in solvers:
        solver.set_initial_condition([rhs.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        if len(t_mesh) <= 50:
            plt.plot(t, u[:, 0])  # markers by default
        else:
            plt.plot(t, u[:, 0], '-2')  # no markers
        plt.hold('on')
        legends.append(solver_name)

    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([rhs.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    plt.plot(t_e, u_e[:, 0], '-')  # avoid markers by spec. line type
    legends.append('exact (RK4, dt=%g)' % (t_fine[1] - t_fine[0]))
    plt.legend(legends, loc='upper right')
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plotfilestem = '_'.join(legends)
    plt.savefig('tmp_%s.png' % plotfilestem)
    plt.savefig('tmp_%s.pdf' % plotfilestem)
示例#7
0
def run_solvers_and_check_amplitudes(solvers,
                                     timesteps_per_period=20,
                                     num_periods=1,
                                     I=1,
                                     w=2 * np.pi):
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)

    file_name = 'Amplitudes'  # initialize filename for plot
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([0, I])
        u, t = solver.solve(t_mesh)

        solver_name = \
               'CrankNicolson' if solver.__class__.__name__ == \
               'MidpointImplicit' else solver.__class__.__name__
        file_name = file_name + '_' + solver_name

        minima, maxima = minmax(t, u[:, 0])
        a = amplitudes(minima, maxima)
        plt.plot(range(len(a)), a, '-', label=solver_name)
        plt.hold('on')

    plt.xlabel('Number of periods')
    plt.ylabel('Amplitude (absolute value)')
    plt.legend(loc='upper left')
    plt.savefig(file_name + '.png')
    plt.savefig(file_name + '.pdf')
    plt.show()
示例#8
0
def non_physical_behavior(I, a, T, dt, theta):
    """
    Given lists/arrays a and dt, and numbers I, dt, and theta,
    make a two-dimensional contour line B=0.5, where B=1>0.5
    means oscillatory (unstable) solution, and B=0<0.5 means
    monotone solution of u'=-au.
    """
    a = np.asarray(a)
    dt = np.asarray(dt)  # must be arrays
    B = np.zeros((len(a), len(dt)))  # results
    for i in range(len(a)):
        for j in range(len(dt)):
            u, t = solver(I, a[i], T, dt[j], theta)
            # Does u have the right monotone decay properties?
            correct_qualitative_behavior = True
            for n in range(1, len(u)):
                if u[n] > u[n - 1]:  # Not decaying?
                    correct_qualitative_behavior = False
                    break  # Jump out of loop
            B[i, j] = float(correct_qualitative_behavior)
    a_, dt_ = st.ndgrid(a, dt)  # make mesh of a and dt values
    st.contour(a_, dt_, B, 1)
    st.grid('on')
    st.title('theta=%g' % theta)
    st.xlabel('a')
    st.ylabel('dt')
    st.savefig('osc_region_theta_%s.png' % theta)
    st.savefig('osc_region_theta_%s.eps' % theta)
示例#9
0
def run_solvers_and_plot(solvers, rhs, T, dt, title=''):
    Nt = int(round(T/float(dt)))
    t_mesh = np.linspace(0, T, Nt+1)
    t_fine = np.linspace(0, T, 8*Nt+1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(rhs)

    for solver in solvers:
        solver.set_initial_condition([rhs.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        if len(t_mesh) <= 50:
            plt.plot(t, u[:,0])             # markers by default
        else:
            plt.plot(t, u[:,0], '-2')       # no markers
        plt.hold('on')
        legends.append(solver_name)

    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([rhs.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    plt.plot(t_e, u_e[:,0], '-') # avoid markers by spec. line type
    legends.append('exact (RK4, dt=%g)' % (t_fine[1]-t_fine[0]))
    plt.legend(legends, loc='upper right')
    plt.xlabel('t');  plt.ylabel('u')
    plt.title(title)
    plotfilestem = '_'.join(legends)
    plt.savefig('tmp_%s.png' % plotfilestem)
    plt.savefig('tmp_%s.pdf' % plotfilestem)
示例#10
0
    def plot(self, include_exact=True, plt=None):
        """
        Add solver.u curve to scitools plotting object plt,
        and include the exact solution if include_exact is True.
        This plot function can be called several times (if
        the solver object has computed new solutions).
        """
        if plt is None:
            import scitools.std as plt

        plt.plot(self.solver.t, self.solver.u, '--o')
        plt.hold('on')
        theta = self.solver.get('theta')
        theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'}
        name = theta2name.get(theta, '')
        legends = ['numerical %s' % name]
        if include_exact:
            t_e = np.linspace(0, self.problem.get('T'), 1001)
            u_e = self.problem.exact_solution(t_e)
            plt.plot(t_e, u_e, 'b-')
            legends.append('exact')
        plt.legend(legends)
        plt.xlabel('t')
        plt.ylabel('u')
        dt = self.solver.get('dt')
        plt.title('theta=%g, dt=%g' % (theta, dt))
        plt.savefig('%s_%g.png' % (name, dt))
        return plt
示例#11
0
def visualize(u, t, title='', filename='tmp'):
    plt.plot(t, u, 'b-')
    plt.xlabel('t')
    plt.ylabel('u')
    dt = t[1] - t[0]
    plt.title('dt=%g' % dt)
    umin = 1.2*u.min(); umax = 1.2*u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
示例#12
0
	def plot(self, plt = None):
		if plt is None:
			import scitools.std as plt

		plt.plot(self.solver.t, self.solver.v, 'b--o')
		
		plt.hold("on")
		plt.xlabel("t")
		plt.ylabel("v")
		plt.savefig("%g.png" % (self.solver.dt))

		return plt
示例#13
0
def visualize(list_of_curves, legends, title='', filename='tmp'):
    """Plot list of curves: (u, t)."""
    for u, t in list_of_curves:
        plt.plot(t, u)
        plt.hold('on')
    plt.legend(legends)
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
示例#14
0
    def plot(self, plt=None):
        if plt is None:
            import scitools.std as plt

        plt.plot(self.solver.t, self.solver.v, 'b--o')

        plt.hold("on")
        plt.xlabel("t")
        plt.ylabel("v")
        plt.savefig("%g.png" % (self.solver.dt))

        return plt
示例#15
0
def visualize(u, t, title='', filename='tmp'):
    plt.plot(t, u, 'b-')
    plt.xlabel('t')
    plt.ylabel('u')
    dt = t[1] - t[0]
    plt.title('dt=%g' % dt)
    umin = 1.2*u.min(); umax = 1.2*u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
示例#16
0
def visualize(list_of_curves, legends, title='', filename='tmp'):
    """Plot list of curves: (u, t)."""
    for u, t in list_of_curves:
        plt.plot(t, u)
        plt.hold('on')
    plt.legend(legends)
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
示例#17
0
def visualize(u, t, title="", filename="tmp"):
    plt.plot(t, u, "b-")
    plt.xlabel("t")
    plt.ylabel("u")
    dt = t[1] - t[0]
    plt.title("dt=%g" % dt)
    umin = 1.2 * u.min()
    umax = 1.2 * u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + ".png")
    plt.savefig(filename + ".pdf")
    plt.show()
示例#18
0
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, b=0):
    w = 2 * np.pi  # frequency of undamped free oscillations
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)
    t_fine = np.linspace(0, T, 8 * Nt + 1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(f)

    for solver in solvers:
        solver.set_initial_condition([solver.users_f.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        # Make plots (plot last 10 periods????)
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver_name)

    # Compare with exact solution plotted on a very fine mesh
    #t_fine = np.linspace(0, T, 10001)
    #u_e = solver.users_f.exact(t_fine)
    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([solver.users_f.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_e, u_e[:, 0], '-')  # avoid markers by spec. line type
        legends.append('exact (RK4)')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, b=0):
    w = 2*np.pi    # frequency of undamped free oscillations
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)
    t_fine = np.linspace(0, T, 8*Nt+1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(f)

    for solver in solvers:
        solver.set_initial_condition([solver.users_f.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        # Make plots (plot last 10 periods????)
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver_name)

    # Compare with exact solution plotted on a very fine mesh
    #t_fine = np.linspace(0, T, 10001)
    #u_e = solver.users_f.exact(t_fine)
    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([solver.users_f.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_e, u_e[:,0], '-') # avoid markers by spec. line type
        legends.append('exact (RK4)')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))
def run_solver_and_plot(solver, timesteps_per_period=20,
                        num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)

    solver.set(f_kwargs={'w': w})
    solver.set_initial_condition([0, I])
    u, t = solver.solve(t_mesh)

    from vib_undamped import solver
    u2, t2 = solver(I, w, dt, T)

    plt.plot(t, u[:,1], 'r-', t2, u2, 'b-')
    plt.legend(['Euler-Cromer', '2nd-order ODE'])
    plt.xlabel('t');  plt.ylabel('u')
    plt.savefig('tmp1.png'); plt.savefig('tmp1.pdf')
示例#21
0
def logistic():
    problem = Logistic(0.2, 1, 0.1)
    T = 40
    dt = 0.1
    method = ForwardEuler(problem, dt)
    method.set_initial_condition(problem.u0, 0)
    u, t = method.solve(T)
    # note that import * is not legal inside functions so we
    # have to import each specific function:
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=0.2, dt=%g, %d steps' \
          % (dt, len(u)-1))
    # compare with exponential growth:
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
示例#22
0
def logistic():
    problem = Logistic(alpha=0.2, R=1, U0=0.1)
    T = 40
    solver = ForwardEuler(problem)
    solver.set_initial_condition(problem.U0)
    t = np.linspace(0, T, 401)  # 400 intervals in [0,T]
    u, t = solver.solve(t)
    # Note that import * is not legal inside functions so we
    # have to import each specific function.
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=%s, R=%g, dt=%g' \
          % (problem.alpha, problem.R, t[1]-t[0]))
    # Compare with exponential growth
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
示例#23
0
def logistic():
    problem = Logistic(alpha=0.2, R=1, U0=0.1)
    T = 40
    method = ForwardEuler(problem)
    method.set_initial_condition(problem.U0)
    t = np.linspace(0, T, 401)  # 400 intervals in [0,T]
    u, t = method.solve(t)
    # Note that import * is not legal inside functions so we
    # have to import each specific function.
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=%s, R=%g, dt=%g' \
          % (problem.alpha, problem.R, t[1]-t[0]))
    # Compare with exponential growth
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
示例#24
0
def run_solver_and_plot(solver,
                        timesteps_per_period=20,
                        num_periods=1,
                        I=1,
                        w=2 * np.pi):
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)

    solver.set(f_kwargs={'w': w})
    solver.set_initial_condition([0, I])
    u, t = solver.solve(t_mesh)

    from vib_undamped import solver
    u2, t2 = solver(I, w, dt, T)

    plt.plot(t, u[:, 1], 'r-', t2, u2, 'b-')
    plt.legend(['Euler-Cromer', '2nd-order ODE'])
    plt.xlabel('t')
    plt.ylabel('u')
    plt.savefig('tmp1.png')
    plt.savefig('tmp1.pdf')
示例#25
0
def viz(I, V, f, c, L, Nx, C, T,
        ymax,                      # y axis: [-ymax, ymax]
        u_exact,                   # u_exact(x, t)
        animate='u and u_exact',   # or 'error'
        movie_filename='movie',
        ):
    """Run solver and visualize u at each time level."""
    import scitools.std as plt
    import time, glob, os

    class Plot:
        def __init__(self, ymax, frame_name='frame'):
            self.max_error = []   # hold max amplitude errors
            self.max_error_t = [] # time points corresponding to max_error
            self.frame_name = frame_name
            self.ymax = ymax

        def __call__(self, u, x, t, n):
            """user_action function for solver."""
            if animate == 'u and u_exact':
                plt.plot(x, u, 'r-',
                         x, u_exact(x, t[n]), 'b--',
                         xlabel='x', ylabel='u',
                         axis=[0, L, -self.ymax, self.ymax],
                         title='t=%f' % t[n], show=True)
            else:
                error = u_exact(x, t[n]) - u
                local_max_error = np.abs(error).max()
                # self.max_error holds the increasing amplitude error
                if self.max_error == [] or \
                       local_max_error > max(self.max_error):
                    self.max_error.append(local_max_error)
                    self.max_error_t.append(t[n])
                # Use user's ymax until the error exceeds that value.
                # This gives a growing max value of the yaxis (but
                # never shrinking)
                self.ymax = max(self.ymax, max(self.max_error))
                plt.plot(x, error, 'r-',
                         xlabel='x', ylabel='error',
                         axis=[0, L, -self.ymax, self.ymax],
                         title='t=%f' % t[n], show=True)
            plt.savefig('%s_%04d.png' % (self.frame_name, n))

    # Clean up old movie frames
    for filename in glob.glob('frame_*.png'):
        os.remove(filename)

    plot = Plot(ymax)
    u, x, t, cpu = solver(I, V, f, c, L, Nx, C, T, plot)

    # Make plot of max error versus time
    plt.figure()
    plt.plot(plot.max_error_t, plot.max_error)
    plt.xlabel('time'); plt.ylabel('max abs(error)')
    plt.savefig('error.png')
    plt.savefig('error.pdf')

    # Make .flv movie file
    fps = 4  # Frames per second
    codec2ext = dict(flv='flv') #, libx64='mp4', libvpx='webm', libtheora='ogg')

    filespec = 'frame_%04d.png'
    movie_program = 'avconv'  # or 'ffmpeg'
    for codec in codec2ext:
        ext = codec2ext[codec]
        cmd = '%(movie_program)s -r %(fps)d -i %(filespec)s '\
              '-vcodec %(codec)s %(movie_filename)s.%(ext)s' % vars()
        os.system(cmd)
示例#26
0
def estimate(truncation_error, T, N_0, m, makeplot=True):
    """
    Compute the truncation error in a problem with one independent
    variable, using m meshes, and estimate the convergence
    rate of the truncation error.

    The user-supplied function truncation_error(dt, N) computes
    the truncation error on a uniform mesh with N intervals of
    length dt::

      R, t, R_a = truncation_error(dt, N)

    where R holds the truncation error at points in the array t,
    and R_a are the corresponding theoretical truncation error
    values (None if not available).

    The truncation_error function is run on a series of meshes
    with 2**i*N_0 intervals, i=0,1,...,m-1.
    The values of R and R_a are restricted to the coarsest mesh.
    and based on these data, the convergence rate of R (pointwise)
    and time-integrated R can be estimated empirically.
    """
    N = [2**i*N_0 for i in range(m)]

    R_I = np.zeros(m) # time-integrated R values on various meshes
    R   = [None]*m    # time series of R restricted to coarsest mesh
    R_a = [None]*m    # time series of R_a restricted to coarsest mesh
    dt = np.zeros(m)
    legends_R = [];  legends_R_a = []  # all legends of curves

    for i in range(m):
        dt[i] = T/float(N[i])
        R[i], t, R_a[i] = truncation_error(dt[i], N[i])

        R_I[i] = np.sqrt(dt[i]*np.sum(R[i]**2))

        if i == 0:
            t_coarse = t           # the coarsest mesh

        stride = N[i]/N_0
        R[i] = R[i][::stride]      # restrict to coarsest mesh
        R_a[i] = R_a[i][::stride]

        if makeplot:
            plt.figure(1)
            plt.plot(t_coarse, R[i], log='y')
            legends_R.append('N=%d' % N[i])
            plt.hold('on')

            plt.figure(2)
            plt.plot(t_coarse, R_a[i] - R[i], log='y')
            plt.hold('on')
            legends_R_a.append('N=%d' % N[i])

    if makeplot:
        plt.figure(1)
        plt.xlabel('time')
        plt.ylabel('pointwise truncation error')
        plt.legend(legends_R)
        plt.savefig('R_series.png')
        plt.savefig('R_series.pdf')
        plt.figure(2)
        plt.xlabel('time')
        plt.ylabel('pointwise error in estimated truncation error')
        plt.legend(legends_R_a)
        plt.savefig('R_error.png')
        plt.savefig('R_error.pdf')

    # Convergence rates
    r_R_I = convergence_rates(dt, R_I)
    print 'R integrated in time; r:',
    print ' '.join(['%.1f' % r for r in r_R_I])
    R = np.array(R)  # two-dim. numpy array
    r_R = [convergence_rates(dt, R[:,n])[-1]
           for n in range(len(t_coarse))]

    # Plot convergence rates
    if makeplot:
        plt.figure()
        plt.plot(t_coarse, r_R)
        plt.xlabel('time')
        plt.ylabel('r')
        plt.axis([t_coarse[0], t_coarse[-1], 0, 2.5])
        plt.title('Pointwise rate $r$ in truncation error $\sim\Delta t^r$')
        plt.savefig('R_rate_series.png')
        plt.savefig('R_rate_series.pdf')
示例#27
0
def run_solvers_and_plot(solvers,
                         timesteps_per_period=20,
                         num_periods=1,
                         I=1,
                         w=2 * np.pi):
    P = 2 * np.pi / w  # one period
    dt = P / timesteps_per_period
    N = num_periods * timesteps_per_period
    T = N * dt
    t_mesh = np.linspace(0, T, N + 1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:, 0], u[:, 1])  # markers by default
            else:
                plt.plot(u[:, 0], u[:, 1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:, 0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2 * np.pi / p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I * np.cos(w * t_fine)
    v_e = -w * I * np.sin(w * t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-')  # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-')  # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)')
        plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
示例#28
0
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 19 21:13:30 2015

@author: antalcides
"""
from ForwardEuleruni import *
from LogisticUni import *

problem = Logistic(0.2, 1, 0.1)

T = 40
dt = 0.1
method = ForwardEuler(problem, dt)
method.set_initial_condition(problem.u0, 0)
u, t = method.solve(T)
from scitools.std import plot, hardcopy, xlabel, ylabel, title
plot(t, u)
xlabel('t')
ylabel('u')
title('Logistic growth: alpha=0.2, dt=%g, %d steps' \
    % (dt, len(u)-1))
def run_solvers_and_plot(solvers,
                         timesteps_per_period=20,
                         num_periods=1,
                         I=1,
                         w=2 * np.pi):
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Compute energy
        dt = t[1] - t[0]
        E = 0.5 * ((u[2:, 0] - u[:-2, 0]) /
                   (2 * dt))**2 + 0.5 * w**2 * u[1:-1, 0]**2
        # Compute error in energy
        E0 = 0.5 * 0**2 + 0.5 * w**2 * I**2
        e_E = E - E0

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__
        print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % (
            solver_name, t[-1], dt, np.abs(e_E).max() / E0)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver_name)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:, 0], u[:, 1])  # markers by default
            else:
                plt.plot(u[:, 0], u[:, 1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:, 0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2 * np.pi / p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I * np.cos(w * t_fine)
    v_e = -w * I * np.sin(w * t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-')  # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-')  # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)')
        plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vib_%d_%d_p.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vib_%d_%d_a.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods))
示例#30
0
def viz(
    I,
    V,
    f,
    c,
    L,
    dt,
    C,
    T,
    ymax,  # y axis: [-ymax, ymax]
    u_exact,  # u_exact(x, t)
    animate='u and u_exact',  # or 'error'
    movie_filename='movie',
):
    """Run solver and visualize u at each time level."""
    import scitools.std as plt
    import time, glob, os

    class Plot:
        def __init__(self, ymax, frame_name='frame'):
            self.max_error = []  # hold max amplitude errors
            self.max_error_t = []  # time points corresp. to max_error
            self.frame_name = frame_name
            self.ymax = ymax

        def __call__(self, u, x, t, n):
            """user_action function for solver."""
            if animate == 'u and u_exact':
                plt.plot(x,
                         u,
                         'r-',
                         x,
                         u_exact(x, t[n]),
                         'b--',
                         xlabel='x',
                         ylabel='u',
                         axis=[0, L, -self.ymax, self.ymax],
                         title='t=%f' % t[n],
                         show=True)
            else:
                error = u_exact(x, t[n]) - u
                local_max_error = np.abs(error).max()
                # self.max_error holds the increasing amplitude error
                if self.max_error == [] or \
                       local_max_error > max(self.max_error):
                    self.max_error.append(local_max_error)
                    self.max_error_t.append(t[n])
                # Use user's ymax until the error exceeds that value.
                # This gives a growing max value of the yaxis (but
                # never shrinking)
                self.ymax = max(self.ymax, max(self.max_error))
                plt.plot(x,
                         error,
                         'r-',
                         xlabel='x',
                         ylabel='error',
                         axis=[0, L, -self.ymax, self.ymax],
                         title='t=%f' % t[n],
                         show=True)
            plt.savefig('%s_%04d.png' % (self.frame_name, n))

    # Clean up old movie frames
    for filename in glob.glob('frame_*.png'):
        os.remove(filename)

    plot = Plot(ymax)
    u, x, t, cpu = solver(I, V, f, c, L, dt, C, T, plot)

    # Make plot of max error versus time
    plt.figure()
    plt.plot(plot.max_error_t, plot.max_error)
    plt.xlabel('time')
    plt.ylabel('max abs(error)')
    plt.savefig('error.png')
    plt.savefig('error.pdf')

    # Make .flv movie file
    fps = 4  # Frames per second
    codec2ext = dict(flv='flv')  #, libx64='mp4',
    #libvpx='webm', libtheora='ogg')

    filespec = 'frame_%04d.png'
    movie_program = 'avconv'  # or 'ffmpeg'
    for codec in codec2ext:
        ext = codec2ext[codec]
        cmd = '%(movie_program)s -r %(fps)d -i %(filespec)s '\
              '-vcodec %(codec)s %(movie_filename)s.%(ext)s' % vars()
        os.system(cmd)
示例#31
0
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # one period
    dt = P/timesteps_per_period
    N = num_periods*timesteps_per_period
    T = N*dt
    t_mesh = np.linspace(0, T, N+1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:,0], u[:,1])        # markers by default
            else:
                plt.plot(u[:,0], u[:,1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:,0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2*np.pi/p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I*np.cos(w*t_fine)
    v_e = -w*I*np.sin(w*t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-') # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)');  plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
示例#32
0
    T = num_periods * P
    t = np.linspace(0, T, time_steps_per_period * num_periods + 1)
    import odespy

    def f(u, t, alpha):
        # Note the sequence of unknowns: v, u (v=du/dt)
        v, u = u
        return [-alpha * np.sign(v) - u, v]

    solver = odespy.RK4(f, f_args=[alpha])
    solver.set_initial_condition([beta, 1])  # sequence must match f
    uv, t = solver.solve(t)
    u = uv[:, 1]  # recall sequence in f: v, u
    v = uv[:, 0]
    return u, t


if __name__ == "__main__":
    alpha_values = [0, 0.05, 0.1]
    for alpha in alpha_values:
        u, t = simulate(alpha, 0, 6, 60)
        plt.plot(t, u)
        plt.hold("on")
    plt.legend([r"$\alpha=%g$" % alpha for alpha in alpha_values])
    plt.xlabel(r"$\bar t$")
    plt.ylabel(r"$\bar u$")
    plt.savefig("tmp.png")
    plt.savefig("tmp.pdf")
    plt.show()
    raw_input()  # for scitools' matplotlib engine
import scitools.std as plt
import sys
import numpy as np
import matplotlib.pyplot as plt

x, y = np.loadtxt('volt.txt', delimiter=',', unpack=True)

plt.figure(1)
plt.plot(x, y, '*', linewidth=1)  # avoid markers by spec. line type
#plt.xlim([0.0, 10])
#plt.ylim([0.0, 2])
plt.legend(['Force-- Tip'],
           loc='upper right',
           prop={"family": "Times New Roman"})
plt.xlabel('Sampled time')
plt.ylabel('$Force /m$')
plt.savefig('volt1v.png')
plt.savefig('volt1v.pdf')
plt.hold(True)
示例#34
0
    T = num_periods * P
    t = np.linspace(0, T, time_steps_per_period * num_periods + 1)
    import odespy

    def f(u, t, alpha):
        # Note the sequence of unknowns: v, u (v=du/dt)
        v, u = u
        return [-alpha * np.sign(v) - u, v]

    solver = odespy.RK4(f, f_args=[alpha])
    solver.set_initial_condition([beta, 1])  # sequence must match f
    uv, t = solver.solve(t)
    u = uv[:, 1]  # recall sequence in f: v, u
    v = uv[:, 0]
    return u, t


if __name__ == '__main__':
    alpha_values = [0, 0.05, 0.1]
    for alpha in alpha_values:
        u, t = simulate(alpha, 0, 6, 60)
        plt.plot(t, u)
        plt.hold('on')
    plt.legend([r'$\alpha=%g$' % alpha for alpha in alpha_values])
    plt.xlabel(r'$\bar t$')
    plt.ylabel(r'$\bar u$')
    plt.savefig('tmp.png')
    plt.savefig('tmp.pdf')
    plt.show()
    raw_input()  # for scitools' matplotlib engine
示例#35
0
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Compute energy
        dt = t[1] - t[0]
        E = 0.5*((u[2:,0] - u[:-2,0])/(2*dt))**2 + 0.5*w**2*u[1:-1,0]**2
        # Compute error in energy
        E0 = 0.5*0**2 + 0.5*w**2*I**2
        e_E = E - E0

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__
        print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % (solver_name, t[-1], dt, np.abs(e_E).max()/E0)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:,0], u[:,1])        # markers by default
            else:
                plt.plot(u[:,0], u[:,1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:,0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2*np.pi/p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I*np.cos(w*t_fine)
    v_e = -w*I*np.sin(w*t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-') # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)');  plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vib_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vib_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.eps' % (timesteps_per_period, num_periods))