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)
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
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))
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)
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))
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
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())