Exemplo n.º 1
0
    def test_addition(self):
        """Tests the multiplication of signals."""

        # Test Constant
        const1 = Constant(0.3)
        const2 = Constant(0.5)
        self.assertTrue(isinstance(const1 + const2, Signal))
        self.assertEqual((const1 + const2).value(), 0.8)

        # Test Signal
        signal1 = Signal(3.0, carrier_freq=0.1)
        signal2 = Signal(lambda t: 2.0 * t ** 2, carrier_freq=0.1)
        self.assertTrue(isinstance(const1 + signal1, Signal))
        self.assertTrue(isinstance(signal1 + const1, Signal))
        self.assertTrue(isinstance(signal1 + signal2, Signal))
        self.assertEqual((signal1 + signal2).carrier_freq, 0.0)
        self.assertEqual((signal1 + const1).carrier_freq, 0.0)
        self.assertEqual((signal1 + signal2).envelope_value(), 3.0)
        expected = 21.0 * np.cos(0.1 * 2.0 * np.pi * 3.0)
        self.assertAlmostEqual((signal1 + signal2).envelope_value(3.0), expected, places=8)
        self.assertEqual((signal1 + signal2).value(), 3.0)
        self.assertEqual((signal1 + signal2).value(2.0), 11.0 * np.cos(0.1 * 2.0 * np.pi * 2.0))

        # Test piecewise constant
        dt = 1.0
        samples = Array([0.0, 0.0, 1.0, 2.0, 1.0, 0.0, 0.0])
        carrier_freq = 0.5
        pwc1 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq)

        dt = 1.0
        samples = Array([0.0, 0.0, 1.0, 2.0, 1.0, 0.0, 0.0])
        carrier_freq = 0.1
        pwc2 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq)

        # Test types
        self.assertTrue(isinstance(const1 + pwc1, Signal))
        self.assertTrue(isinstance(signal1 + pwc1, Signal))
        self.assertTrue(isinstance(pwc1 + pwc2, Signal))
        self.assertTrue(isinstance(pwc1 + const1, Signal))
        self.assertTrue(isinstance(pwc1 + signal1, Signal))

        # Test values
        self.assertEqual((pwc1 + pwc2).carrier_freq, 0.0)

        self.assertEqual((pwc1 + pwc2).envelope_value(), 0.0)
        expected = 1.0 * np.cos(0.5 * 2.0 * np.pi * 4.0) + 1.0 * np.cos(0.1 * 2.0 * np.pi * 4.0)
        self.assertAlmostEqual((pwc1 + pwc2).envelope_value(4.0), expected, places=8)
        self.assertEqual((pwc1 + pwc2).value(), 0.0)
        expected = 1.0 * np.cos(0.5 * 2.0 * np.pi * 4.0) + 1.0 * np.cos(0.1 * 2.0 * np.pi * 4.0)
        self.assertAlmostEqual((pwc1 + pwc2).value(4.0), expected, places=8)

        # Test phase
        pwc2 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq, phase=0.5)
        expected = 1.0 * np.cos(0.5 * 2.0 * np.pi * 4.0) + 1.0 * np.cos(
            0.1 * 2.0 * np.pi * 4.0 + 0.5
        )
        self.assertAlmostEqual((pwc1 + pwc2).envelope_value(4.0), expected, places=8)
