def generate_rho_optimized(rf='berlin_run/rho_optimize'): """Optimize in Liouville space""" if os.path.isfile(join(rf, 'qubit_pop.dat')): return mkdir(rf) oct_unidir_model(set_observables=False, mcwf=False, lambda_a=1e-2)\ .write_to_runfolder(rf) pc = qdyn_optimize(['--rho', '--debug', '--J_T=J_T_re', rf], _out=join(rf, 'oct.log')) pc.wait() for pulse1 in sorted(glob(join(rf, 'pulse1.oct.dat.0*'))): pulse2 = pulse1.replace('pulse1', 'pulse2') ext = os.path.splitext(pulse1)[1] rf_prop = 'berlin_run/rho_optimize_prop' + ext oct_unidir_model().write_to_runfolder(rf_prop) shutil.copy(pulse1, join(rf_prop, 'pulse1.dat')) shutil.copy(pulse2, join(rf_prop, 'pulse2.dat')) if os.path.isfile(join(rf_prop, 'qubit_pop.dat')): continue print("propagate %s" % rf_prop) pc = qdyn_prop_traj(['--n-trajs=20', '--state-label=10', rf_prop], _out=join(rf, 'prop.log')) pc.wait() print("%.2e" % err_state_to_state(psi10, join(rf_prop, 'psi_final.dat.*')))
def generate_guess(rf='berlin_run/guess'): """Do a quantum trajectory simulation of the guess pulse""" if os.path.isfile(join(rf, 'qubit_pop.dat')): return mkdir(rf) oct_unidir_model().write_to_runfolder(rf) pc = qdyn_prop_traj(['--n-trajs=20', '--state-label=10', rf], _out=join(rf, 'prop.log')) pc.wait()
def main(argv=None): for folder in FOLDERS: rf_orig = join(ORIG_ROOT, folder) rf_new = join(NEW_ROOT, folder) print("%s -> %s" % (rf_orig, rf_new)) gate = Gate2Q.read(join(rf_orig, 'target_gate.dat'), name='O', format='array') mkdir(rf_new) generate_runfolder(rf_orig, rf_new, gate)
def generate_analytical(rf='berlin_run/analytical'): if os.path.isfile(join(rf, 'qubit_pop.dat')): return mkdir(rf) omega1 = QDYN.pulse.Pulse.read("omega1_analytical.dat") omega2 = QDYN.pulse.Pulse.read("omega2_analytical.dat") analytical_model = make_qdyn_model( SYS, Delta, g, kappa, Sym1, Op1, Sym2, Op2, pulse1=omega1, pulse2=omega2, mcwf=True, non_herm=False, states={'': psi10}, set_observables=True) analytical_model.write_to_runfolder(rf) __ = qdyn_prop_traj(['--n-trajs=1', rf], _out=join(rf, 'prop.log'))
def propagate(write_run, config, params, pulse, commands, runfolder): """ Propagate the Transmon system Arguments --------- write_run: callable `write_run(config, params, pulse, runfolder)` writes all the run data to the given runfolder config: str Template string for the config files. param: dict Dictionary of replacements for the config template Keys 'T' and 'nt' will be set automatically based on the first pulse pulse: QDYN.pulse.Pulse object Pulse to be propagated commands: str of list of str Shell commands to do the propagation Returns ------- U: QDYN.gate2q.Gate2Q object Gate resulting from the propagation As a side effect, `params[T]` and `params[nt]` will be set according to the properties of `pulse` """ mkdir(runfolder) U_dat_file = os.path.join(runfolder, 'U.dat') if not PROPAGATE: if os.path.isfile(U_dat_file): U = Gate2Q(file=U_dat_file) return U params['T'] = pulse.T params['nt'] = len(pulse.tgrid) + 1 write_run(config, params, pulse, runfolder) with open(os.path.join(runfolder, 'prop.sh'), 'w') as prop_sh: if type(commands) in [list, tuple]: commands = "\n".join(commands) else: commands = str(commands) prop_sh.write(commands) if os.path.isfile(U_dat_file): os.unlink(U_dat_file) subprocess.call(['bash', 'prop.sh'], cwd=runfolder) U = Gate2Q(file=U_dat_file) return U
def converged_propagate(write_run, config, params, pulse, commands, runfolder, nq_step=1, nc_step=10, limit=0.01): """ Run `propagate` repeatedly, varying the number of qubit levels nq, and cavity levels nc until convergence is reached (the norm of the obtained gate is stable within the given limit) The initial values for nq and nc are taken from params['nq'] and params['ns']. Raises a NotConvergedError if convergence cannot be obtained. Paramters --------- write_run, config, params, pulse, commands, runfolder: see `propagate` nq_step: int step by which to increase nq in each iteration nc_step: int step by which to increase nc in each iteration limit: float convergence is reached as soon as norm(U1 - U2) < limit. Returns ------- U: QDYN.gate2q.Gate2Q object Gate resulting from the propagation As a side effect, params['nq'] and params['nc'] will contain the "converged" values for the number of qubit and cavity levels. Note that params['nq'] will always be increased by at least nq_step, compared to the input value, and equivalently for params['nc']. """ global NQ_MAX_USED global NC_MAX_USED def compare_results(U1, U2): return norm(U1 - U2) < limit mkdir(runfolder) if not PROPAGATE: U_dat_file = os.path.join(runfolder, 'U.dat') if os.path.isfile(U_dat_file): config_params = read_params(os.path.join(runfolder, 'config'), unit='MHz') params['nq'] = config_params['n_qubit'] params['nc'] = config_params['n_cavity'] U = Gate2Q(file=U_dat_file) return U with open(os.path.join(runfolder, 'converged_prop.log'), 'w') as log_fh: log_header_fmt = "# "+"%6s"+"%8s"+"%15s"*2+"\n" log_fh.write(log_header_fmt%("nq", "nc", "Norm(U)", "C(U)")) log_fmt = "%8d"*2+"%15.6e"*2+"\n" U = propagate(write_run, config, params, pulse, commands, runfolder) log_fh.write(log_fmt%(params['nq'], params['nc'], norm(U), U.closest_unitary().concurrence())) converged = False while not converged: # first, we increase the cavity until we reach convergence c_converged = False while not c_converged: params['nc'] += nc_step if (params['nc'] > NC_MAX): raise NotConvergedError next_U = propagate(write_run, config, params, pulse, commands, runfolder) log_fh.write(log_fmt%(params['nq'], params['nc'], norm(next_U), next_U.closest_unitary().concurrence())) c_converged = compare_results(U, next_U) U = next_U params['nc'] -= nc_step # then, we increase the qubit until we reach convergence q_converged = False while not q_converged: params['nq'] += nq_step if (params['nq'] > NQ_MAX): raise NotConvergedError next_U = propagate(write_run, config, params, pulse, commands, runfolder) log_fh.write(log_fmt%(params['nq'], params['nc'], norm(next_U), next_U.closest_unitary().concurrence())) q_converged = compare_results(U, next_U) U = next_U params['nq'] -= nq_step # check that we are really converged with respect to both the qubit # and the cavity. If necessary, we start over. converged = False params['nc'] += nc_step params['nq'] += nq_step next_U = propagate(write_run, config, params, pulse, commands, runfolder) log_fh.write(log_fmt%(params['nq'], params['nc'], norm(next_U), next_U.closest_unitary().concurrence())) converged = compare_results(U, next_U) U = next_U if params['nq'] > NQ_MAX_USED: NQ_MAX_USED = params['nq'] if params['nc'] > NC_MAX_USED: NC_MAX_USED = params['nc'] return U