コード例 #1
0
    def test_multi_qubit_error_transfer_matrix(self):
        """Test the calculation of the multi-qubit transfer matrix"""
        n_cops = 4
        n_nops = 2
        for d, n_dt in zip(rng.randint(3, 9, 10), rng.randint(1, 11, 10)):
            f, n = np.modf(np.log2(d))
            btype = 'Pauli' if f == 0.0 else 'GGM'
            pulse = testutil.rand_pulse_sequence(d, n_dt, n_cops, n_nops,
                                                 btype)
            omega = util.get_sample_frequencies(pulse, n_samples=51)

            # Assert fidelity is same as computed by infidelity()
            S = 1e-8 / omega**2
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        atol=1e-4)

            S = np.outer(1e-7 * (np.arange(n_nops) + 1),
                         400 / (omega**2 + 400))
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        atol=1e-4)

            S = np.tile(1e-8 / abs(omega)**2,
                        (n_nops, n_nops, 1)).astype(complex)
            S[np.triu_indices(n_nops, 1)].imag = 1e-10 * omega
            S[np.tril_indices(n_nops, -1)].imag = \
                - S[np.triu_indices(n_nops, 1)].imag
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        atol=1e-4)
コード例 #2
0
    def test_caching(self):
        """Make sure calculation works with or without cached intermediates."""

        for d, n_dt in zip(testutil.rng.integers(2, 5, 5),
                           testutil.rng.integers(2, 8, 5)):
            pulse = testutil.rand_pulse_sequence(d, n_dt)
            omega = ff.util.get_sample_frequencies(pulse, n_samples=27)
            spect = 1 / omega

            # Cache control matrix but not intermediates
            pulse.cache_control_matrix(omega, cache_intermediates=False)
            infid_nocache = ff.infidelity(pulse,
                                          spect,
                                          omega,
                                          cache_intermediates=False)
            infid_cache = ff.infidelity(pulse,
                                        spect,
                                        omega,
                                        cache_intermediates=True)

            self.assertArrayAlmostEqual(infid_nocache, infid_cache)

            cm_nocache = ff.gradient.calculate_derivative_of_control_matrix_from_scratch(
                omega,
                pulse.propagators,
                pulse.eigvals,
                pulse.eigvecs,
                pulse.basis,
                pulse.t,
                pulse.dt,
                pulse.n_opers,
                pulse.n_coeffs,
                pulse.c_opers,
                intermediates=dict())

            pulse.cleanup('frequency dependent')
            pulse.cache_control_matrix(omega, cache_intermediates=True)
            cm_cache = ff.gradient.calculate_derivative_of_control_matrix_from_scratch(
                omega,
                pulse.propagators,
                pulse.eigvals,
                pulse.eigvecs,
                pulse.basis,
                pulse.t,
                pulse.dt,
                pulse.n_opers,
                pulse.n_coeffs,
                pulse.c_opers,
                intermediates=pulse._intermediates)

            self.assertArrayAlmostEqual(cm_nocache, cm_cache)
コード例 #3
0
    def test_multi_qubit_error_transfer_matrix(self):
        """Test the calculation of the multi-qubit transfer matrix"""
        n_cops = 4
        n_nops = 2
        for d, n_dt in zip(rng.randint(3, 9, 10), rng.randint(1, 11, 10)):
            f, n = np.modf(np.log2(d))
            btype = 'Pauli' if f == 0.0 else 'GGM'
            pulse = testutil.rand_pulse_sequence(d, n_dt, n_cops, n_nops,
                                                 btype)
            omega = ff.util.get_sample_frequencies(pulse, n_samples=51)

            # Assert fidelity is same as computed by infidelity()
            S = 1e-2 / omega**2
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)

            S = np.outer(1e-2 * (np.arange(n_nops) + 1),
                         400 / (omega**2 + 400))
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)

            S = np.einsum('i,j,o->ijo', 1e-2 * (np.arange(n_nops) + 1),
                          1e-2 * (np.arange(n_nops) + 1),
                          400 / (omega**2 + 400))
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)
コード例 #4
0
    def test_plot_infidelity_convergence(self):
        def spectrum(omega):
            return omega**0

        n, infids = ff.infidelity(simple_pulse, spectrum, {},
                                  test_convergence=True)
        fig, ax = plotting.plot_infidelity_convergence(n, infids)
コード例 #5
0
    def test_infidelity_convergence(self):
        omega = {
            'omega_IR': 0,
            'omega_UV': 2,
            'spacing': 'linear',
            'n_min': 10,
            'n_max': 50,
            'n_points': 4
        }

        def spectrum(omega):
            return omega**0

        simple_pulse = testutil.rand_pulse_sequence(2, 1, 1, 1)
        complicated_pulse = testutil.rand_pulse_sequence(2, 100, 3, 3)

        with self.assertRaises(TypeError):
            n, infids = ff.infidelity(simple_pulse,
                                      spectrum, [],
                                      test_convergence=True)

        with self.assertRaises(TypeError):
            n, infids = ff.infidelity(simple_pulse, [1, 2, 3],
                                      dict(spacing='foobar'),
                                      test_convergence=True)

        with self.assertRaises(ValueError):
            n, infids = ff.infidelity(simple_pulse,
                                      spectrum,
                                      dict(spacing='foobar'),
                                      test_convergence=True)

        # Test with default args
        n, infids = ff.infidelity(simple_pulse,
                                  spectrum, {},
                                  test_convergence=True)

        # Test with non-default args
        identifiers = rng.choice(complicated_pulse.n_oper_identifiers,
                                 rng.randint(1, 4))

        n, infids = ff.infidelity(complicated_pulse,
                                  spectrum,
                                  omega,
                                  test_convergence=True,
                                  n_oper_identifiers=identifiers)