Exemplo n.º 2
0
    def get_awg_signals(signals: List[PiecewiseConstant],
                        if_modulation: float) -> List[PiecewiseConstant]:
        r"""
        Create signals that correspond to the output ports of an Arbitrary Waveform Generator
        to be used with IQ mixers. For each signal in the list the number of signals is double
        to create the I and Q components. The I and Q signals represent the real and imaginary
        parts, respectively, of

        .. math::
            \Omega(t) e^{i \omega_{if} t}

        where :math:`\Omega` is the complex-valued pulse envelope and :math:`\omega_{if}` is the
        intermediate frequency.

        Args:
            signals: A list of signals for which to create I and Q.
            if_modulation: The intermediate frequency with which the AWG modulates the pulse
                envelopes.

        Returns:
            iq signals: A list of signals which is twice as long as the input list of signals.
                For each input signal get_awg_signals returns two
        """
        new_signals = []

        for sig in signals:
            new_freq = sig.carrier_freq + if_modulation

            samples_i = sig.samples
            samples_q = np.imag(samples_i) - 1.0j * np.real(samples_i)

            sig_i = PiecewiseConstant(
                sig.dt,
                samples_i,
                sig.start_time,
                sig.duration,
                new_freq,
                sig.phase,
                sig.name + "_i",
            )
            sig_q = PiecewiseConstant(
                sig.dt,
                samples_q,
                sig.start_time,
                sig.duration,
                new_freq,
                sig.phase,
                sig.name + "_q",
            )

            new_signals += [sig_i, sig_q]

        return new_signals
Exemplo n.º 3
0
    def test_multiplication(self):
        """Tests the multiplication of signals."""

        # Test Constant
        const1 = Constant(0.3)
        const2 = Constant(0.5)
        self.assertTrue(isinstance(const1 * const2, Signal))
        self.assertEqual((const1 * const2).value(), 0.15)
        self.assertEqual((const1 * const2).value(10.0), 0.15)

        # Test Signal
        signal1 = Signal(3.0, carrier_freq=0.1)
        signal2 = Signal(lambda t: 2.0 * t ** 2, carrier_freq=0.1)
        self.assertTrue(isinstance(const1 * signal1, Signal))
        self.assertTrue(isinstance(signal1 * const1, Signal))
        self.assertTrue(isinstance(signal1 * signal2, Signal))
        self.assertEqual((signal1 * signal2).carrier_freq, 0.2)
        self.assertEqual((signal1 * const1).carrier_freq, 0.1)
        self.assertEqual((signal1 * signal2).envelope_value(), 0.0)
        self.assertEqual((signal1 * signal2).envelope_value(3.0), 3.0 * 18.0)
        self.assertEqual((signal1 * signal2).value(), 0.0)
        self.assertEqual((signal1 * signal2).value(2.0), 24.0 * np.cos(0.2 * 2.0 * np.pi * 2.0))

        # Test piecewise constant
        dt = 1.0
        samples = Array([0.0, 0.0, 1.0, 2.0, 1.0, 0.0, 0.0])
        carrier_freq = 0.5
        pwc1 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq)

        dt = 2.0
        samples = Array([0.0, 0.0, 1.0, 2.0, 1.0, 0.0, 0.0])
        carrier_freq = 0.1
        pwc2 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq)

        # Test types
        self.assertTrue(isinstance(const1 * pwc1, Signal))
        self.assertTrue(isinstance(signal1 * pwc1, Signal))
        self.assertTrue(isinstance(pwc1 * pwc2, Signal))
        self.assertTrue(isinstance(pwc1 * const1, Signal))
        self.assertTrue(isinstance(pwc1 * signal1, Signal))

        # Test values
        self.assertEqual((pwc1 * pwc2).carrier_freq, 0.6)
        self.assertEqual((pwc1 * pwc2).envelope_value(), 0.0)
        self.assertEqual((pwc1 * pwc2).envelope_value(4.0), 1.0)
        self.assertEqual((pwc1 * pwc2).value(), 0.0)
        self.assertEqual((pwc1 * pwc2).value(4.0), 1.0 * np.cos(0.6 * 2.0 * np.pi * 4.0))

        # Test phase
        pwc2 = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq, phase=0.5)
        self.assertEqual((pwc1 * pwc2).value(4.0), 1.0 * np.cos(0.6 * 2.0 * np.pi * 4.0 + 0.5))
Exemplo n.º 4
0
    def test_jit_PiecewiseConstant(self):
        """Verify that jit works through PiecewiseConstant."""

        test_sig = PiecewiseConstant(dt=1.0, samples=Array([1.0, 2.0, 3.0]))

        jit_eval = jit(lambda t: test_sig.value(t).data)

        val1 = jit_eval(0.5)
        expected = 1.0
        self.assertEqual(val1, expected)

        val2 = jit_eval(2.41)
        expected = 3.0
        self.assertEqual(val2, expected)
