def test_pulse_to_signals(self):
        """Generic test."""

        sched = Schedule(name="Schedule")
        sched += Play(Drag(duration=20, amp=0.5, sigma=4, beta=0.5),
                      DriveChannel(0))
        sched += ShiftPhase(1.0, DriveChannel(0))
        sched += Play(Drag(duration=20, amp=0.5, sigma=4, beta=0.5),
                      DriveChannel(0))
        sched += ShiftFrequency(0.5, DriveChannel(0))
        sched += Play(
            GaussianSquare(duration=200, amp=0.3, sigma=4, width=150),
            DriveChannel(0))

        test_gaussian = GaussianSquare(duration=200,
                                       amp=0.3,
                                       sigma=4,
                                       width=150)
        sched = sched.insert(0, Play(test_gaussian, DriveChannel(1)))

        converter = InstructionToSignals(dt=1, carriers=None)

        signals = converter.get_signals(sched)

        self.assertEqual(len(signals), 2)
        self.assertTrue(isinstance(signals[0], PiecewiseConstant))
        self.assertTrue(isinstance(signals[0], PiecewiseConstant))

        samples = test_gaussian.get_waveform().samples
        self.assertTrue(
            np.allclose(signals[1].samples[0:len(samples)], samples))
    def test_parametric_pulses_with_no_duplicates(self):
        """Test parametric pulses with no duplicates."""
        schedule = Schedule()
        drive_channel = DriveChannel(0)
        schedule += Play(Gaussian(duration=25, sigma=4, amp=0.5j),
                         drive_channel)
        schedule += Play(Gaussian(duration=25, sigma=4, amp=0.49j),
                         drive_channel)
        schedule += Play(
            GaussianSquare(duration=150, amp=0.2, sigma=8, width=140),
            drive_channel)
        schedule += Play(
            GaussianSquare(duration=150, amp=0.19, sigma=8, width=140),
            drive_channel)
        schedule += Play(Constant(duration=150, amp=0.1 + 0.4j), drive_channel)
        schedule += Play(Constant(duration=150, amp=0.1 + 0.41j),
                         drive_channel)
        schedule += Play(Drag(duration=25, amp=0.2 + 0.3j, sigma=7.8, beta=4),
                         drive_channel)
        schedule += Play(Drag(duration=25, amp=0.2 + 0.31j, sigma=7.8, beta=4),
                         drive_channel)

        compressed_schedule = transforms.compress_pulses([schedule])
        original_pulse_ids = get_pulse_ids([schedule])
        compressed_pulse_ids = get_pulse_ids(compressed_schedule)
        self.assertEqual(len(original_pulse_ids), len(compressed_pulse_ids))
Exemple #3
0
    def rescale_cr_inst(instruction: Play,
                        theta: float,
                        sample_mult: int = 16) -> Play:
        """
        Args:
            instruction: The instruction from which to create a new shortened or lengthened pulse.
            theta: desired angle, pi/2 is assumed to be the angle that the pulse in the given
                play instruction implements.
            sample_mult: All pulses must be a multiple of sample_mult.

        Returns:
            qiskit.pulse.Play: The play instruction with the stretched compressed
                GaussianSquare pulse.

        Raises:
            QiskitError: if the pulses are not GaussianSquare.
        """
        pulse_ = instruction.pulse
        if isinstance(pulse_, GaussianSquare):
            amp = pulse_.amp
            width = pulse_.width
            sigma = pulse_.sigma
            n_sigmas = (pulse_.duration - width) / sigma

            # The error function is used because the Gaussian may have chopped tails.
            gaussian_area = abs(amp) * sigma * np.sqrt(
                2 * np.pi) * math.erf(n_sigmas)
            area = gaussian_area + abs(amp) * width

            target_area = abs(theta) / (np.pi / 2.0) * area
            sign = theta / abs(theta)

            if target_area > gaussian_area:
                width = (target_area - gaussian_area) / abs(amp)
                duration = math.ceil(
                    (width + n_sigmas * sigma) / sample_mult) * sample_mult
                return Play(
                    GaussianSquare(amp=sign * amp,
                                   width=width,
                                   sigma=sigma,
                                   duration=duration),
                    channel=instruction.channel,
                )
            else:
                amp_scale = sign * target_area / gaussian_area
                duration = math.ceil(
                    n_sigmas * sigma / sample_mult) * sample_mult
                return Play(
                    GaussianSquare(amp=amp * amp_scale,
                                   width=0,
                                   sigma=sigma,
                                   duration=duration),
                    channel=instruction.channel,
                )
        else:
            raise QiskitError(
                "RZXCalibrationBuilder only stretches/compresses GaussianSquare."
            )
    def rescale_cr_inst(instruction: Play,
                        theta: float,
                        sample_mult: int = 16) -> Play:
        """
        Args:
            instruction: The instruction from which to create a new shortened or lengthened pulse.
            theta: desired angle, pi/2 is assumed to be the angle that the pulse in the given
                play instruction implements.
            sample_mult: All pulses must be a multiple of sample_mult.

        Returns:
            qiskit.pulse.Play: The play instruction with the stretched compressed
                GaussianSquare pulse.

        Raises:
            QiskitError: if rotation angle is not assigned.
        """
        try:
            theta = float(theta)
        except TypeError as ex:
            raise QiskitError("Target rotation angle is not assigned.") from ex

        # This method is called for instructions which are guaranteed to play GaussianSquare pulse
        amp = instruction.pulse.amp
        width = instruction.pulse.width
        sigma = instruction.pulse.sigma
        n_sigmas = (instruction.pulse.duration - width) / sigma

        # The error function is used because the Gaussian may have chopped tails.
        gaussian_area = abs(amp) * sigma * np.sqrt(
            2 * np.pi) * math.erf(n_sigmas)
        area = gaussian_area + abs(amp) * width

        target_area = abs(theta) / (np.pi / 2.0) * area
        sign = np.sign(theta)

        if target_area > gaussian_area:
            width = (target_area - gaussian_area) / abs(amp)
            duration = round(
                (width + n_sigmas * sigma) / sample_mult) * sample_mult
            return Play(
                GaussianSquare(amp=sign * amp,
                               width=width,
                               sigma=sigma,
                               duration=duration),
                channel=instruction.channel,
            )
        else:
            amp_scale = sign * target_area / gaussian_area
            duration = round(n_sigmas * sigma / sample_mult) * sample_mult
            return Play(
                GaussianSquare(amp=amp * amp_scale,
                               width=0,
                               sigma=sigma,
                               duration=duration),
                channel=instruction.channel,
            )