コード例 #6
0
    def test_filter_functions(self):

        # Basis for qubit subspace
        qubit_subspace_basis = ff.Basis(
            [np.pad(b, 1, 'constant') for b in ff.Basis.pauli(2)],
            skip_check=True,
            btype='Pauli')

        c_opers = ff_testutil.subspace_opers
        n_opers = c_opers
        c_coeffs, n_coeffs = ff_testutil.c_coeffs, ff_testutil.n_coeffs
        dt = ff_testutil.dt
        infid_MC = ff_testutil.cnot_infid_fast
        A = ff_testutil.A

        identifiers = ['eps_12', 'eps_23', 'eps_34', 'b_12', 'b_23', 'b_34']
        H_c = list(
            zip(c_opers[:3] + [c_opers[3] + 7 * c_opers[4] - c_opers[5]],
                c_coeffs[:3] + [c_coeffs[3]], identifiers[:4]))
        H_n = list(zip(n_opers[:3], n_coeffs[:3], identifiers[:3]))
        cnot = ff.PulseSequence(H_c, H_n, dt, basis=qubit_subspace_basis)

        T = dt.sum()
        omega = np.logspace(np.log10(1 / T), 2, 125)
        S_t, omega_t = ff.util.symmetrize_spectrum(A[0] / omega**0.0, omega)
        infid, xi = ff.infidelity(cnot,
                                  S_t,
                                  omega_t,
                                  identifiers[:3],
                                  return_smallness=True)
        # infid scaled with d = 6, but we actually have d = 4
        infid *= 1.5
        self.assertLessEqual(np.abs(1 - (infid.sum() / infid_MC[0])), .4)
        self.assertLessEqual(infid.sum(), xi**2 / 4)

        time_slot_comp_closed = SchroedingerSolver(
            h_drift=[OPERATORS['h_drift']] * len(dt),
            h_ctrl=OPERATORS['h_ctrl'],
            initial_state=OPERATORS['initial_state'],
            tau=list(dt),
            calculate_propagator_derivatives=True,
            exponential_method='spectral',
            is_skew_hermitian=True,
            transfer_function=id_tf,
            amplitude_function=exp_amp_func,
            filter_function_h_n=H_n,
            filter_function_basis=qubit_subspace_basis)
        time_slot_comp_closed.set_optimization_parameters(eps.T)

        ff_infid = OperatorFilterFunctionInfidelity(
            solver=time_slot_comp_closed,
            noise_power_spec_density=S_t,
            omega=omega_t)
        print(ff_infid.grad())
        np.testing.assert_array_almost_equal(infid, ff_infid.costs() * 1.5)
コード例 #7
0
    def test_infidelity_cnot(self):
        """Compare infidelity to monte carlo results"""
        c_opers = testutil.subspace_opers
        n_opers = c_opers
        c_coeffs, n_coeffs = testutil.c_coeffs, testutil.n_coeffs
        dt = testutil.dt
        infid_MC = testutil.cnot_infid_fast
        A = testutil.A

        # Basis for qubit subspace
        qubit_subspace_basis = ff.Basis(
            [np.pad(b, 1, 'constant') for b in ff.Basis.pauli(2)],
            skip_check=True,
            btype='Pauli')
        complete_basis = ff.Basis(qubit_subspace_basis,
                                  traceless=False,
                                  btype='Pauli')

        identifiers = ['eps_12', 'eps_23', 'eps_34', 'b_12', 'b_23', 'b_34']
        H_c = list(zip(c_opers, c_coeffs, identifiers))
        H_n = list(zip(n_opers, n_coeffs, identifiers))
        cnot = ff.PulseSequence(H_c, H_n, dt, basis=qubit_subspace_basis)
        cnot_full = ff.PulseSequence(H_c, H_n, dt, basis=complete_basis)

        # Manually set dimension of pulse as the dimension of the computational
        # subspace
        cnot.d = 4
        T = dt.sum()

        for f_min, A, alpha, MC, rtol in zip((1 / T, 1e-2 / T), A, (0.0, 0.7),
                                             infid_MC, (0.04, 0.02)):

            omega = np.geomspace(f_min, 1e2, 250) * 2 * np.pi
            S_t, omega_t = ff.util.symmetrize_spectrum(A / omega**alpha, omega)

            infid, xi = ff.infidelity(cnot,
                                      S_t,
                                      omega_t,
                                      identifiers[:3],
                                      return_smallness=True)

            U = ff.error_transfer_matrix(cnot_full, S_t, omega_t,
                                         identifiers[:3])
            infid_P = np.trace(U[:, :16, :16], axis1=1, axis2=2).real / 4**2

            print(np.abs(1 - (infid.sum() / MC)))
            print(np.abs(1 - (infid_P.sum() / MC)))
            self.assertLessEqual(np.abs(1 - (infid.sum() / MC)), rtol)
            self.assertLessEqual(np.abs(1 - (infid_P.sum() / MC)), rtol)
            self.assertLessEqual(infid.sum(), xi**2 / 4)
コード例 #8
0
    def test_multi_qubit_error_transfer_matrix(self):
        """Test the calculation of the multi-qubit transfer matrix"""
        n_cops = 4
        n_nops = 2
        for d, n_dt in zip(rng.integers(3, 7, 10), rng.integers(1, 6, 10)):
            f, n = np.modf(np.log2(d))
            btype = 'Pauli' if f == 0.0 else 'GGM'
            pulse = testutil.rand_pulse_sequence(d, n_dt, n_cops, n_nops,
                                                 btype)
            omega = util.get_sample_frequencies(pulse, n_samples=51)

            # Single spectrum, different spectra for each noise oper
            spectra = [
                1e-8 / omega**2,
                np.outer(1e-7 * (np.arange(n_nops) + 1),
                         400 / (omega**2 + 400))
            ]
            # Cross-correlated spectra which are complex, real part symmetric and
            # imaginary part antisymmetric
            spec = np.tile(1e-8 / abs(omega)**2,
                           (n_nops, n_nops, 1)).astype(complex)
            spec[np.triu_indices(n_nops, 1)].imag = 1e-10 * omega
            spec[np.tril_indices(
                n_nops, -1)].imag = -spec[np.triu_indices(n_nops, 1)].imag
            spectra.append(spec)

            for S in spectra:
                # Assert fidelity is same as computed by infidelity()
                U = ff.error_transfer_matrix(pulse, S, omega)
                # Calculate U in loop
                Up = ff.error_transfer_matrix(pulse,
                                              S,
                                              omega,
                                              memory_parsimonious=True)
                # Calculate second order
                U2 = ff.error_transfer_matrix(pulse,
                                              S,
                                              omega,
                                              second_order=True)
                I_fidelity = ff.infidelity(pulse, S, omega)
                I_transfer = 1 - np.einsum('...ii', U) / d**2
                I_transfer_2 = 1 - np.einsum('...ii', U2) / d**2
                self.assertArrayAlmostEqual(Up, U)
                self.assertArrayAlmostEqual(I_transfer,
                                            I_fidelity.sum(),
                                            atol=1e-4)
                self.assertArrayAlmostEqual(I_transfer_2,
                                            I_fidelity.sum(),
                                            atol=1e-4)
