def test_damping_after_dephasing(): damping = damping_kraus_map(p=1 - np.exp(-.1)) dephasing = dephasing_kraus_map(p=.5 * (1 - np.exp(-.2))) ks_ref = combine_kraus_maps(damping, dephasing) ks_actual = damping_after_dephasing(10, 10, 1) np.testing.assert_allclose(ks_actual, ks_ref)
def test_damping_after_dephasing(): damping = damping_kraus_map(p=1 - np.exp(-0.1)) dephasing = dephasing_kraus_map(p=0.5 * (1 - np.exp(-0.2))) ks_ref = combine_kraus_maps(damping, dephasing) ks_actual = damping_after_dephasing(20, 40 / 3.0, 2.0) np.testing.assert_allclose(ks_actual, ks_ref)
def test_damping_after_dephasing(): damping = damping_kraus_map() dephasing = dephasing_kraus_map() ks_ref = combine_kraus_maps(damping, dephasing) ks_actual = damping_after_dephasing(10, 10, 1) np.testing.assert_allclose(ks_actual, ks_ref)
def add_damping_dephasing_noise(prog, T1, T2, gate_time): p = Program() p.defgate("noise", np.eye(2)) p.define_noisy_gate("noise", [0], damping_after_dephasing(T1, T2, gate_time)) for elem in prog: p.inst(elem) if isinstance(elem, Measurement): continue # skip measurement p.inst(("noise", 0)) return p
def test_damping_after_dephasing(): gate_time = 1 T1 = 10 T2 = 3 kraus_map = damping_after_dephasing(T1, T2, gate_time) # Density matrix for the |+> state rho = 0.5 * np.ones((2, 2)) # See Eq. 7.144 of Nielsen and Chuang target_rho = [ [1 - 0.5 * np.exp(-gate_time / T1), 0.5 * np.exp(-gate_time / T2)], [0.5 * np.exp(-gate_time / T2), 0.5 * np.exp(-gate_time / T1)], ] noisy_rho = np.zeros((2, 2)) for op in kraus_map: noisy_rho += op @ rho @ (op.T.conj()) np.testing.assert_allclose(noisy_rho, target_rho)
def _modified_decoherence_noise_model( gates: Sequence[Gate], T1: Union[Dict[int, float], float] = 30e-6, T2: Union[Dict[int, float], float] = 30e-6, gate_time_1q: float = 50e-9, gate_time_2q: float = 150e-09, ro_fidelity: Union[Dict[int, float], float] = 0.95, ) -> NoiseModel: """ The default noise parameters - T1 = 30 us - T2 = 30 us - 1q gate time = 50 ns - 2q gate time = 150 ns are currently typical for near-term devices. This function will define new gates and add Kraus noise to these gates. It will translate the input program to use the noisy version of the gates. :param gates: The gates to provide the noise model for. :param T1: The T1 amplitude damping time either globally or in a dictionary indexed by qubit id. By default, this is 30 us. :param T2: The T2 dephasing time either globally or in a dictionary indexed by qubit id. By default, this is also 30 us. :param gate_time_1q: The duration of the one-qubit gates, namely RX(+pi/2) and RX(-pi/2). By default, this is 50 ns. :param gate_time_2q: The duration of the two-qubit gates, namely CZ. By default, this is 150 ns. :param ro_fidelity: The readout assignment fidelity :math:`F = (p(0|0) + p(1|1))/2` either globally or in a dictionary indexed by qubit id. :return: A NoiseModel with the appropriate Kraus operators defined. """ all_qubits = set(sum(([t.index for t in g.qubits] for g in gates), [])) if isinstance(T1, dict): all_qubits.update(T1.keys()) if isinstance(T2, dict): all_qubits.update(T2.keys()) if isinstance(ro_fidelity, dict): all_qubits.update(ro_fidelity.keys()) if not isinstance(T1, dict): T1 = {q: T1 for q in all_qubits} if not isinstance(T2, dict): T2 = {q: T2 for q in all_qubits} if not isinstance(ro_fidelity, dict): ro_fidelity = {q: ro_fidelity for q in all_qubits} kraus_maps = [] for g in gates: targets = tuple(t.index for t in g.qubits) key = (g.name, tuple(g.params)) if g.name in NO_NOISE: if not g.dd: g.gate_time = gate_time_1q continue matrix, _ = get_modified_noisy_gate(g.name, g.params) if len(targets) == 1: if g.gate_time == None: g.gate_time = gate_time_1q noisy_I = damping_after_dephasing(T1.get(targets[0], INFINITY), T2.get(targets[0], INFINITY), g.gate_time) else: if len(targets) != 2: raise ValueError( "Noisy gates on more than 2Q not currently supported") if g.gate_time == None: g.gate_time = gate_time_2q # note this ordering of the tensor factors is necessary due to how the QVM orders # the wavefunction basis noisy_I = tensor_kraus_maps( damping_after_dephasing(T1.get(targets[1], INFINITY), T2.get(targets[1], INFINITY), g.gate_time), damping_after_dephasing(T1.get(targets[0], INFINITY), T2.get(targets[0], INFINITY), g.gate_time)) kraus_maps.append( KrausModel(g.name, tuple(g.params), targets, combine_kraus_maps(noisy_I, [matrix]), 1.0)) aprobs = {} for q, f_ro in ro_fidelity.items(): aprobs[q] = np.array([[f_ro, 1. - f_ro], [1. - f_ro, f_ro]]) return NoiseModel(kraus_maps, aprobs)