Exemple #5
0
    def test_pass_alive_with_dcx_ish(self):
        """Test if the pass is not terminated by error with direct CX input."""
        cx_sched = Schedule()
        # Fake direct cr
        cx_sched.insert(0,
                        Play(GaussianSquare(800, 0.2, 64, 544),
                             ControlChannel(1)),
                        inplace=True)
        # Fake direct compensation tone
        # Compensation tone doesn't have dedicated pulse class.
        # So it's reported as a waveform now.
        compensation_tone = Waveform(0.1 * np.ones(800, dtype=complex))
        cx_sched.insert(0,
                        Play(compensation_tone, DriveChannel(0)),
                        inplace=True)

        inst_map = InstructionScheduleMap()
        inst_map.add("cx", (1, 0), schedule=cx_sched)

        theta = pi / 3
        rzx_qc = circuit.QuantumCircuit(2)
        rzx_qc.rzx(theta, 1, 0)

        pass_ = RZXCalibrationBuilder(instruction_schedule_map=inst_map)
        with self.assertWarns(UserWarning):
            # User warning that says q0 q1 is invalid
            cal_qc = PassManager(pass_).run(rzx_qc)
        self.assertEqual(cal_qc, rzx_qc)
Exemple #6
0
    def rescale_cr_inst(instruction: Play,
                        theta: float,
                        sample_mult: int = 16,
                        phase_delta: float = 0,
                        amp_increase: float = 0.) -> Play:
        """
        Args:
            instruction: The instruction from which to create a new shortened or lengthened instruction.
            theta: desired angle, pi/2 is assumed to be the angle that
                the schedule with name 'name' in 'sched' implements.
            sample_mult: All pulses must be a multiple of sample_mult.
            phase_delta: Multiplies the pulse samples by np.exp(1.0j*phase_delta).
            amp_increase: Multiplies the amplitude of the samples by (1. + amp_increase).
        """
        if not isinstance(instruction.pulse, GaussianSquare):
            raise QiskitError('Parameteric builder only stretches/compresses '
                              'GaussianSquare.')

        amp = instruction.pulse.amp
        width = instruction.pulse.width
        sigma = instruction.pulse.sigma
        n_sigmas = (instruction.pulse.duration - width) / sigma

        # The error function is used because the Gaussian may have chopped tails.
        gaussian_area = abs(amp) * sigma * np.sqrt(
            2 * np.pi) * math.erf(n_sigmas)
        area = gaussian_area + abs(amp) * width

        target_area = theta / (np.pi / 2.) * area

        if target_area > gaussian_area:
            width = (target_area - gaussian_area) / abs(amp)
            duration = math.ceil(
                (width + n_sigmas * sigma) / sample_mult) * sample_mult
            return Play(GaussianSquare(amp=amp,
                                       width=width,
                                       sigma=sigma,
                                       duration=duration),
                        channel=instruction.channel)
        else:
            amp_scale = target_area / gaussian_area
            duration = math.ceil(n_sigmas * sigma / sample_mult) * sample_mult
            return Play(GaussianSquare(amp=amp * amp_scale,
                                       width=0,
                                       sigma=sigma,
                                       duration=duration),
                        channel=instruction.channel)
 def test_gauss_square_samples(self):
     """Test that the gaussian square samples match the formula."""
     duration = 125
     sigma = 4
     amp = 0.5j
     # formulaic
     times = np.array(range(25), dtype=np.complex_)
     times = times - (25 / 2) + 0.5
     gauss = amp * np.exp(-(times / sigma)**2 / 2)
     # command
     command = GaussianSquare(duration=duration,
                              sigma=sigma,
                              amp=amp,
                              width=100)
     samples = command.get_sample_pulse().samples
     np.testing.assert_almost_equal(samples[50], amp)
     np.testing.assert_almost_equal(samples[100], amp)
     np.testing.assert_almost_equal(samples[:10], gauss[:10])
 def test_param_validation(self):
     """Test that parametric pulse parameters are validated when initialized."""
     with self.assertRaises(PulseError):
         Gaussian(duration=25, sigma=0, amp=0.5j)
     with self.assertRaises(PulseError):
         GaussianSquare(duration=150, amp=0.2, sigma=8, width=160)
     with self.assertRaises(PulseError):
         ConstantPulse(duration=150, amp=0.9 + 0.8j)
     with self.assertRaises(PulseError):
         Drag(duration=25, amp=0.2 + 0.3j, sigma=-7.8, beta=4)
     with self.assertRaises(PulseError):
         Drag(duration=25, amp=0.2 + 0.3j, sigma=7.8, beta=4j)
 def test_parametric_commands_in_sched(self):
     """Test that schedules can be built with parametric commands."""
     sched = Schedule(name='test_parametric')
     sched += Play(Gaussian(duration=25, sigma=4, amp=0.5j), DriveChannel(0))
     sched += Play(Drag(duration=25, amp=0.2+0.3j, sigma=7.8, beta=4), DriveChannel(1))
     sched += Play(Constant(duration=25, amp=1), DriveChannel(2))
     sched_duration = sched.duration
     sched += Play(GaussianSquare(duration=1500, amp=0.2,
                                  sigma=8, width=140),
                   MeasureChannel(0)) << sched_duration
     self.assertEqual(sched.duration, 1525)
     self.assertTrue('sigma' in sched.instructions[0][1].pulse.parameters)
