コード例 #1
0
    def update_calibrations(self, experiment_data: ExperimentData):
        r"""Update the amplitude of one or several schedules.

        The update rule extracts the rate of the oscillation from the fit to the cosine function.
        Recall that the amplitude is the x-axis in the analysis of the :class:`Rabi` experiment.
        The value of the amplitude is thus the desired rotation-angle divided by the rate of
        the oscillation:

        .. math::

            A_i \to \frac{\theta_i}{\omega}

        where :math:`\theta_i` is the desired rotation angle (e.g. :math:`\pi` and :math:`\pi/2`
        for "x" and "sx" gates, respectively) and :math:`\omega` is the rate of the oscillation.

        Args:
            experiment_data: The experiment data from which to extract the measured Rabi oscillation
            used to set the pulse amplitude.
        """

        result_index = self.experiment_options.result_index
        group = experiment_data.metadata["cal_group"]

        rate = 2 * np.pi * BaseUpdater.get_value(
            experiment_data, self.__outcome__, result_index)

        for angle, param, schedule, prev_amp in experiment_data.metadata[
                "angles_schedules"]:

            value = np.round(angle / rate, decimals=8) * np.exp(
                1.0j * np.angle(prev_amp))

            BaseUpdater.add_parameter_value(self._cals, experiment_data, value,
                                            param, schedule, group)
コード例 #2
0
    def update_calibrations(self, experiment_data: ExperimentData):
        """Update the drag parameter of the pulse in the calibrations."""

        result_index = self.experiment_options.result_index
        group = experiment_data.metadata["cal_group"]
        target_angle = experiment_data.metadata["target_angle"]
        qubits = experiment_data.metadata["physical_qubits"]

        schedule = self._cals.get_schedule(self._sched_name, qubits)

        # Obtain sigma as it is needed for the fine DRAG update rule.
        sigmas = []
        for block in schedule.blocks:
            if isinstance(block, Play) and hasattr(block.pulse, "sigma"):
                sigmas.append(getattr(block.pulse, "sigma"))

        if len(set(sigmas)) != 1:
            raise CalibrationError(
                "Cannot run fine Drag calibration on a schedule with multiple values of sigma."
            )

        if len(sigmas) == 0:
            raise CalibrationError(f"Could not infer sigma from {schedule}.")

        d_theta = BaseUpdater.get_value(experiment_data, "d_theta",
                                        result_index)

        # See the documentation in fine_drag.py for the derivation of this rule.
        d_beta = -np.sqrt(np.pi) * d_theta * sigmas[0] / target_angle**2
        old_beta = experiment_data.metadata["cal_param_value"]
        new_beta = old_beta + d_beta

        BaseUpdater.add_parameter_value(self._cals, experiment_data, new_beta,
                                        self._param_name, schedule, group)
コード例 #3
0
    def update_calibrations(self, experiment_data: ExperimentData):
        r"""Update the qubit frequency based on the measured angle deviation.

        The frequency of the qubit is updated according to

        ..math::

            f \to f - \frac{{\rm d}\theta}{2\pi\tau{\rm d}t}

        Here, :math:`{\rm d}\theta` is the measured angle error from the fit. The duration of
        the single qubit-gate is :math:`\tau` in samples and :math:`{\rm d}t` is the duration
        of a sample. This is also the duration of the time unit ``dt`` of the delay.
        """
        result_index = self.experiment_options.result_index
        group = experiment_data.metadata["cal_group"]
        prev_freq = experiment_data.metadata["cal_param_value"]
        tau = experiment_data.metadata["delay_duration"]
        dt = experiment_data.metadata["dt"]

        d_theta = BaseUpdater.get_value(experiment_data, "d_theta", result_index)
        new_freq = prev_freq - d_theta / (2 * np.pi * tau * dt)

        BaseUpdater.add_parameter_value(
            self._cals, experiment_data, new_freq, self._param_name, self._sched_name, group
        )
