Ejemplo n.º 1
0
    def test_quasi_static_noise_monte_carlo(self):
        np.random.seed(0)
        h_ctrl = [
            DenseOperator(np.diag([.5, -.5])),
        ]
        h_drift = [DenseOperator(np.zeros((2, 2)))]

        n_noise_values = 20
        noise_levels = 1e-4 * np.arange(1, n_noise_values + 1)
        actual_noise_levels = np.zeros((n_noise_values, ))
        average_infids = np.zeros((n_noise_values, ))

        for i, std_dev in enumerate(noise_levels):
            ntg = NTGQuasiStatic(standard_deviation=[
                std_dev,
            ],
                                 n_samples_per_trace=1,
                                 n_traces=2000,
                                 sampling_mode='monte_carlo')

            ctrl_amps = 2 * np.pi * np.ones((1, 1)) * 0
            t_slot_comp = SchroedingerSMonteCarlo(h_drift=h_drift,
                                                  h_ctrl=h_ctrl,
                                                  initial_state=DenseOperator(
                                                      np.eye(2)),
                                                  tau=[1],
                                                  h_noise=h_ctrl,
                                                  noise_trace_generator=ntg)
            t_slot_comp.set_optimization_parameters(ctrl_amps)

            quasi_static_infid = OperationNoiseInfidelity(
                solver=t_slot_comp,
                target=DenseOperator(np.eye(2)),
                neglect_systematic_errors=False,
                fidelity_measure='entanglement')
            average_infids[i] = quasi_static_infid.costs() * (2 / 3)
            actual_noise_levels[i] = np.std(ntg.noise_samples)

        self.assertLess(
            np.sum(
                np.abs((np.ones_like(average_infids) - average_infids /
                        (noise_levels**2 / 6)))) / 100, 0.05)
        self.assertLess(
            np.sum(
                np.abs((np.ones_like(average_infids) - average_infids /
                        (actual_noise_levels**2 / 6)))) / 100, 0.05)
Ejemplo n.º 2
0
    def test_quasi_static_noise_deterministic_sampling(self):
        """ The same problem has also been positively tested with two time
        steps. """
        h_ctrl = [
            DenseOperator(np.diag([.5, -.5])),
        ]
        h_drift = [DenseOperator(np.zeros((2, 2)))]

        noise_levels = 1e-4 * np.arange(1, 101)
        actual_noise_levels = np.zeros((100, ))
        average_infids = np.zeros((100, ))

        for i, std_dev in enumerate(noise_levels):
            ntg = NTGQuasiStatic(standard_deviation=[
                std_dev,
            ],
                                 n_samples_per_trace=1,
                                 n_traces=200,
                                 sampling_mode='uncorrelated_deterministic')

            ctrl_amps = 2 * np.pi * np.ones((1, 1))
            t_slot_comp = SchroedingerSMonteCarlo(h_drift=h_drift,
                                                  h_ctrl=h_ctrl,
                                                  initial_state=DenseOperator(
                                                      np.eye(2)),
                                                  tau=[1],
                                                  h_noise=h_ctrl,
                                                  noise_trace_generator=ntg)
            t_slot_comp.set_optimization_parameters(ctrl_amps)

            quasi_static_infid = OperationNoiseInfidelity(
                solver=t_slot_comp,
                target=DenseOperator(np.eye(2)),
                neglect_systematic_errors=True,
                fidelity_measure='entanglement')
            average_infids[i] = quasi_static_infid.costs() * (2 / 3)
            actual_noise_levels[i] = np.std(ntg.noise_samples)

        self.assertLess(
            np.sum(
                np.abs((np.ones_like(average_infids) - average_infids /
                        (noise_levels**2 / 6)))) / 100, 0.05)
        self.assertLess(
            np.sum(
                np.abs((np.ones_like(average_infids) - average_infids /
                        (actual_noise_levels**2 / 6)))) / 100, 1e-5)