Exemple #10
0
def stretch_sub_sched(sim_pulse_array, factor):
    '''
    Input: A set of pulses happening at the same time (sim = simultaneous) and factor to be stretched by
    Output: A schedule consisting of the stretched pulses
    
    '''
    sub_sched = qiskit.pulse.Schedule()
    for instruc in sim_pulse_array:

        #anything except shift phase
        if (isinstance(instruc, Play)):

            if (isinstance(instruc.pulse, Drag)):
                drag = instruc.pulse
                ## param = {"duration": self.duration, "amp": self.amp, "sigma": self.sigma, "width": self.width}
                param = drag.parameters
                duration = int(factor * param['duration'])
                sigma = (factor * param['sigma'])
                #stretching the drag pulse
                s_pulse = Drag(duration, param['amp'] / factor, sigma,
                               param['beta'])
                channel = instruc.channels[0]
                sub_sched = sub_sched.append(pulse.Play(s_pulse, channel))

            elif (isinstance(instruc.pulse, GaussianSquare)):

                gauss = instruc.pulse
                ## param = {"duration": self.duration, "amp": self.amp, "sigma": self.sigma, "width": self.width}
                param = gauss.parameters
                #print('------Old Param')
                #print(param)
                #stretching the drag pulse
                duration = get_closest_multiple_of_16(factor *
                                                      param['duration'])
                sigma = (factor * param['sigma'])
                width = get_closest_multiple_of_16(factor * param['width'])
                s_pulse = GaussianSquare(duration, param['amp'] / factor,
                                         sigma, width)
                #print('------new Param')
                #print('Duration')
                #print(str(duration) + ' '+ str(param['amp']/factor) + ' '+ str(sigma) + ' '+ str(width))

                #print(param)
                channel = instruc.channels[0]
                sub_sched = sub_sched.append(pulse.Play(s_pulse, channel))

            #if not acquire
            elif (not isinstance(instruc, Acquire)):
                sub_sched += instruc
        else:
            sub_sched += instruc
    return sub_sched
 def test_repr(self):
     """Test the repr methods for parametric pulses."""
     gaussian = Gaussian(duration=25, amp=0.7, sigma=4)
     self.assertEqual(repr(gaussian),
                      'Gaussian(duration=25, amp=(0.7+0j), sigma=4)')
     gaus_square = GaussianSquare(duration=20, sigma=30, amp=1.0, width=3)
     self.assertEqual(
         repr(gaus_square),
         'GaussianSquare(duration=20, amp=(1+0j), sigma=30, width=3)')
     drag = Drag(duration=5, amp=0.5, sigma=7, beta=1)
     self.assertEqual(repr(drag),
                      'Drag(duration=5, amp=(0.5+0j), sigma=7, beta=1)')
     const = ConstantPulse(duration=150, amp=0.1 + 0.4j)
     self.assertEqual(repr(const),
                      'ConstantPulse(duration=150, amp=(0.1+0.4j))')