コード例 #9
0
    def test_infidelity_cnot(self):
        """Compare infidelity to monte carlo results"""
        c_opers = testutil.subspace_opers
        n_opers = c_opers
        c_coeffs, n_coeffs = testutil.c_coeffs, testutil.n_coeffs
        dt = testutil.dt
        infid_MC = testutil.cnot_infid_fast
        A = testutil.A

        # Basis for qubit subspace
        qubit_subspace_basis = ff.Basis(
            [np.pad(b, 1, 'constant') for b in ff.Basis.pauli(2)[1:]],
            skip_check=True,
            btype='Pauli')
        complete_basis = ff.Basis(qubit_subspace_basis,
                                  traceless=False,
                                  btype='Pauli')

        identifiers = ['eps_12', 'eps_23', 'eps_34', 'b_12', 'b_23', 'b_34']
        H_c = list(zip(c_opers, c_coeffs, identifiers))
        H_n = list(zip(n_opers, n_coeffs, identifiers))
        cnot = ff.PulseSequence(H_c, H_n, dt, basis=qubit_subspace_basis)
        cnot_full = ff.PulseSequence(H_c, H_n, dt, basis=complete_basis)

        # Manually set dimension of pulse as the dimension of the computational
        # subspace
        cnot.d = 4
        f_min = 1 / cnot.tau
        omega = np.geomspace(f_min, 1e2, 250)

        for A, alpha, MC in zip(A, (0.0, 0.7), infid_MC):
            S = A / omega**alpha

            infid, xi = ff.infidelity(cnot,
                                      S,
                                      omega,
                                      identifiers[:3],
                                      return_smallness=True)

            K = numeric.calculate_cumulant_function(cnot_full, S, omega,
                                                    identifiers[:3])
            infid_P = -np.trace(K[:, :16, :16], axis1=1, axis2=2).real / 4**2

            self.assertLessEqual(np.abs(1 - (infid.sum() / MC)), 0.10)
            self.assertLessEqual(np.abs(1 - (infid_P.sum() / MC)), 0.10)
            self.assertLessEqual(infid.sum(), xi**2 / 4)
コード例 #10
0
    def test_single_qubit_error_transfer_matrix(self):
        """Test the calculation of the single-qubit transfer matrix"""
        d = 2
        for n_dt in rng.integers(1, 11, 10):
            pulse = testutil.rand_pulse_sequence(d, n_dt, 3, 2, btype='Pauli')
            traceless = rng.integers(2, dtype=bool)
            if not traceless:
                # Test that result correct for finite trace n_oper (edge case)
                pulse.n_opers[0] = np.eye(d) / np.sqrt(d)

            omega = util.get_sample_frequencies(pulse, n_samples=51)
            n_oper_identifiers = pulse.n_oper_identifiers
            traces = pulse.basis.four_element_traces.todense()

            # Single spectrum, different spectra for each noise oper, and
            # Cross-correlated spectra which are complex, real part symmetric and
            # imaginary part antisymmetric
            spectra = [
                1e-8 / omega**2,
                np.outer(1e-6 * np.arange(1, 3), 400 / (omega**2 + 400)),
                np.array([[
                    1e-6 / abs(omega), 1e-8 / abs(omega) + 1j * 1e-8 / omega
                ], [1e-8 / abs(omega) - 1j * 1e-8 / omega, 2e-6 / abs(omega)]])
            ]

            for S in spectra:
                # Assert fidelity is same as computed by infidelity()
                U = ff.error_transfer_matrix(pulse, S, omega)
                # Calculate U in loop
                Up = ff.error_transfer_matrix(pulse,
                                              S,
                                              omega,
                                              memory_parsimonious=True)
                # Calculate on foot (multi-qubit way)
                Gamma = numeric.calculate_decay_amplitudes(
                    pulse, S, omega, n_oper_identifiers)
                Delta = numeric.calculate_frequency_shifts(
                    pulse, S, omega, n_oper_identifiers)
                K = -(np.einsum('...kl,klji->...ij', Gamma, traces) -
                      np.einsum('...kl,kjli->...ij', Gamma, traces) -
                      np.einsum('...kl,kilj->...ij', Gamma, traces) +
                      np.einsum('...kl,kijl->...ij', Gamma, traces)) / 2
                U_onfoot = sla.expm(K.sum(tuple(range(K.ndim - 2))))
                U_from_K = ff.error_transfer_matrix(cumulant_function=K)
                self.assertArrayAlmostEqual(Up, U)
                self.assertArrayAlmostEqual(U, U_onfoot, atol=1e-14)
                self.assertArrayAlmostEqual(U_from_K, U_onfoot)
                if traceless:
                    # Simplified fidelity calculation relies on traceless n_opers
                    I_fidelity = ff.infidelity(pulse, S, omega)
                    I_decayamps = -np.einsum('...ii', K) / d**2
                    I_transfer = 1 - np.einsum('...ii', U) / d**2
                    self.assertArrayAlmostEqual(I_fidelity, I_decayamps)
                    self.assertArrayAlmostEqual(I_transfer,
                                                I_fidelity.sum(),
                                                rtol=1e-4,
                                                atol=1e-10)

                # second order
                K -= (np.einsum('...kl,klji->...ij', Delta, traces) -
                      np.einsum('...kl,lkji->...ij', Delta, traces) -
                      np.einsum('...kl,klij->...ij', Delta, traces) +
                      np.einsum('...kl,lkij->...ij', Delta, traces)) / 2
                U = ff.error_transfer_matrix(pulse,
                                             S,
                                             omega,
                                             second_order=True)
                U_onfoot = sla.expm(K.sum(tuple(range(K.ndim - 2))))
                U_from_K = ff.error_transfer_matrix(cumulant_function=K)
                self.assertArrayAlmostEqual(U, U_onfoot, atol=1e-14)
                self.assertArrayAlmostEqual(U_from_K, U_onfoot)
                if traceless:
                    # Simplified fidelity calculation relies on traceless n_opers
                    I_transfer = 1 - np.einsum('...ii', U) / d**2
                    self.assertArrayAlmostEqual(I_transfer,
                                                I_fidelity.sum(),
                                                rtol=1e-4,
                                                atol=1e-10)