Ejemplo n.º 3
0
    def quasi_static_noise(self):

        sigma_z = DenseOperator(np.asarray([[1, 0], [0, -1]]))
        sigma_x = DenseOperator(np.asarray([[0, 1], [1, 0]]))
        h_drift = DenseOperator(np.zeros((2, 2)))

        # reference_frequency = 20e9 * 2 * np.pi
        reference_frequency = 100e6 * 2 * np.pi
        driving_frequency = 1e6 * 2 * np.pi

        # 100 per reference period
        # int(reference_frequency / driving_frequency) to make one driving period
        # 20 driving periods
        n_time_steps = int(35 * reference_frequency / driving_frequency * 20)
        n_noise_traces = 100  # int(10 * 60 * 1e6 / 35)
        evolution_time = 35e-6

        delta_t = evolution_time / n_time_steps

        down = np.asarray([[0], [1]])
        up = np.asarray([[1], [0]])
        x_half = rabi.x_half.data

        projector_left = up.T
        projector_right = up

        def up_amplitude(unitary):
            probability = projector_left @ unitary.data @ projector_right
            return np.abs(probability) ** 2

        ctrl_amps = delta_t * np.arange(1, 1 + n_time_steps)
        ctrl_amps = driving_frequency * np.sin(reference_frequency * ctrl_amps)


        def rabi_driving(transferred_parameters, **_):
            ctrl_amps = delta_t * np.arange(1, 1 + n_time_steps)
            ctrl_amps = 2 * np.sin(reference_frequency * ctrl_amps)
            # times 2 because the rabi frequency is .5 * Amplitude
            ctrl_amps = np.einsum("tc, t->tc", transferred_parameters, ctrl_amps)
            return ctrl_amps


        def rabi_driving_noise(noise_samples, **_):
            ctrl_amps = delta_t * np.arange(1, 1 + n_time_steps)
            ctrl_amps = 2 * np.sin(reference_frequency * ctrl_amps)
            ctrl_amps = np.einsum("sno, t->tno", noise_samples, ctrl_amps)
            return ctrl_amps


        rabi_driving_amp_func = CustomAmpFunc(value_function=rabi_driving,
                                              derivative_function=None)
        id_transfer_func = OversamplingTF(oversampling=n_time_steps)
        id_transfer_func.set_times(np.asarray([evolution_time]))


        ts_comp_unperturbed = SchroedingerSolver(
            h_drift=[reference_frequency * .5 * sigma_z, ] * n_time_steps,
            h_ctrl=[.5 * sigma_x, ],
            initial_state=DenseOperator(np.eye(2)),
            tau=[delta_t, ] * n_time_steps,
            exponential_method='Frechet',

        )

        ts_comp_lindblad = LindbladSolver(
            h_drift=[reference_frequency * .5 * sigma_z, ] * n_time_steps,
            h_ctrl=[.5 * sigma_x, ],
            initial_state=DenseOperator(np.eye(2)),
            tau=[delta_t, ] * n_time_steps,
            exponential_method='Frechet'
        )

        ts_comp_unperturbed.set_optimization_parameters(np.expand_dims(ctrl_amps, 1))


        """
        # unperturbed:
        forward_propagators = ts_comp_unperturbed.forward_propagators
        
        propabilities = np.zeros((n_time_steps, ))
        for j in range(n_time_steps):
            propabilities[j] = up_amplitude(forward_propagators[j])
        
        plt.figure()
        plt.plot(delta_t * np.arange(n_time_steps), propabilities)
        """

        # Tom
        # todo: he seems to assume angular frequencies in his spectrum
        S_01 = 3e8
        S_02 = 3e4
        # S(f) = S_01 / f + S_02 / f^2

        f_min = 1 / 10 / 60  # 1 over 10 minutes
        f_max = 1 / 35e-6

        variance_f = S_01 * (np.log(f_max) - np.log(f_min)) \
            - S_02 * (1 / f_max - 1 / f_min)
        sigma_f = np.sqrt(variance_f)


        """
        # Yoneda
        S_0 = 3.2 * 1e6 * 4 * np.pi * np.pi
        
        f_min = 1e-2
        f_max = 1 / 35e-6
        
        variance_f = S_0 * (np.log(f_max) - np.log(f_min))
        sigma_f = np.sqrt(variance_f)  # 29 kHz
        """
        expected_t2star = np.sqrt(2 / variance_f)

        ntg = NTGQuasiStatic(
            standard_deviation=[sigma_f, ],
            n_samples_per_trace=1,
            n_traces=n_noise_traces,
            always_redraw_samples=False,
            sampling_mode='monte_carlo'
        )


        tslot_comp = SchroedingerSMonteCarlo(
            h_drift=[reference_frequency * .5 * sigma_z, ] * n_time_steps,
            h_ctrl=[.5 * sigma_x, ],
            h_noise=[.5 * sigma_x],
            initial_state=DenseOperator(np.eye(2)),
            tau=[delta_t, ] * n_time_steps,
            noise_trace_generator=ntg,
            exponential_method='Frechet',
            transfer_function=id_transfer_func,
            amplitude_function=rabi_driving_amp_func,
            noise_amplitude_function=rabi_driving_noise
        )

        """
        # for the rotating frame
        delta_rabi = 1.5 / 10 * 1e6
        tslot_comp.set_optimization_parameters(
            (2 * np.pi * delta_rabi) * np.ones((n_time_steps, 1)))
        """
        tslot_comp.set_optimization_parameters(np.asarray([[driving_frequency]]))

        forward_propagators = tslot_comp.forward_propagators_noise

        propabilities = np.zeros((n_noise_traces, n_time_steps))
        for i in range(n_noise_traces):
            for j in range(n_time_steps):
                propabilities[i, j] = up_amplitude(forward_propagators[i][j])

        propabilities = np.mean(propabilities, axis=0)

        """
        def t2star_decay(t, delta_f, t2_star):
            return .5 * np.exp(-(t / t2_star) ** 2) * np.cos(
                2 * np.pi * delta_f * t) + .5
        """


        def t2star_decay(t, sigma_driving):
            return .5 * np.exp(-.5 * (sigma_driving * t) ** 2) * np.cos(driving_frequency * t) + .5


        def t2star_decay_2(t, sigma_driving):
            return .5 * (1 + (sigma_driving ** 2 / driving_frequency * t)) ** -.25 * np.cos(driving_frequency * t) + .5


        def t2star_decay_3(t, sigma_driving, sigma_ref):
            up_prop = np.exp(-.5 * (sigma_driving * t) ** 2)
            up_prop *= (1 + (sigma_ref ** 2 / driving_frequency * t) ** 2) ** -.25
            up_prop *= .5 * np.cos(driving_frequency * t)
            up_prop += .5
            return up_prop


        def t2star_decay_4(t, sigma_driving, sigma_ref, periodicity):
            up_prop = np.exp(-.5 * (sigma_driving * t) ** 2)
            up_prop *= (1 + ((sigma_ref ** 2) / periodicity * t) ** 2) ** -.25
            up_prop *= .5 * np.cos(periodicity * t)
            up_prop += .5
            return up_prop


        def t2star_decay_5(t, sigma_driving, sigma_ref, periodicity, lin_decay):
            up_prop = np.exp(-.5 * (sigma_driving * t) ** 2)
            up_prop *= np.exp(-1 * lin_decay * t)
            up_prop *= (1 + ((sigma_ref ** 2) / periodicity * t) ** 2) ** -.25
            up_prop *= .5 * np.cos(periodicity * t)
            up_prop += .5
            return up_prop


        popt, pcov = scipy.optimize.curve_fit(
            t2star_decay_3,
            xdata=delta_t * np.arange(n_time_steps),
            ydata=propabilities,
            p0=np.asarray([sigma_f, sigma_f])
        )


        popt, pcov = scipy.optimize.curve_fit(
            t2star_decay_5,
            xdata=delta_t * np.arange(n_time_steps),
            ydata=propabilities,
            p0=np.asarray([sigma_f, sigma_f, driving_frequency, sigma_f])
        )

        self.assertLess(np.linalg.norm(
            propabilities - t2star_decay(delta_t * np.arange(n_time_steps),
                           sigma_driving=sigma_f)) / len(propabilities), 1e-3)

        """
Ejemplo n.º 4
0
    def test_relative_gradients_xy(self):
        amp_bound = rabi.rabi_frequency_max / rabi.lin_freq_rel
        np.random.seed(0)
        initial_pulse = amp_bound * (
            2 * np.random.rand(rabi.n_time_samples, 2) - 1)

        ntg_quasi_static = NTGQuasiStatic(
            standard_deviation=[
                rabi.sigma_rabi,
            ],
            n_samples_per_trace=rabi.n_time_samples * rabi.oversampling,
            n_traces=10,
            always_redraw_samples=False,
            sampling_mode='uncorrelated_deterministic')

        tslot = SchroedingerSMonteCarlo(
            h_drift=[
                0 * rabi.h_drift,
            ],
            h_ctrl=rabi.h_ctrl,
            h_noise=[
                rabi.h_drift,
            ],
            noise_trace_generator=ntg_quasi_static,
            initial_state=DenseOperator(np.eye(2)),
            tau=[
                rabi.time_step,
            ] * rabi.n_time_samples,
            is_skew_hermitian=True,
            exponential_method='Frechet',
            transfer_function=rabi.exponential_transfer_function,
            amplitude_function=rabi.lin_amp_func)

        entanglement_infid = OperationInfidelity(
            solver=tslot,
            target=rabi.x_half,
            fidelity_measure='entanglement',
            index=['Entanglement Fidelity QS-Noise XY-Control'])

        tslot_noise = SchroedingerSMonteCarlo(
            h_drift=[
                0 * rabi.h_drift,
            ],
            h_ctrl=rabi.h_ctrl,
            h_noise=[
                rabi.h_drift,
            ],
            noise_trace_generator=ntg_quasi_static,
            initial_state=DenseOperator(np.eye(2)),
            tau=[
                rabi.time_step,
            ] * rabi.n_time_samples,
            is_skew_hermitian=True,
            exponential_method='Frechet',
            transfer_function=rabi.exponential_transfer_function,
            amplitude_function=rabi.lin_amp_func)

        entanglement_infid_qs_noise_xy = OperationNoiseInfidelity(
            solver=tslot_noise,
            target=rabi.x_half,
            fidelity_measure='entanglement',
            index=['Entanglement Fidelity QS-Noise XY-Control'],
            neglect_systematic_errors=True)

        dynamics = Simulator(solvers=[
            tslot,
        ],
                             cost_fktns=[
                                 entanglement_infid,
                             ])

        dynamics_noise = Simulator(solvers=[
            tslot_noise,
        ],
                                   cost_fktns=[entanglement_infid_qs_noise_xy])

        _, rel_grad_deviation_unperturbed = \
            dynamics.compare_numeric_to_analytic_gradient(initial_pulse)
        self.assertLess(rel_grad_deviation_unperturbed, 1e-6)

        _, rel_grad_deviation_qs_noise = \
            dynamics_noise.compare_numeric_to_analytic_gradient(initial_pulse)
        self.assertLess(rel_grad_deviation_qs_noise, 1e-4)
Ejemplo n.º 5
0
    def test_phase_control_gradient(self):
        amp_bound = rabi.rabi_frequency_max / rabi.lin_freq_rel
        phase_bound_upper = 50 / 180 * np.pi
        phase_bound_lower = -50 / 180 * np.pi

        def random_phase_control_pulse(n):
            amp = amp_bound * (2 * np.random.rand(n) - 1)
            phase = (phase_bound_upper - phase_bound_lower) \
                * np.random.rand(n) \
                - (phase_bound_upper - phase_bound_lower) / 2
            return np.concatenate(
                (np.expand_dims(amp, 1), np.expand_dims(phase, 1)), axis=1)

        dynamics_phase_control = Simulator(
            solvers=[rabi.solver_qs_noise_phase_control],
            cost_fktns=[rabi.entanglement_infid_phase_control])

        ntg_quasi_static = NTGQuasiStatic(
            standard_deviation=[
                rabi.sigma_rabi,
            ],
            n_samples_per_trace=rabi.n_time_samples * rabi.oversampling,
            n_traces=10,
            always_redraw_samples=False,
            sampling_mode='uncorrelated_deterministic')

        time_slot_comp_qs_noise_phase_control = SchroedingerSMonteCarlo(
            h_drift=[
                0 * rabi.h_drift,
            ],
            h_ctrl=rabi.h_ctrl,
            h_noise=[
                rabi.h_drift,
            ],
            noise_trace_generator=ntg_quasi_static,
            initial_state=DenseOperator(np.eye(2)),
            tau=[
                rabi.time_step,
            ] * rabi.n_time_samples,
            is_skew_hermitian=True,
            exponential_method='Frechet',
            transfer_function=rabi.identity_transfer_function,
            amplitude_function=rabi.phase_ctrl_amp_func)

        entanglement_infid_qs_noise_phase_control = OperationNoiseInfidelity(
            solver=time_slot_comp_qs_noise_phase_control,
            target=rabi.x_half,
            fidelity_measure='entanglement',
            index=['Entanglement Fidelity QS-Noise Phase Control'],
            neglect_systematic_errors=True)

        dynamics_phase_control_qs_noise = Simulator(
            solvers=[
                time_slot_comp_qs_noise_phase_control,
            ],
            cost_fktns=[
                entanglement_infid_qs_noise_phase_control,
            ])

        np.random.seed(0)
        inital_pulse = random_phase_control_pulse(rabi.n_time_samples)

        _, rel_grad_deviation_unperturbed = dynamics_phase_control.\
            compare_numeric_to_analytic_gradient(inital_pulse)
        self.assertLess(rel_grad_deviation_unperturbed, 2e-6)

        _, rel_grad_deviation_qs_noise = dynamics_phase_control_qs_noise.\
            compare_numeric_to_analytic_gradient(inital_pulse)
        self.assertLess(rel_grad_deviation_qs_noise, 5e-5)
Ejemplo n.º 6
0
# The noise trace generator explicitly simulates noise realizations
ntg_one_over_f_noise = NTGColoredNoise(
    noise_spectral_density=toms_spectral_noise_density,
    dt=(time_step / oversampling),
    n_samples_per_trace=n_time_samples * oversampling,
    n_traces=1000,
    n_noise_operators=1,
    always_redraw_samples=True)

# 6.2 quasi static contribution
# for the remaining quasi static noise contribution, we integrate the spectral
# density from 10^-3 Hz to 1 / (time_step / oversampling)
ntg_quasi_static = NTGQuasiStatic(standard_deviation=[
    sigma_f,
],
                                  n_samples_per_trace=n_time_samples *
                                  oversampling,
                                  n_traces=8,
                                  always_redraw_samples=False,
                                  sampling_mode='uncorrelated_deterministic')

# ##################### 7. Time Slot Computer #################################
# The time slot computer calculates the evolution of the qubit taking into
# account the amplitude and transfer function and also the noise traces if
# required.

# 7.1 xy-control
solver_unperturbed_xy = SchroedingerSolver(
    h_drift=[
        0 * h_drift,
    ],
    h_ctrl=h_ctrl,
Ejemplo n.º 7
0
    def test_quasi_static_noise(self):

        expected_t2star = np.sqrt(2 / variance_f)

        ntg = NTGQuasiStatic(standard_deviation=[
            sigma_f,
        ],
                             n_samples_per_trace=n_time_steps,
                             n_traces=n_noise_traces,
                             always_redraw_samples=False,
                             sampling_mode='uncorrelated_deterministic')

        tslot_comp = SchroedingerSMonteCarlo(h_drift=[
            h_drift,
        ] * n_time_steps,
                                             h_ctrl=[
                                                 .5 * sigma_z,
                                             ],
                                             h_noise=[.5 * sigma_z],
                                             initial_state=DenseOperator(
                                                 np.eye(2)),
                                             tau=[
                                                 delta_t,
                                             ] * n_time_steps,
                                             noise_trace_generator=ntg,
                                             exponential_method='Frechet')

        def up_amplitude(unitary):
            probability = projector_left @ unitary.data @ projector_right
            return np.abs(probability)**2

        tslot_comp.set_optimization_parameters(
            (2 * np.pi * delta_rabi) * np.ones((n_time_steps, 1)))
        forward_propagators = tslot_comp.forward_propagators_noise

        propabilities = np.zeros((n_noise_traces, n_time_steps))
        for i in range(n_noise_traces):
            for j in range(n_time_steps):
                propabilities[i, j] = up_amplitude(forward_propagators[i][j])

        propabilities = np.mean(propabilities, axis=0)

        # plt.figure()
        # plt.plot(delta_t * np.arange(n_time_steps), propabilities, marker='.')

        def t2star_decay(t, delta_f, t2_star):
            return .5 * np.exp(-(t / t2_star)**2) * np.cos(
                2 * np.pi * delta_f * t) + .5

        popt, pcov = scipy.optimize.curve_fit(
            t2star_decay,
            xdata=delta_t * np.arange(n_time_steps),
            ydata=propabilities,
            p0=np.asarray([delta_rabi, expected_t2star]))

        self.assertLess(
            np.linalg.norm(propabilities - t2star_decay(
                delta_t * np.arange(n_time_steps), popt[0], popt[1])) /
            len(propabilities), 1e-3)

        self.assertLess(
            np.abs((expected_t2star - popt[1]) / (expected_t2star + popt[1])),
            1e-2)
        """