Exemple #12
0
    def test_measure_with_custom_inst_map(self):
        """Test measure with custom inst_map, meas_map with measure_name."""
        q0_sched = Play(GaussianSquare(1200, 1, 0.4, 1150), MeasureChannel(0))
        q0_sched += Acquire(1200, AcquireChannel(0), MemorySlot(0))
        inst_map = InstructionScheduleMap()
        inst_map.add('my_sched', 0, q0_sched)
        sched = macros.measure(qubits=[0],
                               measure_name='my_sched',
                               inst_map=inst_map,
                               meas_map=[[0]])
        self.assertEqual(sched.instructions, q0_sched.instructions)

        with self.assertRaises(PulseError):
            macros.measure(qubits=[0],
                           measure_name="name",
                           inst_map=inst_map,
                           meas_map=[[0]])
Exemple #13
0
    def test_pulse_amp_typecasted(self):
        """Test if scaled pulse amplitude is complex type."""
        fake_play = Play(
            GaussianSquare(duration=800,
                           amp=0.1,
                           sigma=64,
                           risefall_sigma_ratio=2),
            ControlChannel(0),
        )
        fake_theta = circuit.Parameter("theta")
        assigned_theta = fake_theta.assign(fake_theta, 0.01)

        scaled = RZXCalibrationBuilderNoEcho.rescale_cr_inst(
            instruction=fake_play, theta=assigned_theta)
        scaled_pulse = scaled.pulse

        self.assertIsInstance(scaled_pulse.amp, complex)
Exemple #14
0
 def test_rzx_calibration_builder_duration(self, theta: float):
     """Test that pulse durations are computed correctly."""
     width = 512.00000001
     sigma = 64
     n_sigmas = 4
     duration = width + n_sigmas * sigma
     sample_mult = 16
     amp = 1.0
     pulse = GaussianSquare(duration=duration,
                            amp=amp,
                            sigma=sigma,
                            width=width)
     instruction = Play(pulse, ControlChannel(1))
     scaled = RZXCalibrationBuilder.rescale_cr_inst(instruction,
                                                    theta,
                                                    sample_mult=sample_mult)
     gaussian_area = abs(amp) * sigma * np.sqrt(2 * np.pi) * erf(n_sigmas)
     area = gaussian_area + abs(amp) * width
     target_area = abs(theta) / (np.pi / 2.0) * area
     width = (target_area - gaussian_area) / abs(amp)
     expected_duration = round(
         (width + n_sigmas * sigma) / sample_mult) * sample_mult
     self.assertEqual(scaled.duration, expected_duration)
 def test_gauss_square_extremes(self):
     """Test that the gaussian square pulse can build a gaussian."""
     duration = 125
     sigma = 4
     amp = 0.5j
     gaus_square = GaussianSquare(duration=duration,
                                  sigma=sigma,
                                  amp=amp,
                                  width=0)
     gaus = Gaussian(duration=duration, sigma=sigma, amp=amp)
     np.testing.assert_almost_equal(gaus_square.get_sample_pulse().samples,
                                    gaus.get_sample_pulse().samples)
     gaus_square = GaussianSquare(duration=duration,
                                  sigma=sigma,
                                  amp=amp,
                                  width=121)
     const = ConstantPulse(duration=duration, amp=amp)
     np.testing.assert_almost_equal(
         gaus_square.get_sample_pulse().samples[2:-2],
         const.get_sample_pulse().samples[2:-2])
 def test_construction(self):
     """Test that parametric pulses can be constructed without error."""
     Gaussian(duration=25, sigma=4, amp=0.5j)
     GaussianSquare(duration=150, amp=0.2, sigma=8, width=140)
     ConstantPulse(duration=150, amp=0.1 + 0.4j)
     Drag(duration=25, amp=0.2 + 0.3j, sigma=7.8, beta=4)