コード例 #11
0
    def test_infidelity(self):
        """Benchmark infidelity results against previous version's results"""
        rng = np.random.default_rng(seed=123456789)

        spectra = [
            lambda S0, omega: S0 * abs(omega)**0,
            lambda S0, omega: S0 / abs(omega)**0.7,
            lambda S0, omega: S0 * np.exp(-abs(omega)),
            # different spectra for different n_opers
            lambda S0, omega: np.array(
                [S0 * abs(omega)**0, S0 / abs(omega)**0.7]),
            # cross-correlated spectra
            lambda S0, omega: np.array([[
                S0 / abs(omega)**0.7, S0 / (1 + omega**2) + 1j * S0 * omega
            ], [S0 / (1 + omega**2) - 1j * S0 * omega, S0 / abs(omega)**0.7]])
        ]

        ref_infids = ([[2.1571674053883583, 2.1235628100639845],
                       [1.7951695420688032, 2.919850951578396],
                       [0.4327173760925169, 0.817672660809546],
                       [2.1571674053883583, 2.919850951578396],
                       [[1.7951695420688032, -1.1595479985471822],
                        [-1.1595479985471822, 2.919850951578396]],
                       [0.8247284959004152, 2.495561429509174],
                       [0.854760904366362, 3.781670732974073],
                       [0.24181791977082442, 1.122626106375816],
                       [0.8247284959004152, 3.781670732974073],
                       [[0.854760904366362, -0.16574972846239408],
                        [-0.16574972846239408, 3.781670732974073]],
                       [2.9464977186365267, 0.8622319594213088],
                       [2.8391133843027525, 0.678843575761492],
                       [0.813728718501677, 0.16950739577216872],
                       [2.9464977186365267, 0.678843575761492],
                       [[2.8391133843027525, 0.2725782717379744],
                        [0.2725782717379744, 0.678843575761492]]])

        count = 0
        for d in (2, 3, 4):
            pulse = testutil.rand_pulse_sequence(d, 10, 2, 3, local_rng=rng)
            pulse.n_oper_identifiers = np.array(['B_0', 'B_2'])

            omega = np.geomspace(0.1, 10, 51)
            S0 = np.abs(rng.standard_normal())
            for spec in spectra:
                S = spec(S0, omega)
                infids = ff.infidelity(pulse,
                                       S,
                                       omega,
                                       n_oper_identifiers=['B_0', 'B_2'])
                self.assertArrayAlmostEqual(infids,
                                            ref_infids[count],
                                            atol=1e-12)
                if S.ndim == 3:
                    # Diagonal of the infidelity matrix should correspond to
                    # uncorrelated terms
                    uncorrelated_infids = ff.infidelity(
                        pulse,
                        S[range(2), range(2)],
                        omega,
                        n_oper_identifiers=['B_0', 'B_2'])
                    self.assertArrayAlmostEqual(np.diag(infids),
                                                uncorrelated_infids)
                    # Infidelity matrix should be hermitian
                    self.assertArrayEqual(infids, infids.conj().T)

                count += 1

        # Check raises
        with self.assertRaises(TypeError):
            # spectrum not callable
            ff.infidelity(pulse, 2, omega, test_convergence=True)

        with self.assertRaises(TypeError):
            # omega not dict
            ff.infidelity(pulse, lambda x: x, 2, test_convergence=True)

        with self.assertRaises(ValueError):
            # omega['spacing'] not in ('linear', 'log')
            ff.infidelity(pulse,
                          lambda x: x, {'spacing': 2},
                          test_convergence=True)

        with self.assertRaises(ValueError):
            # which not total or correlation
            ff.infidelity(pulse, spectra[0](S0, omega), omega, which=2)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, spectra[0](S0, omega)[:10], omega)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[3](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_1', 'B_2'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[4](S0, omega)[:, [0]],
                          omega,
                          n_oper_identifiers=['B_0'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, rng.standard_normal((2, 3, 4, len(omega))),
                          omega)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(testutil.rand_pulse_sequence(2, 3, n_nops=2),
                          rng.standard_normal((3, 2, 2, len(omega))), omega)

        with self.assertRaises(ValueError):
            # S cross-correlated but not hermitian
            ff.infidelity(testutil.rand_pulse_sequence(2, 3, n_nops=2),
                          rng.standard_normal((2, 2, len(omega))), omega)

        with self.assertRaises(ValueError):
            # S 'cross-correlated' but not hermitian
            ff.infidelity(pulse, (1 + 1j) * rng.standard_normal(
                (1, 1, len(omega))), omega)

        with self.assertRaises(NotImplementedError):
            # smallness parameter for correlated noise source
            ff.infidelity(pulse,
                          spectra[4](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_2'],
                          return_smallness=True)
コード例 #12
0
ファイル: test_core.py プロジェクト: 00mjk/filter_functions
    def test_pulse_correlation_filter_function(self):
        """
        Test calculation of pulse correlation filter function and control
        matrix.
        """
        X, Y, Z = util.paulis[1:]
        T = 1
        omega = np.linspace(-2e1, 2e1, 250)
        H_c, H_n, dt = dict(), dict(), dict()
        H_c['X'] = [[X, [np.pi/2/T]]]
        H_n['X'] = [[X, [1]],
                    [Y, [1]],
                    [Z, [1]]]
        dt['X'] = [T]
        H_c['Y'] = [[Y, [np.pi/4/T]]]
        H_n['Y'] = [[X, [1]],
                    [Y, [1]],
                    [Z, [1]]]
        dt['Y'] = [T]
        n_nops = 3

        # Check if an exception is raised if we want to calculate the PC-FF but
        # one pulse has different frequencies
        with self.assertRaises(ValueError):
            pulses = dict()
            for i, key in enumerate(('X', 'Y')):
                pulses[key] = ff.PulseSequence(H_c[key], H_n[key], dt[key])
                pulses[key].cache_filter_function(omega + i)

            ff.concatenate([pulses['X'], pulses['Y']],
                           calc_pulse_correlation_FF=True)

        # Get filter functions at same frequencies
        [pulse.cache_filter_function(omega) for pulse in pulses.values()]

        pulse_1 = pulses['X'] @ pulses['Y']
        pulse_2 = ff.concatenate([pulses['X'], pulses['Y']],
                                 calc_pulse_correlation_FF=True,
                                 which='fidelity')
        pulse_3 = ff.concatenate([pulses['X'], pulses['Y']],
                                 calc_pulse_correlation_FF=True,
                                 which='generalized')

        self.assertTrue(pulse_2.is_cached('control_matrix_pc'))
        self.assertTrue(pulse_2.is_cached('filter_function_pc'))
        self.assertTrue(pulse_3.is_cached('control_matrix_pc'))
        self.assertTrue(pulse_3.is_cached('filter_function_pc_gen'))

        # Check if the filter functions on the diagonals are real
        filter_function = pulse_2.get_pulse_correlation_filter_function()
        diag_1 = np.eye(2, dtype=bool)
        diag_2 = np.eye(3, dtype=bool)
        self.assertTrue(np.isreal(filter_function[diag_1][:, diag_2]).all())

        self.assertEqual(pulse_1, pulse_2)
        self.assertEqual(pulse_2.get_pulse_correlation_filter_function().shape,
                         (2, 2, n_nops, n_nops, len(omega)))
        self.assertArrayAlmostEqual(
            pulse_1.get_filter_function(omega),
            pulse_2.get_pulse_correlation_filter_function().sum((0, 1))
        )
        self.assertArrayAlmostEqual(pulse_1.get_filter_function(omega),
                                    pulse_2._filter_function)

        # Test the behavior of the pulse correlation control matrix
        with self.assertRaises(ValueError):
            # R wrong dimension
            numeric.calculate_pulse_correlation_filter_function(
                pulse_1._control_matrix)

        with self.assertRaises(util.CalculationError):
            # not calculated
            pulse_1.get_pulse_correlation_control_matrix()

        control_matrix_pc = pulse_2.get_pulse_correlation_control_matrix()
        self.assertArrayEqual(
            filter_function,
            numeric.calculate_pulse_correlation_filter_function(
                control_matrix_pc, 'fidelity'
            )
        )

        control_matrix_pc = pulse_3.get_pulse_correlation_control_matrix()
        filter_function = \
            pulse_3.get_pulse_correlation_filter_function(which='fidelity')
        self.assertArrayEqual(
            filter_function,
            numeric.calculate_pulse_correlation_filter_function(
                control_matrix_pc, 'fidelity'
            )
        )

        filter_function = \
            pulse_3.get_pulse_correlation_filter_function(which='generalized')
        self.assertArrayEqual(
            filter_function,
            numeric.calculate_pulse_correlation_filter_function(
                control_matrix_pc, 'generalized'
            )
        )

        # If for some reason filter_function_pc_xy is removed, check if
        # recovered from control_matrix_pc
        pulse_2._filter_function_pc = None
        pulse_3._filter_function_pc_gen = None

        control_matrix_pc = pulse_3.get_pulse_correlation_control_matrix()
        filter_function = \
            pulse_3.get_pulse_correlation_filter_function(which='fidelity')
        self.assertArrayEqual(
            filter_function,
            numeric.calculate_pulse_correlation_filter_function(
                control_matrix_pc, 'fidelity'
            )
        )

        filter_function = \
            pulse_3.get_pulse_correlation_filter_function(which='generalized')
        self.assertArrayEqual(
            filter_function,
            numeric.calculate_pulse_correlation_filter_function(
                control_matrix_pc, 'generalized'
            )
        )

        spectrum = omega**0*1e-2
        with self.assertRaises(util.CalculationError):
            infid_1 = ff.infidelity(pulse_1, spectrum, omega,
                                    which='correlations')

        with self.assertRaises(ValueError):
            infid_1 = ff.infidelity(pulse_1, spectrum, omega, which='foobar')

        for _ in range(10):
            n_nops = rng.randint(1, 4)
            identifiers = sample(['B_0', 'B_1', 'B_2'], n_nops)

            infid_X = ff.infidelity(pulses['X'], spectrum, omega,
                                    which='total',
                                    n_oper_identifiers=identifiers)
            infid_Y = ff.infidelity(pulses['Y'], spectrum, omega,
                                    which='total',
                                    n_oper_identifiers=identifiers)
            infid_1 = ff.infidelity(pulse_1, spectrum, omega, which='total',
                                    n_oper_identifiers=identifiers)
            infid_2 = ff.infidelity(pulse_2, spectrum, omega,
                                    which='correlations',
                                    n_oper_identifiers=identifiers)

            self.assertAlmostEqual(infid_1.sum(), infid_2.sum())
            self.assertArrayAlmostEqual(infid_X, infid_2[0, 0])
            self.assertArrayAlmostEqual(infid_Y, infid_2[1, 1])

        # Test function for correlated noise spectra
        spectrum = np.array([[1e-4/omega**2, 1e-4*np.exp(-omega**2)],
                             [1e-4*np.exp(-omega**2), 1e-4/omega**2]])
        infid_1 = ff.infidelity(pulse_1, spectrum, omega, which='total',
                                n_oper_identifiers=['B_0', 'B_2'])
        infid_2 = ff.infidelity(pulse_2, spectrum, omega, which='correlations',
                                n_oper_identifiers=['B_0', 'B_2'])

        self.assertAlmostEqual(infid_1.sum(), infid_2.sum())
        self.assertArrayAlmostEqual(infid_1, infid_2.sum(axis=(0, 1)))
コード例 #13
0
# %% Run simulation
# We use the 1/f^0.7 spectrum from Dial et al (2013) and a white spectrum
# leading to the same average clifford infidelity


def spectrum(omega, alpha):
    eps0 = 2.7241e-4
    return 4e-11 * (2 * np.pi * 1e-3 / omega)**alpha / eps0**2


alpha = (0.0, 0.7)
# Scale noise such that average clifford infidelity is the same for all pulse types and alpha
clifford_infids = {
    p: {
        a: np.array([
            ff.infidelity(c, spectrum(omega, a), omega) for c in cliffords[p]
        ])
        for a in alpha
    }
    for p in pulse_types
}

noise_scaling_factor = {
    p: {
        a: clifford_infids['optimized'][0.7].sum(1).mean(0) /
        clifford_infids[p][a].sum(1).mean(0)
        for a in alpha
    }
    for p in pulse_types
}
コード例 #14
0
    def test_single_qubit_error_transfer_matrix(self):
        """Test the calculation of the single-qubit transfer matrix"""
        d = 2
        for n_dt in rng.randint(1, 11, 10):
            pulse = testutil.rand_pulse_sequence(d, n_dt, 3, 2, btype='Pauli')
            omega = util.get_sample_frequencies(pulse, n_samples=51)
            n_oper_identifiers = pulse.n_oper_identifiers
            traces = pulse.basis.four_element_traces.todense()

            # Single spectrum
            # Assert fidelity is same as computed by infidelity()
            S = 1e-8 / omega**2
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            # Calculate on foot (multi-qubit way)
            Gamma = numeric.calculate_decay_amplitudes(pulse, S, omega,
                                                       n_oper_identifiers)
            K = -(np.einsum('...kl,klji->...ij', Gamma, traces) -
                  np.einsum('...kl,kjli->...ij', Gamma, traces) -
                  np.einsum('...kl,kilj->...ij', Gamma, traces) +
                  np.einsum('...kl,kijl->...ij', Gamma, traces)) / 2
            U_onfoot = sla.expm(K.sum(0))
            U_from_K = ff.error_transfer_matrix(cumulant_function=K)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_decayamps = -np.einsum('...ii', K) / d**2
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_fidelity, I_decayamps)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        rtol=1e-4)
            self.assertArrayAlmostEqual(U, U_onfoot, atol=1e-14)
            self.assertArrayAlmostEqual(U_from_K, U_onfoot)

            # Different spectra for each noise oper
            S = np.outer(1e-6 * np.arange(1, 3), 400 / (omega**2 + 400))
            U = ff.error_transfer_matrix(pulse, S, omega)
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            Gamma = numeric.calculate_decay_amplitudes(pulse, S, omega,
                                                       n_oper_identifiers)
            K = -(np.einsum('...kl,klji->...ij', Gamma, traces) -
                  np.einsum('...kl,kjli->...ij', Gamma, traces) -
                  np.einsum('...kl,kilj->...ij', Gamma, traces) +
                  np.einsum('...kl,kijl->...ij', Gamma, traces)) / 2
            U_onfoot = sla.expm(K.sum(0))
            U_from_K = ff.error_transfer_matrix(cumulant_function=K)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_decayamps = -np.einsum('...ii', K) / d**2
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_fidelity, I_decayamps)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        rtol=1e-4)
            self.assertArrayAlmostEqual(U, U_onfoot, atol=1e-14)
            self.assertArrayAlmostEqual(U_from_K, U_onfoot)

            # Cross-correlated spectra are complex, real part symmetric and
            # imaginary part antisymmetric
            S = np.array(
                [[1e-6 / abs(omega), 1e-8 / abs(omega) + 1j * 1e-8 / omega],
                 [1e-8 / abs(omega) - 1j * 1e-8 / omega, 2e-6 / abs(omega)]])
            U = ff.error_transfer_matrix(pulse, S, omega)
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            Gamma = numeric.calculate_decay_amplitudes(pulse, S, omega,
                                                       n_oper_identifiers)
            K = -(np.einsum('...kl,klji->...ij', Gamma, traces) -
                  np.einsum('...kl,kjli->...ij', Gamma, traces) -
                  np.einsum('...kl,kilj->...ij', Gamma, traces) +
                  np.einsum('...kl,kijl->...ij', Gamma, traces)) / 2
            U_onfoot = sla.expm(K.sum((0, 1)))
            U_from_K = ff.error_transfer_matrix(cumulant_function=K)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_decayamps = -np.einsum('...ii', K) / d**2
            I_transfer = 1 - np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(Up, U)
            self.assertArrayAlmostEqual(I_fidelity, I_decayamps)
            self.assertArrayAlmostEqual(I_transfer,
                                        I_fidelity.sum(),
                                        rtol=1e-4)
            self.assertArrayAlmostEqual(U, U_onfoot, atol=1e-14)
            self.assertArrayAlmostEqual(U_from_K, U_onfoot)