コード例 #4
0
    def update_calibrations(self, experiment_data: ExperimentData):
        r"""Update the amplitude of the pulse in the calibrations.

        The update rule of this experiment is

        .. math::

            A \to A \frac{\theta_\text{target}}{\theta_\text{target} + {\rm d}\theta}

        Where :math:`A` is the amplitude of the pulse before the update.

        Args:
            experiment_data: The experiment data from which to extract the measured over/under
                rotation used to adjust the amplitude.
        """
        data = experiment_data.data()

        # No data -> no update
        if len(data) > 0:
            result_index = self.experiment_options.result_index
            group = data[0]["metadata"]["cal_group"]
            target_angle = data[0]["metadata"]["target_angle"]
            prev_amp = data[0]["metadata"]["cal_param_value"]

            d_theta = BaseUpdater.get_value(experiment_data, "d_theta",
                                            result_index)

            BaseUpdater.add_parameter_value(
                self._cals,
                experiment_data,
                prev_amp * target_angle / (target_angle + d_theta),
                self._param_name,
                self._sched_name,
                group,
            )
コード例 #5
0
    def update_calibrations(self, experiment_data: ExperimentData):
        """Update the beta using the value directly reported from the fit.

        See :class:`DragCalAnalysis` for details on the fit.
        """

        new_beta = BaseUpdater.get_value(experiment_data, "beta",
                                         self.experiment_options.result_index)

        BaseUpdater.add_parameter_value(
            self._cals,
            experiment_data,
            new_beta,
            self._param_name,
            self._sched_name,
            self.experiment_options.group,
        )
コード例 #6
0
    def update_calibrations(self, experiment_data: ExperimentData):
        """Update the frequency using the reported frequency less the imparted oscillation."""

        result_index = self.experiment_options.result_index
        osc_freq = experiment_data.metadata["osc_freq"]
        group = experiment_data.metadata["cal_group"]
        old_freq = experiment_data.metadata["cal_param_value"]

        fit_freq = BaseUpdater.get_value(experiment_data, "freq", result_index)
        new_freq = old_freq + fit_freq - osc_freq

        BaseUpdater.add_parameter_value(
            self._cals,
            experiment_data,
            new_freq,
            self._param_name,
            group=group,
        )
コード例 #7
0
    def update_calibrations(self, experiment_data: ExperimentData):
        r"""Update the value of the parameter in the calibrations.

        The parameter that is updated is the phase of the sx pulse. This phase is contained
        in the complex amplitude of the pulse. The update rule for the half angle calibration is
        therefore:

        ..math::

            A \to A \cdot e^{-i{\rm d}\theta_\text{hac}/2}

        where :math:`A` is the complex amplitude of the sx pulse which has an angle which might be
        different from the angle of the x pulse due to the non-linearity in the mixer's skew. The
        angle :math:`{\rm d}\theta_\text{hac}` is the angle deviation measured through the error
        amplifying pulse sequence.

        Args:
            experiment_data: The experiment data from which to extract the measured over/under
                rotation used to adjust the amplitude.
        """

        result_index = self.experiment_options.result_index
        group = experiment_data.metadata["cal_group"]
        prev_amp = experiment_data.metadata["cal_param_value"]

        d_theta = BaseUpdater.get_value(experiment_data, "d_hac", result_index)
        new_amp = prev_amp * np.exp(-1.0j * d_theta / 2)

        BaseUpdater.add_parameter_value(
            self._cals,
            experiment_data,
            new_amp,
            self._param_name,
            self._sched_name,
            group,
        )
コード例 #8
0
    def update_calibrations(self, experiment_data: ExperimentData):
        r"""Update the amplitude of the pulse in the calibrations.

        The update rule of this experiment is

        .. math::

            A \to A \frac{\theta_\text{target}}{\theta_\text{target} + {\rm d}\theta}

        Where :math:`A` is the amplitude of the pulse before the update.

        Args:
            experiment_data: The experiment data from which to extract the measured over/under
                rotation used to adjust the amplitude.
        """

        result_index = self.experiment_options.result_index
        group = experiment_data.metadata["cal_group"]
        target_angle = experiment_data.metadata["target_angle"]
        prev_amp = experiment_data.metadata["cal_param_value"]

        # Protect against cases where the complex amplitude was converted to a list.
        if isinstance(prev_amp, list) and len(prev_amp) == 2:
            prev_amp = prev_amp[0] + 1.0j * prev_amp[1]

        d_theta = BaseUpdater.get_value(experiment_data, "d_theta",
                                        result_index)

        BaseUpdater.add_parameter_value(
            self._cals,
            experiment_data,
            prev_amp * target_angle / (target_angle + d_theta),
            self._param_name,
            self._sched_name,
            group,
        )