def spinecho_short(fname): with open(get_path(__file__, 'experimental/echo_experimental.json')) as f: vis_exp = json.load(f) with open(get_path(__file__, 'simulations/echo_gpe.json')) as f: gpe = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner.json')) as f: wig = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner_varied_pulse.json')) as f: wig_tech = json.load(f) t_exp = numpy.array(vis_exp['xarray']) v_exp = numpy.array(vis_exp['yarray']) v_exp_err = numpy.array(vis_exp['yerrors']) gpe_t = numpy.array(gpe['times']) gpe_v = numpy.array(gpe['visibility']) wig_t = numpy.array(wig['times']) wig_v = numpy.array(wig['visibility']) wig_tech_t = numpy.array(wig_tech['times']) wig_tech_v = numpy.array(wig_tech['est_visibility']) fig = mplh.figure(width=0.75) s = fig.add_subplot(111, xlabel='$t$ (s)', ylabel='$\\mathcal{V}$') s.errorbar(t_exp, v_exp, yerr=v_exp_err, color='k', linestyle='none', capsize=1.5) # GPE s.plot(gpe_t, gpe_v, color=mplh.color.f.green.main, linestyle=':', dashes=mplh.dash[':']) # Pure Wigner s.plot(wig_t, wig_v, color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) # Wigner + technical noise s.plot(wig_tech_t, wig_tech_v, color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.set_xlim((0, 1.8)) s.set_ylim((0, 1.)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.plot([0.05, 0.16], [0.23, 0.23], color=mplh.color.f.green.main, linestyle=':', dashes=mplh.dash[':']) s.text(0.18, 0.22, 'mean-field') s.plot([0.05, 0.16], [0.15, 0.15], color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.text(0.18, 0.14, 'Wigner') s.plot([0.05, 0.16], [0.07, 0.07], color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.text(0.18, 0.06, 'Wigner + tech. noise') s.errorbar([0.88], [0.07], yerr=[0.02], color='k', linestyle='none', capsize=1.5) s.text(0.92, 0.06, 'experiment') fig.tight_layout(pad=0.3) fig.savefig(fname)
def spinecho_single_run_population(fname): with open(get_path(__file__, 'simulations/echo_wigner_single_run.json')) as f: wig = json.load(f) wig_t = numpy.array(wig['times']) wig_N1 = numpy.array(wig['N1']) wig_N2 = numpy.array(wig['N2']) fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='$t$ (s)', ylabel='$N$') # Pure Wigner s.plot(wig_t, wig_N1, color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.plot(wig_t, wig_N2, color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.set_xlim((0, 1.3)) s.set_ylim((0, 55000. / 2)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.text(0.1, 2500, 'spin echo sequence') s.text(1., 4000, '$\\vert 1 \\rangle$') s.text(1., 13000, '$\\vert 2 \\rangle$') fig.text(0.01, 0.92, '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def spinecho_noise(fname): with open(get_path(__file__, 'experimental/echo_phnoise_exp.json')) as f: exp = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner.json')) as f: wig = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner_varied_pulse.json')) as f: tech_wig = json.load(f) t_wig = numpy.array(wig['times']) ph_wig = numpy.array(wig['est_phnoises']) t_tech_wig = numpy.array(tech_wig['times']) ph_tech_wig = numpy.array(tech_wig['est_phnoises']) t_exp = numpy.array(exp['xarray']) ph_exp = numpy.array(exp['yarray']) ph_exp_errors = numpy.array(exp['yerrors']) fig = mplh.figure(width=0.75) s = fig.add_subplot(111, xlabel='$t$ (s)', ylabel='$\\mathcal{\\sigma}$ (rad)') s.errorbar(t_exp, ph_exp, yerr=ph_exp_errors, color='k', linestyle='none', capsize=1.5) s.plot(t_wig, ph_wig, color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.plot(t_tech_wig, ph_tech_wig, color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.set_xlim((0, 1.6)) s.set_ylim((0, 0.5)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.plot([0.03, 0.15], [0.43, 0.43], color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.text(0.18, 0.42, 'Wigner') s.plot([0.03, 0.15], [0.39, 0.39], color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.text(0.18, 0.38, 'Wigner + tech. noise') s.errorbar([0.09], [0.35], yerr=[0.01], color='k', linestyle='none', capsize=1.5) s.text(0.18, 0.34, 'experiment') fig.tight_layout(pad=0.3) fig.savefig(fname)
def convergence_by_time(fname): with open(get_path(__file__, 'convergence_wigner.json')) as f: results = json.load(f) colors = { "RK46NL": mplh.color.f.blue, "RK4IP": mplh.color.f.red, "CDIP": mplh.color.f.green, "CD": mplh.color.f.yellow} linestyles = { "RK46NL": '-', "RK4IP": '--', "CDIP": ':', "CD": '-.'} fig = mplh.figure(width=0.75) s = fig.add_subplot(111, xlabel='integration time (s)', ylabel='$E_2$') s.set_xscale('log', basex=10) s.set_yscale('log', basey=10) tmin = 10 tmax = 10 ** 4 s.set_xlim(tmin, tmax) s.set_ylim(10**(-7), 1) s.fill_between([tmin, tmax], [10**(-5), 10**(-5)], [10**(-4), 10**(-4)], facecolor=(0.9, 0.9, 0.9), color=(0.7,0.7,0.7), linewidth=0.5) for label in colors: times = [] N_errors = [] int_steps = [int(steps) for steps in results[label]] for steps in sorted(int_steps): result = results[label][str(steps)] times.append(result['t_integration']) N_errors.append(result['weak_errors']['N']) s.plot(times, N_errors, label=label + ", N errors", color=colors[label].main, dashes=mplh.dash[linestyles[label]]) s.text(4.5*10**2, 10**(-2), '\\abbrev{CD}') s.text(2.5*10**2, 1.5*10**(-3), '\\abbrev{CDIP}') s.text(6.5*10**1, 10**(-2), '\\abbrev{RK4IP}') s.text(2*10**1, 1.5*10**(-3), '\\abbrev{RK46NL}') s.text(1.5*10**1, 3*10**(-6), 'target accuracy') fig.tight_layout(pad=0.3) fig.savefig(fname)
def spinecho_long(fname): with open(get_path(__file__, 'simulations/echo_gpe_long.json')) as f: gpe = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner_long.json')) as f: wig = json.load(f) with open(get_path(__file__, 'simulations/echo_wigner_varied_pulse_long.json')) as f: wig_tech = json.load(f) t_gpe = numpy.array(gpe['times']) v_gpe = numpy.array(gpe['visibility']) t_wig = numpy.array(wig['times']) v_wig = numpy.array(wig['visibility']) t_tech_wig = numpy.array(wig_tech['times']) v_tech_wig = numpy.array(wig_tech['est_visibility']) fig = mplh.figure() s = fig.add_subplot(111, xlabel='$t$ (s)', ylabel='$\\mathcal{V}$') # GPE s.plot(t_gpe, v_gpe, color=mplh.color.f.green.main, linestyle=':', dashes=mplh.dash[':']) # Pure Wigner s.plot(t_wig, v_wig, color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.plot(t_tech_wig, v_tech_wig, color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.set_xlim((0, 3.)) s.set_ylim((0, 1.)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.text(0.2, 0.1, 'spin echo sequence') fig.text(0.01, 0.92, '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def illustration_noise(fname, t_ms): with open(get_path(__file__, 'ramsey_sim_phnoise_' + str(t_ms) + 'ms.json')) as f: meas = json.load(f) Pz = numpy.array(meas['Pz']) phis = numpy.array(meas['phis']) est_phase = numpy.array(meas['est_phase']) est_phnoise = numpy.array(meas['est_phnoise']) est_amp = numpy.array(meas['est_amp']) fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='$\\phi$ (rad)', ylabel='$P_z$') phis_fit = numpy.linspace(0, numpy.pi * 2, 200) Pz_fit = est_amp * numpy.cos(phis_fit + est_phase) s.plot(phis_fit, Pz_fit, color=mplh.color.f.red.main, linestyle='-', dashes=mplh.dash['-']) s.scatter(phis, Pz, color='grey', s=1) s.text(numpy.pi / 2 - est_phase - est_phnoise - 0.5, 0.05, "$\\sigma") arrow_kwds = dict( shape="full", overhang=0, head_starts_at_zero=False, fill=False, length_includes_head=True) s.arrow( numpy.pi / 2 - est_phase - est_phnoise - 0.5, 0.0, 0.45, 0.0, **arrow_kwds) s.arrow( numpy.pi / 2 - est_phase + est_phnoise + 0.5, 0.0, -0.45, 0.0, **arrow_kwds) s.set_xlim((0, 2 * numpy.pi)) s.set_ylim((-1, 1)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.text(0.15, -0.85, '$t=' + str(t_ms) + '\\,\\mathrm{ms}$') fig.text(0.01, 0.92, '(a)' if t_ms == 20 else '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _squeezing(fname, coupling, ens): with open(get_path(__file__, 'single_well_squeezing_wigner_' + ens + '_Na200.pickle')) as f: wigner = pickle.load(f) suffix = '_c' if coupling else '_nc' interaction = (100.4, 80.8, 95.5) if coupling else (100.4, 0., 100.4) tau_exact = numpy.linspace(1e-3, 120 if coupling else 20, 200) s_exact = get_exact_S(tau_exact, 200, *interaction) tau_wigner = wigner['tau' + suffix] s_wigner = wigner['s_pi2' + suffix] s_wigner_err = wigner['s_pi2' + suffix + '_err'] s_exact = numpy.log10(s_exact) * 10 tau_wigner, s_wigner_bot, s_wigner_top = mplh.crop_bounds( tau_wigner, numpy.log10(s_wigner - s_wigner_err) * 10, numpy.log10(s_wigner + s_wigner_err) * 10, (0, (120 if coupling else 20), -15, 1)) fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='$\\tau$', ylabel='$S_{\\theta + \\pi/2}$ (dB)') s.plot(tau_exact, s_exact, color="black") s.fill_between( tau_wigner, s_wigner_bot, s_wigner_top, facecolor=mplh.color.f.blue.lightest, linewidth=0) s.text( 18 if coupling else 3, -1, "interaction on" if coupling else "interaction off") s.set_xlim((0, 120 if coupling else 20)) s.set_ylim((-15, 1)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) fig.text(0.01, 0.92, '(b)' if coupling else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _two_comp_gs(fname, a12): with open(get_path(__file__, 'two_comp_gs.json'), 'rb') as f: data = json.load(f) zs = numpy.array(data[str(a12)]['xs']) / 1e-6 # to um n_z = numpy.array(data[str(a12)]['n_x']) * 1e-6 # to um^-1 fig = mplh.figure() s = fig.add_subplot(111, xlabel='$z$ ($\\mu\\mathrm{m}$)', ylabel='$n_z$ ($\\mu\\mathrm{m}^{-1}$)') s.plot(zs, n_z[0], color=mplh.color.f.blue.main, linestyle='-') s.plot(zs, n_z[1], color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.text( 11, 2000. / 2500 * 1600 if a12 == 97. else 2000, '$a_{12}=' + str(a12) + '\\,r_B$') s.text( 11, 1700. / 2500 * 1600 if a12 == 97. else 1700, ('(miscible)' if a12 == 97. else '(immiscible)')) s.text( -28 if a12 == 97. else -26, 1000. / 2500 * 1600 if a12 == 97. else 1000, '$\\vert 1 \\rangle$') s.text( -15 if a12 == 97. else -13, 2000. / 2500 * 1600 if a12 == 97. else 2000, '$\\vert 2 \\rangle$') s.set_xlim(-40, 40) if a12 == 97.: s.set_ylim(0, 1600) else: s.set_ylim(0, 2500) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) fig.text(0.01, 0.92, '(a)' if a12 == 97. else '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _grid_check(prefix, fname): wigner = (prefix == 'wigner') with open(get_path(__file__, 'grid_test.json')) as f: data = json.load(f) data = data['wigner' if wigner else 'gpe'] fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='relative spacing', ylabel='$\\Delta \\mathcal{V}$') radial_spacings = list(sorted(data['radial_points'])) radial_diffs = [data['radial_points'][spacing] for spacing in radial_spacings] s.scatter([1.] + radial_spacings, [0.] + radial_diffs, marker='^', color=mplh.color.f.red.main, s=10) axial_spacings = list(sorted(data['axial_points'])) axial_diffs = [data['axial_points'][spacing] for spacing in axial_spacings] s.scatter([1.] + axial_spacings, [0.] + axial_diffs, marker='.', color=mplh.color.f.blue.main, s=10) s.plot([0.4, 1.6], [0, 0], color='grey', linewidth=0.5, dashes=mplh.dash['-.']) s.set_xlim((0.4, 1.6)) s.set_ylim((-0.01, 0.07)) legend_x = 0.7 legend_y = 0.06 s.scatter( [legend_x, legend_x + 0.04, legend_x + 0.08], [legend_y] * 3, marker='.', color=mplh.color.f.blue.dark, s=10) s.text(legend_x + 0.12, legend_y - 0.002, 'axial spacing') s.scatter( [legend_x, legend_x + 0.04, legend_x + 0.08], [legend_y - 0.008] * 3, marker='^', color=mplh.color.f.red.dark, s=10) s.text(legend_x + 0.12, legend_y - 0.01, 'radial spacing') s.text(1.32, 0.06, 'Wigner' if wigner else 'GPE') fig.text(0.01, 0.92, '(b)' if wigner else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def ghz_errors(fname): with open(get_path(__file__, 'ghz_sampling.json')) as f: data = json.load(f) fig = mplh.figure(width=0.5) ax = fig.add_subplot(111) ax.set_xlabel('$M$') ax.set_ylabel('$\\log_{2}(\\mathrm{Err}(F) / F_{\\mathrm{QM}})$') corr1 = filter_data(data['different_order_correlations'], representation='Q', quantity='N_total', size=10**9) corrm = filter_data(data['violations'], representation='Q', size=10**9) corrp = filter_data(data['violations'], representation='number', size=10**9) ax.plot(corr1['ns'], numpy.log2(corr1['error'] / corr1['ns'] * 2.), color=mplh.color.f.green.main, linestyle='-.', dashes=mplh.dash['-.']) ax.plot(corrm['ns'], numpy.log2(corrm['error'] / corrm['qms'])[:50], color=mplh.color.f.blue.main) ax.plot(corrp['ns'], numpy.log2(corrp['error'] / corrp['qms']), color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) ref_ns = numpy.arange(1, 36) ax.plot(ref_ns, ref_ns / 2. - 20, linestyle=':', dashes=mplh.dash[':'], linewidth=0.5, color='grey') ax.set_xlim((0, 61)) ax.set_ylim((-24, 0)) ax.yaxis.set_ticks(range(-20, 1, 5)) ax.text(40, -21, 'first order') ax.text(40, -10, 'SU(2)-Q') ax.text(5, -3, 'positive-P') ax.text(34, -5, 'reference') fig.text(0.01, 0.92, '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _cooperative(fname, N): if N == 1: data = 'cooperative-N1-J1-21.json' else: data = 'cooperative-N2-J2-25.json' with open(get_path(__file__, data)) as f: n = json.load(f) fig = mplh.figure(width=0.5) ax = fig.add_subplot(111) thetas_scaled = numpy.array(n['thetas']) deltas = numpy.array(n['deltas_mean']) err = numpy.array(n['deltas_err']) ax.fill_between(thetas_scaled, deltas-err, deltas+err, facecolor=mplh.color.f.blue.lightest, interpolate=True, color=mplh.color.f.blue.darkest, linewidth=0) ax.plot( thetas_scaled, deltas_analytic(thetas_scaled / numpy.sqrt(N), N, N), 'k--', dashes=mplh.dash['--']) ax.set_xlim((thetas_scaled[0], thetas_scaled[-1])) ax.set_ylim((-0.05, 0.45 if N == 1 else 0.55)) ax.set_xlabel( "$\\phantom{\\sqrt{2}}$" + "$\\theta" + ("\\sqrt{2}" if N == 2 else "") + "$ (rad)" + "$\\phantom{\\sqrt{2}}$") ax.set_ylabel("$\\Delta$") ax.text(0.3, -0.05 + (0.05 if N == 1 else 0.05 * (0.6 / 0.5)), '$N=1$, $J=1$' if N == 1 else '$N=2$, $J=2$') fig.text(0.01, 0.92, '(a)' if N == 1 else '(b)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _one_comp_gs(fname, N): with open(get_path(__file__, 'one_comp_gs.json'), 'rb') as f: data = json.load(f) zs = numpy.array(data[str(N)]['xs']) / 1e-6 # to um n_z = numpy.array(data[str(N)]['n_x']) * 1e-6 # to um^-1 tf_n_z = numpy.array(data[str(N)]['tf_n_x']) * 1e-6 # to um^-1 fig = mplh.figure() s = fig.add_subplot(111, xlabel='$z$ ($\\mu\\mathrm{m}$)', ylabel='$n_z$ ($\\mu\\mathrm{m}^{-1}$)') s.plot(zs, n_z[0], color=mplh.color.f.blue.main, linestyle='-') s.plot(zs, tf_n_z[0], color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.text( 6 if N == 1000 else 15, 2400 * 0.03 if N == 1000 else 2400, '$N=' + str(N) + '$') s.text( -14 if N == 1000 else -35, 500 * 0.03 if N == 1000 else 500, 'T-F') s.text( -7.5 if N == 1000 else -23, 500 * 0.03 if N == 1000 else 500, 'numerical') if N == 1000: s.set_xlim(-20, 20) s.set_ylim(0, 90) else: s.set_xlim(-50, 50) s.set_ylim(0, 3000) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) fig.text(0.01, 0.92, '(b)' if N == 1000 else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def riedel_rotation(fname): with open(get_path(__file__, 'riedel_rotation.json')) as f: rotation = json.load(f) angles = numpy.array(rotation['angles']) squeezing = numpy.array(rotation['squeezing']) vertices, codes = buildRiedelTomographyPath() riedel_path = path.Path(vertices, codes) #patch = patches.PathPatch(riedel_path, edgecolor=mplh.color.f.blue.main, # facecolor='none', linestyle='dashdot') riedel_path = riedel_path.vertices riedel_path_x = riedel_path[:,0] riedel_path_y = riedel_path[:,1] fig = mplh.figure(width=0.75) subplot = fig.add_subplot(111) #subplot.add_patch(patch) subplot.plot([angles[0], angles[-1]], [0, 0], color='grey', linewidth=0.5, linestyle='-.', dashes=mplh.dash['-.']) subplot.plot(riedel_path_x, riedel_path_y, color=mplh.color.f.blue.main, linestyle='--', dashes=mplh.dash['--']) subplot.plot(angles, numpy.log10(squeezing) * 10, color=mplh.color.f.red.main) subplot.set_xlim(xmin=angles[0], xmax=angles[-1]) subplot.set_ylim(ymin=-13, ymax=20) subplot.xaxis.set_ticks((-90, -45, 0, 45, 90)) subplot.xaxis.set_ticklabels(('$-90$', '$-45$', '$0$', '$45$', '$90$')) subplot.set_xlabel('$\\theta$ (degrees)') subplot.set_ylabel('$N \\Delta \\hat{S}_\\theta^2 / \\langle \\hat{\\mathbf{S}} \\rangle^2$ (dB)') subplot.text(-80, 12, 'Wigner') subplot.text(-45, 16, 'two-mode') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _distribution(fname, distr_type, order): if distr_type == 'Q': data_name = 'ghz_binning_ardehali_2p_Q.pickle' else: data_name = 'ghz_binning_ardehali_2p_number.pickle' with open(get_path(__file__, data_name)) as f: data = pickle.load(f) if order == 1: corrs = data[1][0] zmax = 5.5 else: corrs = data[1][1] zmax = 3.5 data, edges = corrs fig = mplh.figure(width=0.5, aspect=0.7) ax = fig.add_subplot(111, projection='3d') ax.view_init(elev=40., azim=245.) X = (edges[0][1:] + edges[0][:-1]) / 2 Y = (edges[1][1:] + edges[1][:-1]) / 2 # normalize on 1 data = data.astype(numpy.float64) / data.sum() / (X[1] - X[0]) / (Y[1] - Y[0]) * 100 X, Y = numpy.meshgrid(X, Y) ax.contour(X, Y, data.T, cmap=mplh.cm_zeropos, levels=numpy.linspace(0, zmax, 25)) ax.set_zlabel('\n\nprobability ($\\times 10^{-2}$)') if order == 1: ax.set_xlabel('\n\n$\\mathrm{Re}\,\\sigma_1^x$') ax.set_ylabel('\n\n$\\mathrm{Re}\,\\sigma_2^x$') #ax.set_zlabel('\n\n$P_{\\mathrm{' + representation + '}}$, $\\times 10^{-2}$') ax.set_xlim3d(-3.5, 3.5) ax.xaxis.set_ticks(range(-3, 4)) ax.yaxis.set_ticks(range(-3, 4)) else: ax.set_xlabel('\n\n$\\mathrm{Re}\,\\sigma_1^x \\sigma_2^x$') ax.set_ylabel('\n\n$\\mathrm{Re}\,\\sigma_1^y \\sigma_2^y$') #ax.set_zlabel('\n\n$P_{\\mathrm{' + representation + '}}$, $\\times 10^{-2}$') ax.set_xlim3d(-8.5, 6.5) ax.set_ylim3d(-6.5, 8.5) ax.xaxis.set_ticks(range(-8, 8, 2)) ax.yaxis.set_ticks(range(-6, 10, 2)) ax.zaxis.set_ticks([0, 1, 2, 3]) ax.set_zlim3d(0, zmax) # clear background panes ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) #ax.w_xaxis.set_rotate_label(False) #ax.w_yaxis.set_rotate_label(False) fig.text(0.4, 0.88, 'SU(2)-Q' if distr_type == 'Q' else 'positive-P') labels = { ('P', 1): '(a)', ('P', 2): '(b)', ('Q', 1): '(c)', ('Q', 2): '(d)', } fig.text(0.01, 0.92, labels[(distr_type, order)], fontweight='bold') fig.tight_layout(pad=1.3) fig.savefig(fname)
def _squeezing_N_err(fname, coupling): suffix = '_c' if coupling else '_nc' fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='$\\tau / \\tau_c(N)$', ylabel='Relative errors') colors = { 20: mplh.color.f.blue, 200: mplh.color.f.red, 2000: mplh.color.f.green} dashes = { 20: '-', 200: '--', 2000: ':'} for Na in (20, 200, 2000): with open(get_path(__file__, 'single_well_squeezing_wigner_10k_Na' + str(Na) + '.pickle')) as f: wigner = pickle.load(f) tau_wigner = wigner['tau' + suffix] s_wigner = wigner['s_pi2' + suffix] s_wigner_err = wigner['s_pi2' + suffix + '_err'] interaction = (100.4, 80.8, 95.5) if coupling else (100.4, 0., 100.4) s_exact = get_exact_S(tau_wigner, Na, *interaction) s_exact[0] = 1. tau = tau_wigner / tau_wigner[-1] diff = numpy.abs(s_wigner - s_exact) / s_exact err = s_wigner_err / s_exact tau_diff, min_diff, max_diff = mplh.crop_bounds(tau, diff-err, diff+err, (0, 1., 0, 0.16)) s.fill_between(tau_diff, min_diff, max_diff, facecolor=colors[Na].light, linewidth=0, alpha=0.5) s.plot(tau, diff, color=colors[Na].dark, dashes=mplh.dash[dashes[Na]]) s.text( 0.6, 0.135, "interaction on" if coupling else "interaction off") if coupling: s.text(0.12, 0.12, '$N=20$') s.text(0.25, 0.062, '$N=200$') s.text(0.17, 0.03, '$N=2000$') else: s.text(0.1, 0.12, '$N=20$') s.text(0.27, 0.082, '$N=200$') s.text(0.16, 0.01, '$N=2000$') s.set_xlim((0, 1.)) s.set_ylim((0, 0.16)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) fig.text(0.01, 0.92, '(b)' if coupling else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _feshbach_squeezing(fname, losses): with open(get_path(__file__, 'feshbach_squeezing' + ('' if losses else '_no_losses') + '.json')) as f: sq = json.load(f) datasets = [ ('80.0', mplh.color.f.blue, '-', ), ('85.0', mplh.color.f.red, '--'), ('90.0', mplh.color.f.green, ':'), ('95.0', mplh.color.f.yellow, '-.'), ] t_sq = numpy.array(sq['times']) fig = mplh.figure(width=0.5) subplot = fig.add_subplot(111) for a12, color, linestyle in datasets: xi2_sq = numpy.array(sq['xi2_' + a12]) xi2_sq_err = numpy.array(sq['xi2_' + a12 + '_err']) xi2_log = 10 * numpy.log10(xi2_sq) err_down = 10 * numpy.log10(xi2_sq - xi2_sq_err) err_up = 10 * numpy.log10(xi2_sq + xi2_sq_err) t_err, err_down, err_up = mplh.crop_bounds( t_sq, err_down, err_up, (0, 0.1, (-13 if losses else -20), 1)) positive = err_up > err_down #subplot.fill_between( # t_err * 1e3, err_down, err_up, # facecolor=color.lightest, #interpolate=True, # linewidth=0) subplot.plot(t_sq * 1e3, xi2_log, color=color.main, dashes=mplh.dash[linestyle]) subplot.plot([0, 100], [0, 0], color='grey', linewidth=0.5, linestyle='-.', dashes=mplh.dash['-.']) subplot.set_xlim(xmin=0, xmax=100) subplot.set_ylim(ymin=-13 if losses else -20 , ymax=1) subplot.set_xlabel('$T$ (ms)') subplot.set_ylabel('$\\xi^2$ (dB)') subplot.text(75, 1 - 2.5 if losses else 1 - (2.5 / 14. * 21.), '1-2 losses' if losses else 'no losses') if losses: subplot.text(40, -2, '$80.0\,r_B$') subplot.text(70, -8.5, '$85.0\,r_B$') subplot.text(40, -11.0, '$90.0\,r_B$') subplot.text(43, -6.75, '$95.0\,r_B$') else: subplot.text(35, -16.5, '$80.0\,r_B$') subplot.text(70, -15., '$85.0\,r_B$') subplot.text(75, -12., '$90.0\,r_B$') subplot.text(75, -8., '$95.0\,r_B$') fig.text(0.01, 0.92, '(b)' if losses else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def ghz_violations(fname): with open(get_path(__file__, 'ghz_sampling.json')) as f: data = json.load(f) fig = mplh.figure(width=0.5) G = matplotlib.gridspec.GridSpec(1, 2) ax1 = fig.add_subplot(G[0,0]) ax2 = fig.add_subplot(G[0,1]) ax1.set_xlabel('$M$', color='white' ) # need it to make matplotlib create proper spacing fig.text(0.55, 0.04, '$M$') ax1.set_ylabel('$F / F_{\\mathrm{QM}}$') violations = filter_data(data['violations'], representation='Q', size=10**9) violations_p = filter_data(data['violations'], representation='number', size=10**9) ns = violations['ns'] qms = violations['qms'] mean = violations['mean'] / qms err = violations['error'] / qms ns_p = violations_p['ns'] qms_p = violations_p['qms'] mean_p = violations_p['mean'] / qms_p err_p = violations_p['error'] / qms_p cl_ns = numpy.arange(1, 61) cl_qm = [getF_analytical(n, 'F_ardehali' if n % 2 == 0 else 'F_mermin') for n in cl_ns] cl_qm = numpy.array(zip(*cl_qm)[0]) / numpy.array(zip(*cl_qm)[1]) ax1.set_xlim((0, 10.5)) ax1.set_ylim((-0.05, 1.6)) ax2.set_xlim((49.5, 61)) ax2.set_ylim((-0.05, 1.6)) for ax in (ax1, ax2): ax.plot(cl_ns, numpy.ones(60), color='grey', linewidth=0.5, linestyle='--', dashes=mplh.dash['--']) ax.errorbar(ns, mean, yerr=err, color=mplh.color.f.blue.main, linestyle='None', capsize=1.5) ax.plot(cl_ns, cl_qm, color=mplh.color.f.yellow.main, linestyle='-.', dashes=mplh.dash['-.']) #ax1.errorbar(ns_p, mean_p, yerr=err_p, color=mplh.color.f.red.main, linestyle='None', # capsize=1.5) ax1.text(5, 0.37, '\\textsc{lhv}') ax2.text(51, 0.5, 'SU(2)-Q') # hide the spines between ax and ax2 ax1.spines['right'].set_visible(False) ax2.spines['left'].set_visible(False) ax2.yaxis.tick_right() ax1.xaxis.set_ticks([1, 5, 10]) ax2.xaxis.set_ticks([50, 55, 60]) ax2.tick_params(labelright='off') # don't put tick labels at the right side ax1.yaxis.tick_left() # add cut-out lines d = .015 # how big to make the diagonal lines in axes coordinates # arguments to pass plot, just so we don't keep repeating them kwargs = dict(transform=ax2.transAxes, color='k', clip_on=False, linewidth=0.5) ax2.plot((-d,+d),(-d,+d), **kwargs) ax2.plot((-d,+d),(1-d,1+d), **kwargs) kwargs.update(transform=ax1.transAxes, linewidth=0.5) # switch to the bottom axes ax1.plot((1-d,1+d),(1-d,1+d), **kwargs) ax1.plot((1-d,1+d),(-d,+d), **kwargs) #fig.subplots_adjust(wspace=0.001) fig.text(0.01, 0.92, '(a)', fontweight='bold') fig.tight_layout(pad=0.3) #p1 = ax1.get_position() #p2 = ax2.get_position() #dwidth = (p2.x0 - p1.x0 - p1.width) / 2. - 0.01 #ax1.set_position([p1.x0, p1.y0, p1.width + dwidth, p1.height]) #ax2.set_position([p2.x0 - dwidth, p2.y0, p2.width + dwidth, p2.height]) fig.savefig(fname)
def ramsey_short(fname): with open(get_path(__file__, 'experimental/ramsey_experimental.json')) as f: vis_exp = json.load(f) with open(get_path(__file__, 'simulations/ramsey_gpe_no_losses.json')) as f: gpe_nl = json.load(f) with open(get_path(__file__, 'simulations/ramsey_gpe.json')) as f: gpe = json.load(f) with open(get_path(__file__, 'simulations/ramsey_wigner.json')) as f: wig = json.load(f) with open(get_path(__file__, 'simulations/ramsey_wigner_varied_pulse.json')) as f: wig_tech = json.load(f) t_exp = numpy.array(vis_exp['xarray']) v_exp = numpy.array(vis_exp['yarray']) v_exp_err = numpy.array(vis_exp['yerrors']) gpe_t = numpy.array(gpe['times']) gpe_v = numpy.array(gpe['visibility']) gpe_nl_t = numpy.array(gpe_nl['times']) gpe_nl_v = numpy.array(gpe_nl['visibility']) wig_t = numpy.array(wig['times']) wig_v = numpy.array(wig['visibility']) wig_tech_t = numpy.array(wig_tech['times']) wig_tech_v = numpy.array(wig_tech['est_visibility']) gpe_N1 = numpy.array(gpe['N1']) gpe_N2 = numpy.array(gpe['N2']) fig = mplh.figure(width=0.75) s = fig.add_subplot(111, xlabel='$t$ (s)', ylabel='$\\mathcal{V}$') s.errorbar(t_exp, v_exp, yerr=v_exp_err, color='k', linestyle='none', capsize=1.5) # Theoretical limit of visibility s.plot(wig_t, 2 * numpy.sqrt(gpe_N1 * gpe_N2) / (gpe_N1 + gpe_N2), color='grey', linestyle=':', dashes=mplh.dash[':']) # GPE s.plot(gpe_nl_t, gpe_nl_v, color=mplh.color.f.yellow.main, linestyle='-.', dashes=mplh.dash['-.']) s.plot(gpe_t, gpe_v, color=mplh.color.f.green.main, linestyle=':', dashes=mplh.dash[':']) # Pure Wigner s.plot(wig_t, wig_v, color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) # Wigner + technical noise s.plot(wig_tech_t, wig_tech_v, color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.set_xlim((0, 1.3)) s.set_ylim((0, 1.)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) s.plot([0.04, 0.12], [0.23, 0.23], color=mplh.color.f.green.main, linestyle=':', dashes=mplh.dash[':']) s.text(0.14, 0.22, 'mean-field') s.plot([0.04, 0.12], [0.15, 0.15], color=mplh.color.f.red.main, linestyle='--', dashes=mplh.dash['--']) s.text(0.14, 0.14, 'Wigner') s.plot([0.04, 0.12], [0.07, 0.07], color=mplh.color.f.blue.main, linestyle='-', dashes=mplh.dash['-']) s.text(0.14, 0.06, 'Wigner + tech. noise') s.plot([0.6, 0.68], [0.23, 0.23], color=mplh.color.f.yellow.main, linestyle='-.', dashes=mplh.dash['-.']) s.text(0.7, 0.22, 'mean-field, no losses') s.plot([0.6, 0.68], [0.15, 0.15], color='grey', linestyle=':', dashes=mplh.dash[':']) s.text(0.7, 0.14, 'visibility limit') s.errorbar([0.64], [0.07], yerr=[0.02], color='k', linestyle='none', capsize=1.5) s.text(0.7, 0.06, 'experiment') fig.tight_layout(pad=0.3) fig.savefig(fname)
def _squeezing_err(fname, coupling): suffix = '_c' if coupling else '_nc' colors = { '10k': mplh.color.f.blue, '1k': mplh.color.f.red, '100': mplh.color.f.green} dashes = { '10k': '-', '1k': '--'} fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='$\\tau$', ylabel='Relative errors') for tr in ('1k', '10k'): with open(get_path(__file__, 'single_well_squeezing_wigner_' + tr + '_Na200.pickle')) as f: wigner = pickle.load(f) tau_wigner = wigner['tau' + suffix] s_wigner = wigner['s_pi2' + suffix] s_wigner_err = wigner['s_pi2' + suffix + '_err'] interaction = (100.4, 80.8, 95.5) if coupling else (100.4, 0., 100.4) s_exact = get_exact_S(tau_wigner, 200, *interaction) s_exact[0] = 1. diff = numpy.abs(s_wigner - s_exact) / s_exact err = s_wigner_err / s_exact tau_diff, min_diff, max_diff = mplh.crop_bounds( tau_wigner, diff-err, diff+err, (0, (120 if coupling else 20), 0, 0.1)) s.fill_between(tau_diff, min_diff, max_diff, facecolor=colors[tr].light, linewidth=0, alpha=0.5) s.plot(tau_wigner, diff, color=colors[tr].dark, dashes=mplh.dash[dashes[tr]]) s.text( 72 if coupling else 12, 0.085, "interaction on" if coupling else "interaction off") if coupling: s.text(55, 0.06, '$20,000$') s.text(55, 0.052, 'trajectories') s.text(19, 0.02, '$200,000$') s.text(19, 0.012, 'trajectories') else: s.text(13, 0.06, '$20,000$') s.text(13, 0.052, 'trajectories') s.text(4, 0.02, '$200,000$') s.text(4, 0.012, 'trajectories') s.set_xlim((0, 120 if coupling else 20)) s.set_ylim((0, 0.1)) s.set_aspect((5 ** 0.5 - 1) / 2 * mplh.aspect_modifier(s)) fig.text(0.01, 0.92, '(b)' if coupling else '(a)', fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def convergence(wigner, label, fname): with open(get_path(__file__, 'convergence_' + ('wigner' if wigner else 'gpe') + '.json')) as f: results = json.load(f) colors = { "RK46NL": mplh.color.f.blue, "RK4IP": mplh.color.f.red, "CDIP": mplh.color.f.green, "CD": mplh.color.f.yellow} letters = { "RK46NL": "(a)", "RK4IP": "(b)", "CDIP": "(d)", "CD": "(c)"} fig = mplh.figure(width=0.5) s = fig.add_subplot(111, xlabel='steps', ylabel='errors') s.set_xscale('log', basex=10) s.set_yscale('log', basey=10) s.set_xlim(10**3, 10**6) s.set_ylim(10**(-12), 10) s.set_yticks([10**(-i) for i in (0, 2, 4, 6, 8, 10, 12)]) step_nums = [] strong_errors = [] N_errors = [] SZ2_errors = [] int_steps = [int(steps) for steps in results[label]] for steps in sorted(int_steps): result = results[label][str(steps)] step_nums.append(int(steps)) strong_errors.append(result['strong_errors']['psi']) N_errors.append(result['weak_errors']['N']) SZ2_errors.append(result['weak_errors']['SZ2']) step_nums = numpy.array(step_nums) s.plot(step_nums, 1e3 * (1. / step_nums) ** 1, color='grey', dashes=mplh.dash['-.'], linewidth=0.5) s.plot(step_nums, 1e6 * (1. / step_nums) ** 2, color='grey', dashes=mplh.dash['-.'], linewidth=0.5) s.plot(step_nums, 1e12 * (1. / step_nums) ** 4, color='grey', dashes=mplh.dash['-.'], linewidth=0.5) s.plot(step_nums, strong_errors, label=label + ", strong errors", color=colors[label].main, dashes=mplh.dash['-']) s.plot(step_nums, N_errors, label=label + ", N errors", color=colors[label].main, dashes=mplh.dash['--']) s.plot(step_nums, SZ2_errors, label=label + ", Sz^2 errors", color=colors[label].main, dashes=mplh.dash[':']) s.text(5.7*10**5, (1e3 * (1. / step_nums) ** 1)[-1] / 2, '$\\mathup{d}t$', color='grey', fontsize=7) s.text(5.7*10**5, (1e6 * (1. / step_nums) ** 2)[-1] / 2, '$\\mathup{d}t^2$', color='grey', fontsize=7) s.text(5.7*10**5, (1e12 * (1. / step_nums) ** 4)[-1] / 2, '$\\mathup{d}t^4$', color='grey', fontsize=7) s.text(1.3*10**5, 2*10**(-1), "\\abbrev{" + label + "}") s.plot([1.2*10**3, 2.4*10**3], [3*10**(-7), 3*10**(-7)], dashes=mplh.dash['-'], color=colors[label].main) s.text(3*10**3, 10**(-7), '$E_{\\mathbf{\\Psi}}$') s.plot([1.2*10**3, 2.4*10**3], [3*10**(-9), 3*10**(-9)], dashes=mplh.dash['--'], color=colors[label].main) s.text(3*10**3, 10**(-9), '$E_2$') s.plot([1.2*10**3, 2.4*10**3], [3*10**(-11), 3*10**(-11)], dashes=mplh.dash[':'], color=colors[label].main) s.text(3*10**3, 10**(-11), '$E_4$') fig.text(0.01, 0.92, letters[label], fontweight='bold') fig.tight_layout(pad=0.3) fig.savefig(fname)
def riedel_cloud(fname): cloud_xsize = 100.0 cloud_ysize = 250.0 cloud_zsize = 50.0 cloud_zbins = 25 cloud_levels = 20 cloud_ybins = int(float(cloud_zbins) * cloud_ysize / cloud_zsize + 0.5) cloud_xbins = int(cloud_zbins * cloud_xsize / cloud_zsize + 0.5) cloud_ybins = int(cloud_zbins * cloud_ysize / cloud_zsize + 0.5) with open(get_path(__file__, 'riedel_spins.json')) as f: spins = json.load(f) Sx = numpy.array(spins['Sx']) Sy = numpy.array(spins['Sy']) Sz = numpy.array(spins['Sz']) Sx -= Sx.mean() Sy -= Sy.mean() Sz -= Sz.mean() nullfmt = NullFormatter() fig_width = 8 x_d = 0.09 x_dd = 0.03 x_ly = (1.0 - x_d - x_dd * 2) / (1.0 + cloud_zsize / cloud_xsize) x_lx = (1.0 - x_d - x_dd * 2) / (1.0 + cloud_xsize / cloud_zsize) y_d = x_d y_dd = x_dd y_lx = x_lx y_lz = y_lx / cloud_xsize * cloud_zsize aspect = (x_d + x_dd * 2 + x_ly + x_lx) / (y_d + y_dd * 2 + y_lx + y_lz) y_d *= aspect y_dd *= aspect y_lx *= aspect y_lz *= aspect # definitions for the axes rectYZ = [x_d, y_d, x_ly, y_lz] rectXY = [x_d, y_d + y_dd + y_lz, x_ly, y_lx] rectXZ = [x_d + x_dd + x_ly, y_d, x_lx, y_lz] # start with a rectangular Figure fig = mplh.figure(width=1., aspect=1./aspect) axYZ = plt.axes(rectYZ) axXY = plt.axes(rectXY) axXZ = plt.axes(rectXZ) # no labels axXY.xaxis.set_major_formatter(nullfmt) axXZ.yaxis.set_major_formatter(nullfmt) hm, extent, levels = getHeightmap( Sy, Sz, -cloud_ysize, cloud_ysize, -cloud_zsize, cloud_zsize, cloud_ybins, cloud_zbins, cloud_levels) axYZ.contourf(hm, extent=extent, cmap=mplh.cm_zeropos, levels=levels) axYZ.set_xlabel('$S_y$') axYZ.set_ylabel('$S_z$') axYZ.set_xlim(xmin=-cloud_ysize, xmax=cloud_ysize) axYZ.set_ylim(ymin=-cloud_zsize, ymax=cloud_zsize) hm, extent, levels = getHeightmap( Sy, Sx, -cloud_ysize, cloud_ysize, -cloud_xsize, cloud_xsize, cloud_ybins, cloud_xbins, cloud_levels) axXY.contourf(hm, extent=extent, cmap=mplh.cm_zeropos, levels=levels) axXY.set_ylabel('$S_x$') axXY.set_xlim(xmin=-cloud_ysize, xmax=cloud_ysize) axXY.set_ylim(ymin=-cloud_xsize, ymax=cloud_xsize) axXY.yaxis.set_ticks((-80, -40, 0, 40, 80)) hm, extent, levels = getHeightmap( Sx, Sz, -cloud_xsize, cloud_xsize, -cloud_zsize, cloud_zsize, cloud_xbins, cloud_zbins, cloud_levels) axXZ.contourf(hm, extent=extent, cmap=mplh.cm_zeropos, levels=levels) axXZ.set_xlabel('$S_x$') axXZ.set_xlim(xmin=-cloud_xsize, xmax=cloud_xsize) axXZ.set_ylim(ymin=-cloud_zsize, ymax=cloud_zsize) # Plot the arrows on the YZ facet # optimal squeezing angle and corresponding variance, to plot supporting info min_angle = 9.6 / 180 * numpy.pi min_var = numpy.sqrt(25.349280804) # parameters for arrow pointing at the best squeezing arrow_len = 30 arrow1_x = -(min_var + arrow_len) * numpy.sin(min_angle) arrow1_y = (min_var + arrow_len) * numpy.cos(min_angle) arrow1_dx = (arrow_len) * numpy.sin(min_angle) arrow1_dy = -(arrow_len) * numpy.cos(min_angle) arrow_kwds = dict( width=2, head_width=5, linewidth=0.5, shape="full", overhang=0, head_starts_at_zero=False, fill=False, length_includes_head=True, facecolor=mplh.color.f.blue.main) # supporting lines r = numpy.array([0, 1.0]) # axis of the ellipse l1_x = (r * 2 - 1) * min_var * numpy.sin(min_angle) l1_y = (-r * 2 + 1) * min_var * numpy.cos(min_angle) # horizontal line l2_x = r * 150 l2_y = r * 0 # projection direction line l3_x = r * 150 l3_y = r * 150 * numpy.sin(min_angle) # plot pointing arrows axYZ.arrow(arrow1_x, arrow1_y, arrow1_dx, arrow1_dy, **arrow_kwds) axYZ.arrow(-arrow1_x, -arrow1_y, -arrow1_dx, -arrow1_dy, **arrow_kwds) # plot supporting lines #axYZ.plot(l1_x, l1_y, color=mplh.color.f.blue.main, linewidth=0.5) axYZ.plot(l2_x, l2_y, linestyle='--', color='black', linewidth=0.5, dashes=mplh.dash['--']) axYZ.plot(l3_x, l3_y, linestyle='--', color='black', linewidth=0.5, dashes=mplh.dash['--']) # mark angle arc = patches.Arc((0.0, 0.0), 100, 100, theta1=0, theta2=min_angle / numpy.pi * 180, linewidth=0.5, fill=False) axYZ.add_patch(arc) # plot labels axYZ.text(-30, 20, "$\\sigma_\\theta$") axYZ.text(40, 10, "$\\theta$") fig.savefig(fname)