コード例 #15
0
    def test_infidelity(self):
        """Benchmark infidelity results against previous version's results"""
        rng.seed(123456789)

        spectra = [
            lambda S0, omega: S0 * abs(omega)**0,
            lambda S0, omega: S0 / abs(omega)**0.7,
            lambda S0, omega: S0 * np.exp(-abs(omega)),
            # different spectra for different n_opers
            lambda S0, omega: np.array(
                [S0 * abs(omega)**0, S0 / abs(omega)**0.7]),
            # cross-correlated spectra
            lambda S0, omega: np.array([[
                S0 / abs(omega)**0.7, S0 / (1 + omega**2) + 1j * S0 * omega
            ], [S0 / (1 + omega**2) - 1j * S0 * omega, S0 / abs(omega)**0.7]])
        ]

        ref_infids = ([[0.415494970094, 0.89587362496],
                       [0.493004378474, 0.812378971328],
                       [0.133466914361, 0.197411969384],
                       [0.415494970094, 0.812378971328],
                       [[0.493004378474, 0.435140425045],
                        [0.435140425045, 0.812378971328]],
                       [3.62995021962, 2.938710386281],
                       [2.302617869945, 2.6187737025],
                       [0.506821680978, 0.695495602872],
                       [3.62995021962, 2.6187737025],
                       [[2.302617869945, 0.58515469294],
                        [0.58515469294, 2.6187737025]],
                       [2.822636459567, 1.205901937127],
                       [1.63758822101, 1.236844976323],
                       [0.324175447082, 0.329789052239],
                       [2.822636459567, 1.236844976323],
                       [[1.63758822101, 0.72007826813],
                        [0.72007826813, 1.236844976323]]])

        count = 0
        for d in (2, 3, 4):
            pulse = testutil.rand_pulse_sequence(d, 10, 2, 3)
            pulse.n_oper_identifiers = np.array(['B_0', 'B_2'])

            omega = np.geomspace(0.1, 10, 51)
            S0 = np.abs(rng.standard_normal())
            for spec in spectra:
                S = spec(S0, omega)
                infids = ff.infidelity(pulse,
                                       S,
                                       omega,
                                       n_oper_identifiers=['B_0', 'B_2'])
                self.assertArrayAlmostEqual(infids,
                                            ref_infids[count],
                                            atol=1e-12)
                if S.ndim == 3:
                    # Diagonal of the infidelity matrix should correspond to
                    # uncorrelated terms
                    uncorrelated_infids = ff.infidelity(
                        pulse,
                        S[range(2), range(2)],
                        omega,
                        n_oper_identifiers=['B_0', 'B_2'])
                    self.assertArrayAlmostEqual(np.diag(infids),
                                                uncorrelated_infids)

                    # Infidelity matrix should be hermitian
                    self.assertArrayEqual(infids, infids.conj().T)

                count += 1

        # Check raises
        with self.assertRaises(TypeError):
            # spectrum not callable
            ff.infidelity(pulse, 2, omega, test_convergence=True)

        with self.assertRaises(TypeError):
            # omega not dict
            ff.infidelity(pulse, lambda x: x, 2, test_convergence=True)

        with self.assertRaises(ValueError):
            # omega['spacing'] not in ('linear', 'log')
            ff.infidelity(pulse,
                          lambda x: x, {'spacing': 2},
                          test_convergence=True)

        with self.assertRaises(ValueError):
            # which not total or correlation
            ff.infidelity(pulse, spectra[0](S0, omega), omega, which=2)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, spectra[0](S0, omega)[:10], omega)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[3](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_1', 'B_2'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[4](S0, omega)[:, [0]],
                          omega,
                          n_oper_identifiers=['B_0'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, rng.standard_normal((2, 3, 4, len(omega))),
                          omega)

        with self.assertRaises(NotImplementedError):
            # smallness parameter for correlated noise source
            ff.infidelity(pulse,
                          spectra[4](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_2'],
                          return_smallness=True)
コード例 #16
0
alpha = (0.0, 0.7)
# Scaling factor for the noise so that alpha = 0 and alpha = 0.7 give the same
# average clifford fidelity
noise_scaling_factor = {0.0: 0.4415924985735799, 0.7: 1}

state_infidelities = {}
clifford_infidelities = {}

spectra = {}
for i, a in enumerate(alpha):
    S0 = 4e-11 * (2 * np.pi * 1e-3)**a / eps0**2 * noise_scaling_factor[a]
    spectra[a] = S0 / omega**a

    # Need to calculate with two-sided spectra
    clifford_infidelities[a] = [
        ff.infidelity(C, spectra[a], omega).sum() for C in cliffords
    ]

state_infidelities, exec_times = run_randomized_benchmarking(
    N_G, N_l, m_min, m_max, alpha, spectra, omega)

# %% Plot results
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(8, 3))

fidelities = {a: 1 - infid for a, infid in state_infidelities.items()}
for i, a in enumerate(alpha):

    means = np.mean(fidelities[a], axis=1)
    stds = np.std(fidelities[a], axis=1)

    popt, pcov = optimize.curve_fit(fitfun,
コード例 #17
0
    def test_single_qubit_error_transfer_matrix(self):
        """Test the calculation of the single-qubit transfer matrix"""
        d = 2
        for n_dt in rng.randint(1, 11, 10):
            pulse = testutil.rand_pulse_sequence(d, n_dt, 3, 2, btype='Pauli')
            omega = ff.util.get_sample_frequencies(pulse, n_samples=51)
            n_oper_identifiers = pulse.n_oper_identifiers
            traces = pulse.basis.four_element_traces.todense()

            # Single spectrum
            # Assert fidelity is same as computed by infidelity()
            S = 1e-2 / omega**2
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)

            # Check that _single_qubit_error_transfer_matrix and
            # _multi_qubit_... # give the same
            u_kl = numeric.calculate_error_vector_correlation_functions(
                pulse, S, omega, n_oper_identifiers)
            U_multi = (np.einsum('...kl,klij->...ij', u_kl, traces) / 2 +
                       np.einsum('...kl,klji->...ij', u_kl, traces) / 2 -
                       np.einsum('...kl,kilj->...ij', u_kl, traces))
            self.assertArrayAlmostEqual(U, U_multi, atol=1e-14)

            # Different spectra for each noise oper
            S = np.outer(1e-2 * np.arange(1, 3), 400 / (omega**2 + 400))
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)

            # Check that _single_qubit_error_transfer_matrix and
            # _multi_qubit_... # give the same
            u_kl = numeric.calculate_error_vector_correlation_functions(
                pulse, S, omega, n_oper_identifiers)
            U_multi = (np.einsum('...kl,klij->...ij', u_kl, traces) / 2 +
                       np.einsum('...kl,klji->...ij', u_kl, traces) / 2 -
                       np.einsum('...kl,kilj->...ij', u_kl, traces))
            self.assertArrayAlmostEqual(U, U_multi, atol=1e-14)

            # Cross-correlated spectra
            S = np.einsum('i,j,o->ijo',
                          1e-2 * np.arange(1, 3),
                          1e-2 * np.arange(1, 3),
                          400 / (omega**2 + 400),
                          dtype=complex)
            # Cross spectra are complex
            S[0, 1] *= 1 + 1j
            S[1, 0] *= 1 - 1j
            U = ff.error_transfer_matrix(pulse, S, omega)
            # Calculate U in loop
            Up = ff.error_transfer_matrix(pulse,
                                          S,
                                          omega,
                                          memory_parsimonious=True)
            self.assertArrayAlmostEqual(Up, U)
            I_fidelity = ff.infidelity(pulse, S, omega)
            I_transfer = np.einsum('...ii', U) / d**2
            self.assertArrayAlmostEqual(I_transfer, I_fidelity)

            # Check that _single_qubit_error_transfer_matrix and
            # _multi_qubit_... # give the same
            u_kl = numeric.calculate_error_vector_correlation_functions(
                pulse, S, omega, n_oper_identifiers)
            U_multi = np.zeros_like(U)
            U_multi = (np.einsum('...kl,klij->...ij', u_kl, traces) / 2 +
                       np.einsum('...kl,klji->...ij', u_kl, traces) / 2 -
                       np.einsum('...kl,kilj->...ij', u_kl, traces))
            self.assertArrayAlmostEqual(U, U_multi, atol=1e-16)