Exemplo n.º 5
0
    def test_piecewise_constant(self):
        """Test PWC signal."""

        dt = 1.0
        samples = Array([0.0, 0.0, 1.0, 2.0, 1.0, 0.0, 0.0])
        carrier_freq = 0.5
        piecewise_const = PiecewiseConstant(dt=dt, samples=samples, carrier_freq=carrier_freq)

        self.assertEqual(piecewise_const.envelope_value(), 0.0)
        self.assertEqual(piecewise_const.envelope_value(2.0), 1.0)
        self.assertEqual(piecewise_const.value(), 0.0)
        self.assertEqual(piecewise_const.value(3.0), 2.0 * np.cos(0.5 * 2.0 * np.pi * 3.0))

        piecewise_const = PiecewiseConstant(
            dt=dt, samples=samples, carrier_freq=carrier_freq, phase=0.5
        )
        self.assertEqual(piecewise_const.value(3.0), 2.0 * np.cos(0.5 * 2.0 * np.pi * 3.0 + 0.5))
Exemplo n.º 6
0
 def test_func(val):
     sig = PiecewiseConstant(dt=1.0, samples=val * Array([1.0, 2.0, 3.0]))
     return np.real(sig.value(1.5)).data
Exemplo n.º 7
0
    def get_signals(self, schedule: Schedule) -> List[PiecewiseConstant]:
        """
        Args:
            schedule: The schedule to represent in terms of signals.

        Returns:
            a list of piecewise constant signals.

        Raises:
            qiskit.QiskitError: if not enough frequencies supplied
        """

        if self._carriers and len(self._carriers) < len(schedule.channels):
            raise QiskitError("Not enough carrier frequencies supplied.")

        signals, phases, frequency_shifts = {}, {}, {}

        for idx, chan in enumerate(schedule.channels):
            if self._carriers:
                carrier_freq = self._carriers[idx]
            else:
                carrier_freq = 0.0

            phases[chan.name] = 0.0
            frequency_shifts[chan.name] = 0.0
            signals[chan.name] = PiecewiseConstant(samples=[],
                                                   dt=self._dt,
                                                   name=chan.name,
                                                   carrier_freq=carrier_freq)

        for start_sample, inst in schedule.instructions:
            chan = inst.channel.name
            phi = phases[chan]
            freq = frequency_shifts[chan]

            if isinstance(inst, Play):
                start_idx = len(signals[chan].samples)

                # get the instruction samples
                inst_samples = None
                if isinstance(inst.pulse, Waveform):
                    inst_samples = inst.pulse.samples
                else:
                    inst_samples = inst.pulse.get_waveform().samples

                # build sample array to append to signal
                samples = []
                for idx, sample in enumerate(inst_samples):
                    time = self._dt * (idx + start_idx)
                    samples.append(
                        sample *
                        np.exp(2.0j * np.pi * freq * time + 1.0j * phi))

                signals[chan].add_samples(start_sample, samples)

            if isinstance(inst, ShiftPhase):
                phases[chan] += inst.phase

            if isinstance(inst, ShiftFrequency):
                frequency_shifts[chan] += inst.frequency

            if isinstance(inst, SetPhase):
                phases[chan] = inst.phase

            if isinstance(inst, SetFrequency):
                frequency_shifts[
                    chan] = inst.frequency - signals[chan].carrier_freq

        # ensure all signals have the same number of samples
        max_duration = 0
        for sig in signals.values():
            max_duration = max(max_duration, sig.duration)

        for sig in signals.values():
            if sig.duration < max_duration:
                sig.add_samples(
                    start_sample=sig.duration,
                    samples=np.zeros(max_duration - sig.duration,
                                     dtype=complex),
                )

        return list(signals.values())