def test_get_serialization_data(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex(DeprecationWarning, "deprecated", msg="SequencePT does not issue warning for old serialization routines."): dummy_pt = DummyPulseTemplate(defined_channels={'foo'}, measurement_names={'meas'}, parameter_names={'hugo', 'herbert', 'ilse'}) mpt = MappingPulseTemplate( template=dummy_pt, parameter_mapping={'hugo': Expression('2*k+c'), 'herbert': Expression('c-1.5'), 'ilse': Expression('ilse')}, measurement_mapping={'meas': 'seam'}, channel_mapping={'foo': 'default_channel'}, parameter_constraints=[str(ParameterConstraint('c > 0'))] ) serializer = DummySerializer() expected_data = { 'template': serializer.dictify(dummy_pt), 'parameter_mapping': {'hugo': str(Expression('2*k+c')), 'herbert': str(Expression('c-1.5')), 'ilse': str(Expression('ilse'))}, 'measurement_mapping': {'meas': 'seam'}, 'channel_mapping': {'foo': 'default_channel'}, 'parameter_constraints': [str(ParameterConstraint('c > 0'))] } data = mpt.get_serialization_data(serializer=serializer) self.assertEqual(expected_data, data)
def test_as_expression(self): from sympy.abc import f, k, b duration = 5 dummy = DummyPulseTemplate(defined_channels={'A', 'B', 'C'}, parameter_names={'k', 'f', 'b'}, integrals={ 'A': Expression(2 * k), 'B': Expression(-3.2 * f + b), 'C': Expression(1) }, duration=duration) t = DummyPulseTemplate._AS_EXPRESSION_TIME dummy_expr = { ch: i * t / duration for ch, i in dummy._integrals.items() } pulse = MappingPulseTemplate(dummy, parameter_mapping={ 'k': 'f', 'b': 2.3 }, channel_mapping={ 'A': 'a', 'C': None }, allow_partial_parameter_mapping=True) expected = { 'a': Expression(2 * f * t / duration), 'B': Expression((-3.2 * f + 2.3) * t / duration), } self.assertEqual(expected, pulse._as_expression())
def test_deserialize_old(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex( DeprecationWarning, "deprecated", msg= "FunctionPT does not issue warning for old serialization routines." ): basic_data = dict(duration_expression=str(self.s2), expression=self.s, channel='A', identifier='hugo', measurement_declarations=self.meas_list, parameter_constraints=self.constraints) serializer = DummySerializer( serialize_callback=lambda x: x.original_expression) serializer.subelements[self.s2] = Expression(self.s2) serializer.subelements[self.s] = Expression(self.s) template = FunctionPulseTemplate.deserialize( serializer, **basic_data) self.assertEqual('hugo', template.identifier) self.assertEqual({'a', 'b', 'c', 'x', 'z', 'j', 'u', 'd'}, template.parameter_names) self.assertEqual(template.measurement_declarations, self.meas_list) serialized_data = template.get_serialization_data(serializer) del basic_data['identifier'] self.assertEqual(basic_data, serialized_data)
def test_integral(self) -> None: pulse = TablePulseTemplate(entries={0: [(1, 2, 'linear'), (3, 0, 'jump'), (4, 2, 'hold'), (5, 8, 'hold')], 'other_channel': [(0, 7, 'linear'), (2, 0, 'hold'), (10, 0)], 'symbolic': [(3, 'a', 'hold'), ('b', 4, 'linear'), ('c', Expression('d'), 'hold')]}) expected = {0: Expression('6'), 'other_channel': Expression(7), 'symbolic': Expression('(b-3.)*a + (c-b)*(d+4.) / 2')} self.assertEqual(expected, pulse.integral)
def make_kwargs(self): return { 'expression': Expression('a + b * t'), 'duration_expression': Expression('c'), 'channel': 'A', 'measurements': [('mw', 1, 1), ('mw', 'x', 'z'), ('drup', 'j', 'u')], 'parameter_constraints': [str(ParameterConstraint('a < b')), str(ParameterConstraint('c > 1')), str(ParameterConstraint('d > c'))] }
def test_equality(self) -> None: wf1a = FunctionWaveform(Expression('2*t'), 3, channel='A') wf1b = FunctionWaveform(Expression('2*t'), 3, channel='A') wf3 = FunctionWaveform(Expression('2*t+2'), 3, channel='A') wf4 = FunctionWaveform(Expression('2*t'), 4, channel='A') self.assertEqual(wf1a, wf1a) self.assertEqual(wf1a, wf1b) self.assertNotEqual(wf1a, wf3) self.assertNotEqual(wf1a, wf4)
def make_kwargs(self): return { 'template': DummyPulseTemplate(defined_channels={'foo'}, measurement_names={'meas'}, parameter_names={'hugo', 'herbert', 'ilse'}), 'parameter_mapping': {'hugo': Expression('2*k+c'), 'herbert': Expression('c-1.5'), 'ilse': Expression('ilse')}, 'measurement_mapping': {'meas': 'seam'}, 'channel_mapping': {'foo': 'default_channel'}, 'parameter_constraints': [str(ParameterConstraint('c > 0'))] }
def test_integral(self) -> None: dummy = DummyPulseTemplate(defined_channels={'A', 'B', 'C'}, parameter_names={'k', 'f', 'b'}, integrals={'A': Expression('2*k'), 'B': Expression('-3.2*f+b'), 'C': Expression(1)}) pulse = MappingPulseTemplate(dummy, parameter_mapping={'k': 'f', 'b': 2.3}, channel_mapping={'A': 'a', 'C': None}, allow_partial_parameter_mapping=True) self.assertEqual({'a': Expression('2*f'), 'B': Expression('-3.2*f+2.3')}, pulse.integral)
def test_equality(self): with self.assertWarns(DeprecationWarning): p1 = MappedParameter(Expression("foo + 1"), {'foo': ConstantParameter(3)}) p2 = MappedParameter(Expression("foo + 1"), {'foo': ConstantParameter(4)}) p3 = MappedParameter(Expression("foo + 1"), {'foo': ConstantParameter(3)}) self.assertEqual(p1, p3) self.assertNotEqual(p1, p2)
def test_known_interpolation_strategies(self): strategies = [("linear", LinearInterpolationStrategy()), ("hold", HoldInterpolationStrategy()), ("jump", JumpInterpolationStrategy())] for strat_name, strat_val in strategies: entry = TableEntry('a', Expression('b'), strat_name) self.assertEqual(entry.t, Expression('a')) self.assertEqual(entry.v, Expression('b')) self.assertEqual(entry.interp, strat_val)
def test_build_waveform(self) -> None: with self.assertRaises(ParameterConstraintViolation): self.fpt.build_waveform(self.invalid_par_vals, channel_mapping={'A': 'B'}) wf = self.fpt.build_waveform(self.valid_par_vals, channel_mapping={'A': 'B'}) self.assertIsNotNone(wf) self.assertIsInstance(wf, FunctionWaveform) expression = Expression(self.s).evaluate_symbolic(self.valid_par_vals) duration = Expression(self.s2).evaluate_numeric(c=self.valid_par_vals['c']) expected_waveform = FunctionWaveform(expression, duration=duration, channel='B') self.assertEqual(expected_waveform, wf)
def __init__(self, measurements: Optional[List[MeasurementDeclaration]]): if measurements is None: self._measurement_windows = [] else: self._measurement_windows = [ (name, begin if isinstance(begin, Expression) else Expression(begin), length if isinstance(length, Expression) else Expression(length)) for name, begin, length in measurements ] for _, _, length in self._measurement_windows: if (length < 0) is True: raise ValueError( 'Measurement window length may not be negative')
def test_special_function_numeric_evaluation(self): expr = Expression('erfc(t)') data = [-1., 0., 1.] expected = np.array([1.84270079, 1., 0.15729921]) result = expr.evaluate_numeric(t=data) np.testing.assert_allclose(expected, result)
def test_time_is_0_on_instantiation(self): table = TablePulseTemplate({0: [('a', 1)]}) self.assertEqual(table.duration, Expression('a')) self.assertEqual(table.parameter_names, {'a'}) self.assertIsNone( table.build_waveform(parameters=dict(a=0), channel_mapping={0: 0}))
def __init__( self, value: Union[Real, numpy.ndarray, Expression, str, sympy.Expr]) -> None: """ .. deprecated:: 0.5 A pulse parameter with a constant value. Args: value: The value of the parameter """ warnings.warn( "ConstantParameter is deprecated. Use plain number types instead", DeprecationWarning) super().__init__() try: if isinstance(value, Real): self._value = value elif isinstance(value, (str, Expression, sympy.Expr)): self._value = Expression(value).evaluate_numeric() else: self._value = numpy.array(value).view(HashableNumpyArray) except ExpressionVariableMissingException: raise RuntimeError( "Expressions passed into ConstantParameter may not have free variables." )
def __init__(self, requires_stop: bool = False, is_interruptable: bool = False, parameter_names: Set[str] = {}, defined_channels: Set[ChannelID] = {'default'}, duration: Any = 0, waveform: Waveform = tuple(), measurement_names: Set[str] = set(), measurements: list = list(), integrals: Dict[ChannelID, ExpressionScalar] = { 'default': ExpressionScalar(0) }, program: Optional[Loop] = None, identifier=None, registry=None) -> None: super().__init__(identifier=identifier, measurements=measurements) self.requires_stop_ = requires_stop self.requires_stop_arguments = [] self.is_interruptable_ = is_interruptable self.parameter_names_ = parameter_names self.build_sequence_arguments = [] self.defined_channels_ = defined_channels self._duration = Expression(duration) self.waveform = waveform self.build_waveform_calls = [] self.measurement_names_ = set(measurement_names) self._integrals = integrals self.create_program_calls = [] self._program = program self._register(registry=registry)
def test_requires_stop_and_get_value(self) -> None: with self.assertWarns(DeprecationWarning): p = MappedParameter(Expression("foo + bar * hugo")) with self.assertRaises(ParameterNotProvidedException): p.requires_stop with self.assertRaises(ParameterNotProvidedException): p.get_value() foo = DummyParameter(-1.1) bar = DummyParameter(0.5) hugo = DummyParameter(5.2, requires_stop=True) ilse = DummyParameter(2356.4, requires_stop=True) p._namespace = {'foo': foo, 'bar': bar, 'ilse': ilse} with self.assertRaises(ParameterNotProvidedException): p.requires_stop with self.assertRaises(ParameterNotProvidedException): p.get_value() p._namespace = {'foo': foo, 'bar': bar, 'hugo': hugo} self.assertTrue(p.requires_stop) hugo = DummyParameter(5.2, requires_stop=False) p._namespace = {'foo': foo, 'bar': bar, 'hugo': hugo, 'ilse': ilse} self.assertFalse(p.requires_stop) self.assertEqual(1.5, p.get_value())
def __init__(self, requires_stop: bool=False, parameter_names: Set[str]=set(), defined_channels: Set[ChannelID]=None, duration: Any=0, waveform: Waveform=tuple(), measurement_names: Set[str] = set(), measurements: list=list(), integrals: Dict[ChannelID, ExpressionScalar]=None, program: Optional[Loop]=None, identifier=None, registry=None) -> None: super().__init__(identifier=identifier, measurements=measurements) self.requires_stop_ = requires_stop self.requires_stop_arguments = [] if defined_channels is None: defined_channels = {'default'} if integrals is None: integrals = {ch: ExpressionScalar(0) for ch in defined_channels} self.parameter_names_ = parameter_names self.defined_channels_ = defined_channels self._duration = Expression(duration) self.waveform = waveform self.build_waveform_calls = [] self.measurement_names_ = set(measurement_names) self._integrals = integrals self.create_program_calls = [] self._program = program self._register(registry=registry) if integrals is not None: assert isinstance(integrals, Mapping)
def test_duration(self): dt = DummyPulseTemplate(parameter_names={'idx', 'd'}, duration=Expression('d+idx*2')) flt = ForLoopPulseTemplate(body=dt, loop_index='idx', loop_range='n') self.assertEqual(flt.duration.evaluate_numeric(n=4, d=100), 4 * 100 + 2 * (1 + 2 + 3)) flt = ForLoopPulseTemplate(body=dt, loop_index='idx', loop_range=(3, 'n', 2)) self.assertEqual(flt.duration.evaluate_numeric(n=9, d=100), 3 * 100 + 2 * (3 + 5 + 7)) self.assertEqual(flt.duration.evaluate_numeric(n=8, d=100), 3 * 100 + 2 * (3 + 5 + 7)) flt = ForLoopPulseTemplate(body=dt, loop_index='idx', loop_range=('m', 'n', -2)) self.assertEqual(flt.duration.evaluate_numeric(n=9, d=100, m=14), 3 * 100 + 2 * (14 + 12 + 10)) flt = ForLoopPulseTemplate(body=dt, loop_index='idx', loop_range=('m', 'n', -2)) self.assertEqual(flt.duration.evaluate_numeric(n=9, d=100, m=14), 3 * 100 + 2 * (14 + 12 + 10))
def test_evaluate_numeric_without_numpy(self): e = Expression('a * b + c') params = { 'a': 2, 'b': 1.5, 'c': -7 } self.assertEqual(2 * 1.5 - 7, e.evaluate_numeric(**params)) params = { 'a': 2j, 'b': 1.5, 'c': -7 } self.assertEqual(2j * 1.5 - 7, e.evaluate_numeric(**params)) params = { 'a': 2, 'b': 6, 'c': -7 } self.assertEqual(2 * 6 - 7, e.evaluate_numeric(**params)) params = { 'a': 2, 'b': sympify('k'), 'c': -7 } with self.assertRaises(NonNumericEvaluation): e.evaluate_numeric(**params)
def test_expression_value(self) -> None: expression_str = "exp(4)*sin(pi/2)" expression_obj = Expression(expression_str) expression_val = expression_obj.evaluate_numeric() param = ConstantParameter(expression_str) self.assertEqual(expression_val, param.get_value()) param = ConstantParameter(expression_obj) self.assertEqual(expression_val, param.get_value())
def test_duration(self): seconds2ns = 1e9 pulse_duration = 1.0765001496284785e-07 dpt = DummyPulseTemplate(duration=Expression('duration'), parameter_names={'duration'}, defined_channels={'A'}) mpt = MappingPulseTemplate(dpt, parameter_mapping={'duration': seconds2ns * pulse_duration}) self.assertEqual(seconds2ns * pulse_duration, mpt.duration)
def test_get_serialization_data_old(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex( DeprecationWarning, "deprecated", msg= "TablePT does not issue warning for old serialization routines." ): expected_data = dict(measurements=self.measurements, entries=self.entries, parameter_constraints=[ str(Expression('ilse>2')), str(Expression('k>foo')) ]) data = self.template.get_serialization_data(self.serializer) self.assertEqual(expected_data, data)
def test_integral(self) -> None: dummy = DummyPulseTemplate(integrals={ 'A': ExpressionScalar('foo+2'), 'B': ExpressionScalar('k*3+x**2') }) template = RepetitionPulseTemplate(dummy, 7) self.assertEqual( { 'A': Expression('7*(foo+2)'), 'B': Expression('7*(k*3+x**2)') }, template.integral) template = RepetitionPulseTemplate(dummy, '2+m') self.assertEqual( { 'A': Expression('(2+m)*(foo+2)'), 'B': Expression('(2+m)*(k*3+x**2)') }, template.integral) template = RepetitionPulseTemplate(dummy, Expression('2+m')) self.assertEqual( { 'A': Expression('(2+m)*(foo+2)'), 'B': Expression('(2+m)*(k*3+x**2)') }, template.integral)
def __init__(self, relation: Union[str, sympy.Expr]): super().__init__() if isinstance(relation, str) and '==' in relation: # The '==' operator is interpreted by sympy as exactly, however we need a symbolical evaluation self._expression = sympy.Eq(*sympy.sympify(relation.split('=='))) else: self._expression = sympy.sympify(relation) if not isinstance(self._expression, sympy.boolalg.Boolean): raise ValueError('Constraint is not boolean') self._expression = Expression(self._expression)
def test_deserialize(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex( DeprecationWarning, "deprecated", msg= "SequencePT does not issue warning for old serialization routines." ): dummy_pt = DummyPulseTemplate( defined_channels={'foo'}, measurement_names={'meas'}, parameter_names={'hugo', 'herbert', 'ilse'}) serializer = DummySerializer() data = { 'template': serializer.dictify(dummy_pt), 'parameter_mapping': { 'hugo': str(Expression('2*k+c')), 'herbert': str(Expression('c-1.5')), 'ilse': str(Expression('ilse')) }, 'measurement_mapping': { 'meas': 'seam' }, 'channel_mapping': { 'foo': 'default_channel' }, 'parameter_constraints': [str(ParameterConstraint('c > 0'))] } deserialized = MappingPulseTemplate.deserialize( serializer=serializer, **data) self.assertIsInstance(deserialized, MappingPulseTemplate) self.assertEqual(data['parameter_mapping'], deserialized.parameter_mapping) self.assertEqual(data['channel_mapping'], deserialized.channel_mapping) self.assertEqual(data['measurement_mapping'], deserialized.measurement_mapping) self.assertEqual( data['parameter_constraints'], [str(pc) for pc in deserialized.parameter_constraints]) self.assertIs(deserialized.template, dummy_pt)
def test_get_serialization_data_old(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex( DeprecationWarning, "deprecated", msg= "PointPT does not issue warning for old serialization routines." ): expected_data = dict(measurements=self.measurements, time_point_tuple_list=self.entries, channel_names=(0, 'A'), parameter_constraints=[ str(Expression('ilse>2')), str(Expression('k>foo')) ]) serializer = DummySerializer(lambda x: dict(name=x.name), lambda x: x.name, lambda x: x['name']) data = self.template.get_serialization_data(serializer) self.assertEqual(expected_data, data)
def test_integral(self) -> None: pulse = TablePulseTemplate( entries={ 0: [(1, 2), (3, 0, 'linear'), (4, 2, 'jump'), (5, 8, 'hold')], 'other_channel': [(0, 7), (2, 0, 'linear'), (10, 0)], 'symbolic': [(3, 'a'), ('b', 4, 'hold'), ('c', Expression('d'), 'linear')] }) expected = { 0: Expression('2 + 2 + 2 + 2 + (Max(c, 10) - 5) * 8'), 'other_channel': Expression(7), 'symbolic': Expression( '3 * a + (b-3)*a + (c-b)*(d+4) / 2 + (Max(10, c) - c) * d') } self.assertEqual(expected, pulse.integral)
def operation(cls, expression, **operands): expression = Expression(expression) assert set(expression.variables) == operands.keys() scope = JointScope( FrozenDict({ operand_name: MappedScope(operand._scope, FrozenDict({operand_name: operand._expression})) for operand_name, operand in operands.items() })) return cls(expression, scope)
def test_unsafe_sample(self): fw = FunctionWaveform(Expression('sin(2*pi*t) + 3'), 5, channel='A') t = np.linspace(0, 5, dtype=float) expected_result = np.sin(2*np.pi*t) + 3 result = fw.unsafe_sample(channel='A', sample_times=t) np.testing.assert_equal(result, expected_result) out_array = np.empty_like(t) result = fw.unsafe_sample(channel='A', sample_times=t, output_array=out_array) np.testing.assert_equal(result, expected_result) self.assertIs(result, out_array)