コード例 #18
0
    def test_infidelity(self):
        """Benchmark infidelity results against previous version's results"""
        rng.seed(123456789)

        spectra = [
            lambda S0, omega: S0 * omega**0,
            lambda S0, omega: S0 / omega**0.7,
            lambda S0, omega: S0 * np.exp(-omega),
            # different spectra for different n_opers
            lambda S0, omega: np.array([S0 * omega**0, S0 / omega**0.7]),
            # cross-correlated spectra
            lambda S0, omega: np.array([[
                S0 / omega**0.7, (1 + 1j) * S0 * np.exp(-omega)
            ], [(1 - 1j) * S0 * np.exp(-omega), S0 / omega**0.7]])
        ]

        ref_infids = ([0.448468950307,
                       0.941871479562], [0.65826575772, 1.042914346335],
                      [0.163303005479,
                       0.239032549377], [0.448468950307, 1.042914346335],
                      [[0.65826575772, 0.069510589685 + 0.069510589685j],
                       [0.069510589685 - 0.069510589685j,
                        1.042914346335]], [3.687399348243, 3.034914820757],
                      [2.590545568435,
                       3.10093804628], [0.55880380219, 0.782544974968
                                        ], [3.687399348243, 3.10093804628],
                      [[2.590545568435, -0.114514760108 - 0.114514760108j],
                       [-0.114514760108 + 0.114514760108j,
                        3.10093804628]], [2.864567451344, 1.270260393902], [
                            1.847740998731, 1.559401345443
                        ], [0.362116177417,
                            0.388022992097], [2.864567451344, 1.559401345443],
                      [[1.847740998731, 0.088373663409 + 0.088373663409j],
                       [0.088373663409 - 0.088373663409j, 1.559401345443]])

        count = 0
        for d in (2, 3, 4):
            pulse = testutil.rand_pulse_sequence(d, 10, 2, 3)
            pulse.n_oper_identifiers = np.array(['B_0', 'B_2'])

            omega = np.geomspace(0.1, 10, 51)
            S0 = np.abs(rng.standard_normal())
            for spec in spectra:
                S, omega_t = ff.util.symmetrize_spectrum(
                    spec(S0, omega), omega)
                infids = ff.infidelity(pulse,
                                       S,
                                       omega_t,
                                       n_oper_identifiers=['B_0', 'B_2'])
                self.assertArrayAlmostEqual(infids,
                                            ref_infids[count],
                                            atol=1e-12)
                if S.ndim == 3:
                    # Diagonal of the infidelity matrix should correspond to
                    # uncorrelated terms
                    uncorrelated_infids = ff.infidelity(
                        pulse,
                        S[range(2), range(2)],
                        omega_t,
                        n_oper_identifiers=['B_0', 'B_2'])
                    self.assertArrayAlmostEqual(np.diag(infids),
                                                uncorrelated_infids)

                    # Infidelity matrix should be hermitian
                    self.assertArrayEqual(infids, infids.conj().T)

                count += 1

        # Check raises
        with self.assertRaises(TypeError):
            # spectrum not callable
            ff.infidelity(pulse, 2, omega_t, test_convergence=True)

        with self.assertRaises(TypeError):
            # omega not dict
            ff.infidelity(pulse, lambda x: x, 2, test_convergence=True)

        with self.assertRaises(ValueError):
            # omega['spacing'] not in ('linear', 'log')
            ff.infidelity(pulse,
                          lambda x: x, {'spacing': 2},
                          test_convergence=True)

        with self.assertRaises(ValueError):
            # which not total or correlation
            ff.infidelity(pulse, spectra[0](S0, omega_t), omega, which=2)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, spectra[0](S0, omega_t)[:10], omega)

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[3](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_1', 'B_2'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse,
                          spectra[4](S0, omega)[:, [0]],
                          omega,
                          n_oper_identifiers=['B_0'])

        with self.assertRaises(ValueError):
            # S wrong dimensions
            ff.infidelity(pulse, rng.standard_normal((2, 3, 4, len(omega))),
                          omega)

        with self.assertRaises(NotImplementedError):
            # smallness parameter for correlated noise source
            ff.infidelity(pulse,
                          spectra[4](S0, omega),
                          omega,
                          n_oper_identifiers=['B_0', 'B_2'],
                          return_smallness=True)
コード例 #19
0
eps0 = 2.7241e-4
# Scaling factor for the noise so that alpha = 0 and alpha = 0.7 have the same
# power
noise_scaling_factor = {0.0: 0.4415924985735799, 0.7: 1}

state_infidelities = {}
clifford_infidelities = {}

for i, alpha in enumerate((0.0, 0.7)):
    S0 = 1e-13 * (2 * np.pi *
                  1e-3)**alpha / eps0**2 * noise_scaling_factor[alpha]
    S = S0 / omega**alpha

    # Need to calculate with two-sided spectra
    clifford_infidelities[alpha] = [
        ff.infidelity(C, *util.symmetrize_spectrum(S, omega)).sum()
        for C in cliffords
    ]

    print('=============================================')
    print(f'\t\talpha = {alpha}')
    print('=============================================')
    state_infidelities[alpha], exec_times = run_randomized_benchmarking(
        N_G, N_l, m_min, m_max, omega)

# %% Plot results
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(8, 3))

fidelities = {alpha: 1 - infid for alpha, infid in state_infidelities.items()}
for i, alpha in enumerate((0.0, 0.7)):