Buckets:
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| def solver(I, w, dt, T): | |
| """ | |
| Solve u'' + w**2*u = 0 for t in (0,T], u(0)=I and u'(0)=0, | |
| by a central finite difference method with time step dt. | |
| """ | |
| dt = float(dt) | |
| Nt = int(round(T/dt)) | |
| u = np.zeros(Nt+1) | |
| t = np.linspace(0, Nt*dt, Nt+1) | |
| u[0] = I | |
| u[1] = u[0] - 0.5*dt**2*w**2*u[0] | |
| for n in range(1, Nt): | |
| u[n+1] = 2*u[n] - u[n-1] - dt**2*w**2*u[n] | |
| return u, t | |
| def u_exact(t, I, w): | |
| return I*np.cos(w*t) | |
| def visualize(u, t, I, w): | |
| plt.plot(t, u, 'r--o') | |
| t_fine = np.linspace(0, t[-1], 1001) # very fine mesh for u_e | |
| u_e = u_exact(t_fine, I, w) | |
| plt.hold('on') | |
| plt.plot(t_fine, u_e, 'b-') | |
| plt.legend(['numerical', 'exact'], loc='upper left') | |
| plt.xlabel('t') | |
| plt.ylabel('u') | |
| dt = t[1] - t[0] | |
| plt.title('dt=%g' % dt) | |
| umin = 1.2*u.min(); umax = -umin | |
| plt.axis([t[0], t[-1], umin, umax]) | |
| plt.savefig('tmp1.png'); plt.savefig('tmp1.pdf') | |
| def test_three_steps(): | |
| from math import pi | |
| I = 1; w = 2*pi; dt = 0.1; T = 1 | |
| u_by_hand = np.array([1.000000000000000, | |
| 0.802607911978213, | |
| 0.288358920740053]) | |
| u, t = solver(I, w, dt, T) | |
| diff = np.abs(u_by_hand - u[:3]).max() | |
| tol = 1E-14 | |
| assert diff < tol | |
| def convergence_rates(m, solver_function, num_periods=8): | |
| """ | |
| Return m-1 empirical estimates of the convergence rate | |
| based on m simulations, where the time step is halved | |
| for each simulation. | |
| solver_function(I, w, dt, T) solves each problem, where T | |
| is based on simulation for num_periods periods. | |
| """ | |
| from math import pi | |
| w = 0.35; I = 0.3 # just chosen values | |
| P = 2*pi/w # period | |
| dt = P/30 # 30 time step per period 2*pi/w | |
| T = P*num_periods | |
| dt_values = [] | |
| E_values = [] | |
| for i in range(m): | |
| u, t = solver_function(I, w, dt, T) | |
| u_e = u_exact(t, I, w) | |
| E = np.sqrt(dt*np.sum((u_e-u)**2)) | |
| dt_values.append(dt) | |
| E_values.append(E) | |
| dt = dt/2 | |
| r = [np.log(E_values[i-1]/E_values[i])/ | |
| np.log(dt_values[i-1]/dt_values[i]) | |
| for i in range(1, m, 1)] | |
| return r | |
| def test_convergence_rates(): | |
| r = convergence_rates(m=5, solver_function=solver, num_periods=8) | |
| # Accept rate to 1 decimal place | |
| tol = 0.1 | |
| assert abs(r[-1] - 2.0) < tol | |
| def main(solver_function=solver): | |
| import argparse | |
| from math import pi | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--I', type=float, default=1.0) | |
| parser.add_argument('--w', type=float, default=2*pi) | |
| parser.add_argument('--dt', type=float, default=0.05) | |
| parser.add_argument('--num_periods', type=int, default=5) | |
| parser.add_argument('--savefig', action='store_true') | |
| # Hack to allow --SCITOOLS options (read when importing scitools.std) | |
| parser.add_argument('--SCITOOLS_easyviz_backend', default='matplotlib') | |
| a = parser.parse_args() | |
| I, w, dt, num_periods, savefig = \ | |
| a.I, a.w, a.dt, a.num_periods, a.savefig | |
| P = 2*pi/w # one period | |
| T = P*num_periods | |
| u, t = solver_function(I, w, dt, T) | |
| if num_periods <= 10: | |
| visualize(u, t, I, w) | |
| else: | |
| visualize_front(u, t, I, w, savefig) | |
| #visualize_front_ascii(u, t, I, w) | |
| #plot_empirical_freq_and_amplitude(u, t, I, w) | |
| plt.show() | |
| def plot_empirical_freq_and_amplitude(u, t, I, w): | |
| """ | |
| Find the empirical angular frequency and amplitude of | |
| simulations in u and t. u and t can be arrays or (in | |
| the case of multiple simulations) multiple arrays. | |
| One plot is made for the amplitude and one for the angular | |
| frequency (just called frequency in the legends). | |
| """ | |
| from vib_empirical_analysis import minmax, periods, amplitudes | |
| from math import pi | |
| if not isinstance(u, (list,tuple)): | |
| u = [u] | |
| t = [t] | |
| legends1 = [] | |
| legends2 = [] | |
| for i in range(len(u)): | |
| minima, maxima = minmax(t[i], u[i]) | |
| p = periods(maxima) | |
| a = amplitudes(minima, maxima) | |
| plt.figure(1) | |
| plt.plot(range(len(p)), 2*pi/p) | |
| legends1.append('frequency, case%d' % (i+1)) | |
| plt.hold('on') | |
| plt.figure(2) | |
| plt.plot(range(len(a)), a) | |
| plt.hold('on') | |
| legends2.append('amplitude, case%d' % (i+1)) | |
| plt.figure(1) | |
| plt.plot(range(len(p)), [w]*len(p), 'k--') | |
| legends1.append('exact frequency') | |
| plt.legend(legends1, loc='lower left') | |
| plt.axis([0, len(a)-1, 0.8*w, 1.2*w]) | |
| plt.savefig('tmp1.png'); plt.savefig('tmp1.pdf') | |
| plt.figure(2) | |
| plt.plot(range(len(a)), [I]*len(a), 'k--') | |
| legends2.append('exact amplitude') | |
| plt.legend(legends2, loc='lower left') | |
| plt.axis([0, len(a)-1, 0.8*I, 1.2*I]) | |
| plt.savefig('tmp2.png'); plt.savefig('tmp2.pdf') | |
| plt.show() | |
| def visualize_front(u, t, I, w, savefig=False, skip_frames=1): | |
| """ | |
| Visualize u and the exact solution vs t, using a | |
| moving plot window and continuous drawing of the | |
| curves as they evolve in time. | |
| Makes it easy to plot very long time series. | |
| Plots are saved to files if savefig is True. | |
| Only each skip_frames-th plot is saved (e.g., if | |
| skip_frame=10, only each 10th plot is saved to file; | |
| this is convenient if plot files corresponding to | |
| different time steps are to be compared). | |
| """ | |
| import scitools.std as st | |
| from scitools.MovingPlotWindow import MovingPlotWindow | |
| from math import pi | |
| # Remove all old plot files tmp_*.png | |
| import glob, os | |
| for filename in glob.glob('tmp_*.png'): | |
| os.remove(filename) | |
| P = 2*pi/w # one period | |
| umin = 1.2*u.min(); umax = -umin | |
| dt = t[1] - t[0] | |
| plot_manager = MovingPlotWindow( | |
| window_width=8*P, | |
| dt=dt, | |
| yaxis=[umin, umax], | |
| mode='continuous drawing') | |
| frame_counter = 0 | |
| for n in range(1,len(u)): | |
| if plot_manager.plot(n): | |
| s = plot_manager.first_index_in_plot | |
| st.plot(t[s:n+1], u[s:n+1], 'r-1', | |
| t[s:n+1], I*cos(w*t)[s:n+1], 'b-1', | |
| title='t=%6.3f' % t[n], | |
| axis=plot_manager.axis(), | |
| show=not savefig) # drop window if savefig | |
| if savefig and n % skip_frames == 0: | |
| filename = 'tmp_%04d.png' % frame_counter | |
| st.savefig(filename) | |
| print 'making plot file', filename, 'at t=%g' % t[n] | |
| frame_counter += 1 | |
| plot_manager.update(n) | |
| def visualize_front_ascii(u, t, I, w, fps=10): | |
| """ | |
| Plot u and the exact solution vs t line by line in a | |
| terminal window (only using ascii characters). | |
| Makes it easy to plot very long time series. | |
| """ | |
| from scitools.avplotter import Plotter | |
| import time | |
| from math import pi | |
| P = 2*pi/w | |
| umin = 1.2*u.min(); umax = -umin | |
| p = Plotter(ymin=umin, ymax=umax, width=60, symbols='+o') | |
| for n in range(len(u)): | |
| print p.plot(t[n], u[n], I*cos(w*t[n])), \ | |
| '%.1f' % (t[n]/P) | |
| time.sleep(1/float(fps)) | |
| def bokeh_plot(u, t, legends, I, w, t_range, filename): | |
| """ | |
| Make plots for u vs t using the Bokeh library. | |
| u and t are lists (several experiments can be compared). | |
| legens contain legend strings for the various u,t pairs. | |
| """ | |
| if not isinstance(u, (list,tuple)): | |
| u = [u] # wrap in list | |
| if not isinstance(t, (list,tuple)): | |
| t = [t] # wrap in list | |
| if not isinstance(legends, (list,tuple)): | |
| legends = [legends] # wrap in list | |
| import bokeh.plotting as plt | |
| plt.output_file(filename, mode='cdn', title='Comparison') | |
| # Assume that all t arrays have the same range | |
| t_fine = np.linspace(0, t[0][-1], 1001) # fine mesh for u_e | |
| tools = 'pan,wheel_zoom,box_zoom,reset,'\ | |
| 'save,box_select,lasso_select' | |
| u_range = [-1.2*I, 1.2*I] | |
| font_size = '8pt' | |
| p = [] # list of plot objects | |
| # Make the first figure | |
| p_ = plt.figure( | |
| width=300, plot_height=250, title=legends[0], | |
| x_axis_label='t', y_axis_label='u', | |
| x_range=t_range, y_range=u_range, tools=tools, | |
| title_text_font_size=font_size) | |
| p_.xaxis.axis_label_text_font_size=font_size | |
| p_.yaxis.axis_label_text_font_size=font_size | |
| p_.line(t[0], u[0], line_color='blue') | |
| # Add exact solution | |
| u_e = u_exact(t_fine, I, w) | |
| p_.line(t_fine, u_e, line_color='red', line_dash='4 4') | |
| p.append(p_) | |
| # Make the rest of the figures and attach their axes to | |
| # the first figure's axes | |
| for i in range(1, len(t)): | |
| p_ = plt.figure( | |
| width=300, plot_height=250, title=legends[i], | |
| x_axis_label='t', y_axis_label='u', | |
| x_range=p[0].x_range, y_range=p[0].y_range, tools=tools, | |
| title_text_font_size=font_size) | |
| p_.xaxis.axis_label_text_font_size = font_size | |
| p_.yaxis.axis_label_text_font_size = font_size | |
| p_.line(t[i], u[i], line_color='blue') | |
| p_.line(t_fine, u_e, line_color='red', line_dash='4 4') | |
| p.append(p_) | |
| # Arrange all plots in a grid with 3 plots per row | |
| grid = [[]] | |
| for i, p_ in enumerate(p): | |
| grid[-1].append(p_) | |
| if (i+1) % 3 == 0: | |
| # New row | |
| grid.append([]) | |
| plot = plt.gridplot(grid, toolbar_location='left') | |
| plt.save(plot) | |
| plt.show(plot) | |
| def demo_bokeh(): | |
| """Solve a scaled ODE u'' + u = 0.""" | |
| from math import pi | |
| w = 1.0 # Scaled problem (frequency) | |
| P = 2*np.pi/w # Period | |
| num_steps_per_period = [5, 10, 20, 40, 80] | |
| T = 40*P # Simulation time: 40 periods | |
| u = [] # List of numerical solutions | |
| t = [] # List of corresponding meshes | |
| legends = [] | |
| for n in num_steps_per_period: | |
| dt = P/n | |
| u_, t_ = solver(I=1, w=w, dt=dt, T=T) | |
| u.append(u_) | |
| t.append(t_) | |
| legends.append('# time steps per period: %d' % n) | |
| bokeh_plot(u, t, legends, I=1, w=w, t_range=[0, 4*P], | |
| filename='tmp.html') | |
| if __name__ == '__main__': | |
| #main() | |
| demo_bokeh() | |
| raw_input() | |
Xet Storage Details
- Size:
- 10.2 kB
- Xet hash:
- 408ad015ce7ab197a483fe623369f1fbaed9eea597c63f7495a3904e808a608e
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.