示例#1
0
    def test_undefined_comparison(self):
        valued = Expression(2)
        unknown = Expression('a')

        self.assertIsNone(unknown < 0)
        self.assertIsNone(unknown > 0)
        self.assertIsNone(unknown >= 0)
        self.assertIsNone(unknown <= 0)
        self.assertFalse(unknown == 0)

        self.assertIsNone(0 < unknown)
        self.assertIsNone(0 > unknown)
        self.assertIsNone(0 <= unknown)
        self.assertIsNone(0 >= unknown)
        self.assertFalse(0 == unknown)

        self.assertIsNone(unknown < valued)
        self.assertIsNone(unknown > valued)
        self.assertIsNone(unknown >= valued)
        self.assertIsNone(unknown <= valued)
        self.assertFalse(unknown == valued)

        valued, unknown = unknown, valued
        self.assertIsNone(unknown < valued)
        self.assertIsNone(unknown > valued)
        self.assertIsNone(unknown >= valued)
        self.assertIsNone(unknown <= valued)
        self.assertFalse(unknown == valued)
        valued, unknown = unknown, valued

        self.assertFalse(unknown == valued)
    def __init__(self,
                 expression: Union[str, Expression],
                 duration_expression: Union[str, Expression],
                 measurement: bool = False,
                 identifier: str = None) -> None:
        """Create a new FunctionPulseTemplate instance.

        Args:
            expression (str or Expression): The function represented by this FunctionPulseTemplate
                as a mathematical expression where 't' denotes the time variable and other variables
                will be parameters of the pulse.
            duration_expression (str or Expression): A mathematical expression which reliably
                computes the duration of an instantiation of this FunctionPulseTemplate from
                provided parameter values.
            measurement (bool): True, if this FunctionPulseTemplate shall define a measurement
                window. (optional, default = False)
            identifier (str): A unique identifier for use in serialization. (optional)
        """
        super().__init__(identifier)
        self.__expression = expression
        if not isinstance(self.__expression, Expression):
            self.__expression = Expression(self.__expression)
        self.__duration_expression = duration_expression
        if not isinstance(self.__duration_expression, Expression):
            self.__duration_expression = Expression(self.__duration_expression)
        self.__is_measurement_pulse = measurement  # type: bool
        self.__parameter_names = set(self.__duration_expression.variables() +
                                     self.__expression.variables()) - set(
                                         ['t'])
示例#3
0
    def test_symbolic_math(self):
        a = Expression('a')
        b = Expression('b')

        self.assertExpressionEqual(a + b, b + a)
        self.assertExpressionEqual(a - b, -(b - a))
        self.assertExpressionEqual(a * b, b * a)
        self.assertExpressionEqual(a / b, 1 / (b / a))
 def test_build_waveform(self) -> None:
     wf = self.fpt.build_waveform(self.args)
     self.assertIsNotNone(wf)
     self.assertIsInstance(wf, FunctionWaveform)
     expected_waveform = FunctionWaveform(dict(a=3, y=1),
                                          Expression(self.f),
                                          Expression(self.duration))
     self.assertEqual(expected_waveform, wf)
示例#5
0
    def test_evaluate_numeric(self) -> None:
        e = Expression('a * b + c')
        params = {'a': 2, 'b': 1.5, 'c': -7}
        self.assertEqual(2 * 1.5 - 7, e.evaluate_numeric(**params))

        with self.assertRaises(NonNumericEvaluation):
            params['a'] = sympify('h')
            e.evaluate_numeric(**params)
 def test_sample(self) -> None:
     f = Expression("(t+1)**b")
     length = Expression("c**b")
     par = {"b": 2, "c": 10}
     fw = FunctionWaveform(par, f, length)
     a = np.arange(4)
     expected_result = [[1, 4, 9, 16]]
     result = fw.sample(a)
     self.assertTrue(np.all(result == expected_result))
 def test_parameter_names_and_declarations_expression_input(self) -> None:
     template = FunctionPulseTemplate(Expression("3 * foo + bar * t"),
                                      Expression("5 * hugo"))
     expected_parameter_names = {'foo', 'bar', 'hugo'}
     self.assertEqual(expected_parameter_names, template.parameter_names)
     self.assertEqual(
         {ParameterDeclaration(name)
          for name in expected_parameter_names},
         template.parameter_declarations)
示例#8
0
 def test_evaluate_numpy(self):
     e = Expression('a * b + c')
     params = {
         'a': 2 * np.ones(4),
         'b': 1.5 * np.ones(4),
         'c': -7 * np.ones(4)
     }
     np.testing.assert_equal((2 * 1.5 - 7) * np.ones(4),
                             e.evaluate_numeric(**params))
示例#9
0
 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)
示例#10
0
 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)
示例#11
0
    def test_get_serialization_data(self) -> None:
        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)
示例#12
0
    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_get_serialization_data(self) -> None:
        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'))
                             ])

        data = self.template.get_serialization_data(self.serializer)
        self.assertEqual(expected_data, data)
 def test_add(self) -> None:
     map = PulseTemplateParameterMapping({'bar'})
     dummy1 = DummyPulseTemplate(parameter_names={'foo', 'hugo'})
     dummy2 = DummyPulseTemplate(parameter_names={'grr'})
     map.add(dummy1, 'foo', '4*bar')
     map.add(dummy2, 'grr', Expression('bar ** 2'))
     map.add(dummy1, 'hugo', '3')
     map.add(dummy2, 'grr', Expression('sin(bar)'))
     self.assertEqual(dict(foo=Expression('4*bar'), hugo=Expression('3')),
                      map.get_template_map(dummy1))
     self.assertEqual(dict(grr=Expression('sin(bar)')),
                      map.get_template_map(dummy2))
 def test_map_parameters(self) -> None:
     map = PulseTemplateParameterMapping({'bar', 'barbar'})
     dummy = DummyPulseTemplate(parameter_names={'foo', 'hugo'})
     map.add(dummy, 'hugo', '4*bar')
     map.add(dummy, 'foo', Expression('barbar'))
     mapped = map.map_parameters(
         dummy, dict(bar=ConstantParameter(3), barbar=ConstantParameter(5)))
     self.assertEqual(
         dict(hugo=MappedParameter(Expression('4*bar'),
                                   dict(bar=ConstantParameter(3))),
              foo=MappedParameter(Expression('barbar'),
                                  dict(barbar=ConstantParameter(5)))),
         mapped)
示例#16
0
 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')
示例#17
0
    def test_requires_stop_and_get_value(self) -> None:
        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.dependencies = {'foo': foo, 'hugo': hugo, 'ilse': ilse}
        with self.assertRaises(ParameterNotProvidedException):
            p.requires_stop
        with self.assertRaises(ParameterNotProvidedException):
            p.get_value()

        p.dependencies = {'foo': foo, 'bar': bar, 'hugo': hugo}
        self.assertTrue(p.requires_stop)
        with self.assertRaises(Exception):
            p.get_value()

        hugo = DummyParameter(5.2, requires_stop=False)
        p.dependencies = {'foo': foo, 'bar': bar, 'hugo': hugo, 'ilse': ilse}
        self.assertFalse(p.requires_stop)
        self.assertEqual(1.5, p.get_value())
 def test_equality(self) -> None:
     wf1a = FunctionWaveform(dict(a=2, b=1), Expression('a*t'),
                             Expression('b'))
     wf1b = FunctionWaveform(dict(a=2, b=1), Expression('a*t'),
                             Expression('b'))
     wf2 = FunctionWaveform(dict(a=3, b=1), Expression('a*t'),
                            Expression('b'))
     wf3 = FunctionWaveform(dict(a=2, b=1), Expression('a*t+2'),
                            Expression('b'))
     wf4 = FunctionWaveform(dict(a=2, c=2), Expression('a*t'),
                            Expression('c'))
     self.assertEqual(wf1a, wf1a)
     self.assertEqual(wf1a, wf1b)
     self.assertNotEqual(wf1a, wf2)
     self.assertNotEqual(wf1a, wf3)
     self.assertNotEqual(wf1a, wf4)
 def test_map_parameters_not_provided(self) -> None:
     map = PulseTemplateParameterMapping({'bar', 'barbar'})
     dummy = DummyPulseTemplate(parameter_names={'foo', 'hugo'})
     map.add(dummy, 'hugo', '4*bar')
     map.add(dummy, 'foo', Expression('barbar'))
     with self.assertRaises(ParameterNotProvidedException):
         map.map_parameters(dummy, dict(bar=ConstantParameter(3)))
示例#20
0
    def test_deserialize(self) -> None:
        dummy1 = DummyPulseTemplate(parameter_names={'foo'}, num_channels=2)
        dummy2 = DummyPulseTemplate(parameter_names={}, num_channels=1)
        exp = Expression("bar - 35")

        data = dict(external_parameters=['bar'],
                    subtemplates=[
                        dict(template=str(id(dummy1)),
                             parameter_mappings=dict(foo=str(exp)),
                             channel_mappings=[0, 2]),
                        dict(template=str(id(dummy2)),
                             parameter_mappings=dict(),
                             channel_mappings=[1])
                    ])

        serializer = DummySerializer(serialize_callback=lambda x: str(x) if
                                     isinstance(x, Expression) else str(id(x)))
        serializer.subelements[str(id(dummy1))] = dummy1
        serializer.subelements[str(id(dummy2))] = dummy2
        serializer.subelements[str(exp)] = exp

        template = MultiChannelPulseTemplate.deserialize(serializer, **data)
        self.assertEqual(set(data['external_parameters']),
                         template.parameter_names)
        self.assertEqual({ParameterDeclaration('bar')},
                         template.parameter_declarations)

        recovered_data = template.get_serialization_data(serializer)
        self.assertEqual(data, recovered_data)
示例#21
0
    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}))
示例#22
0
    def test_get_most_simple_representation(self):
        cpl = Expression('1 + 1j').get_most_simple_representation()
        self.assertIsInstance(cpl, complex)
        self.assertEqual(cpl, 1 + 1j)

        integer = Expression('3').get_most_simple_representation()
        self.assertIsInstance(integer, int)
        self.assertEqual(integer, 3)

        flt = Expression('3.').get_most_simple_representation()
        self.assertIsInstance(flt, float)
        self.assertEqual(flt, 3.)

        st = Expression('a + b').get_most_simple_representation()
        self.assertIsInstance(st, str)
        self.assertEqual(st, 'a + b')
    def add(self, template: PulseTemplate, parameter: str,
            mapping_expression: Union[str, Expression]):
        """Add a new mapping for a parameter of a pulse template.

        Args:
            template (PulseTemplate): The pulse template for which a parameter mapping will be
                added.
            parameter (str): The name of the parameter of the pulse template that will be mapped.
            mapping_expression (str or Expression): The mathematical expression that specifies the
                mapping from external parameters to the parameter of the pulse template.
        Raises:
            UnnecessaryMappingException, if parameter is not declared by template.
            MissingParameterDeclarationException, if mapping_expression requires a variable that
                is not a parameter in the external parameters of this PulseTemplateParameterMapping.
        """
        if parameter not in template.parameter_names:
            raise UnnecessaryMappingException(template, parameter)

        if isinstance(mapping_expression, str):
            mapping_expression = Expression(mapping_expression)
        required_externals = set(mapping_expression.variables())
        non_declared_externals = required_externals - self.__external_parameters
        if non_declared_externals:
            raise MissingParameterDeclarationException(
                template, non_declared_externals.pop())

        template_map = self.__get_template_map(template)
        template_map[parameter] = mapping_expression
        self.__map[template] = template_map
示例#24
0
    def test_expression_variable_missing(self):
        variable = 's'
        expression = Expression('s*t')

        self.assertEqual(
            str(ExpressionVariableMissingException(variable, expression)),
            "Could not evaluate <s*t>: A value for variable <s> is missing!")
 def test_get_remaining_mappings(self) -> None:
     map = PulseTemplateParameterMapping({'bar', 'barbar'})
     dummy = DummyPulseTemplate(parameter_names={'foo', 'hugo'})
     self.assertEqual({'foo', 'hugo'}, map.get_remaining_mappings(dummy))
     map.add(dummy, 'hugo', '4*bar')
     self.assertEqual({'foo'}, map.get_remaining_mappings(dummy))
     map.add(dummy, 'foo', Expression('barbar'))
     self.assertEqual(set(), map.get_remaining_mappings(dummy))
示例#26
0
    def test_number_math(self):
        a = Expression('a')
        b = 3.3

        self.assertExpressionEqual(a + b, b + a)
        self.assertExpressionEqual(a - b, -(b - a))
        self.assertExpressionEqual(a * b, b * a)
        self.assertExpressionEqual(a / b, 1 / (b / a))
 def test_deserialize(self) -> None:
     basic_data = dict(duration_expression=str(self.s2),
                       expression=str(self.s),
                       measurement=False,
                       identifier='hugo')
     serializer = DummySerializer(serialize_callback=lambda x: str(x))
     serializer.subelements[str(self.s2)] = Expression(self.s2)
     serializer.subelements[str(self.s)] = Expression(self.s)
     template = FunctionPulseTemplate.deserialize(serializer, **basic_data)
     self.assertEqual('hugo', template.identifier)
     self.assertEqual({'a', 'b', 'c'}, template.parameter_names)
     self.assertEqual(
         {ParameterDeclaration(name)
          for name in {'a', 'b', 'c'}}, template.parameter_declarations)
     serialized_data = template.get_serialization_data(serializer)
     del basic_data['identifier']
     self.assertEqual(basic_data, serialized_data)
示例#28
0
 def test_get_serialization_data(self) -> None:
     exp = Expression("foo + bar * hugo")
     p = MappedParameter(exp)
     serializer = DummySerializer()
     data = p.get_serialization_data(serializer)
     self.assertEqual(
         dict(type=serializer.get_type_identifier(p),
              expression=str(id(exp))), data)
示例#29
0
    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)
示例#30
0
 def test_deserialize(self) -> None:
     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 __init__(self, expression: str, duration_expression: str, measurement: bool=False) -> None:
     super().__init__()
     self.__expression = Expression(expression)
     self.__duration_expression = Expression(duration_expression)
     self.__is_measurement_pulse = measurement # type: bool
     self.__parameter_names = set(self.__duration_expression.variables() + self.__expression.variables()) - set(['t'])
class FunctionPulseTemplate(PulseTemplate):
    """Defines a pulse via a time-domain expression.

    FunctionPulseTemplate stores the expression and its external parameters. The user must provide
    two things: one expression that calculates the length of the pulse from the external parameters
    and the time-domain pulse shape itself as a expression. The external parameters are derived from
    the expressions themselves.
    Like other PulseTemplates the FunctionPulseTemplate can be declared to be a measurement pulse.

    The independent variable in the expression is called 't' and is given in units of nano-seconds.
    """

    def __init__(self, expression: str, duration_expression: str, measurement: bool=False) -> None:
        super().__init__()
        self.__expression = Expression(expression)
        self.__duration_expression = Expression(duration_expression)
        self.__is_measurement_pulse = measurement # type: bool
        self.__parameter_names = set(self.__duration_expression.variables() + self.__expression.variables()) - set(['t'])

    @property
    def parameter_names(self) -> Set[str]:
        """Return the set of names of declared parameters."""
        return self.__parameter_names

    @property
    def parameter_declarations(self) -> Set[ParameterDeclaration]:
        """Return a set of all parameter declaration objects of this TablePulseTemplate."""
        return set()

    def get_pulse_length(self, parameters) -> float:
        """Return the length of this pulse for the given parameters."""
        missing = self.__parameter_names - set(parameters.keys())
        for m in missing:
            raise ParameterNotProvidedException(m)
        return self.__duration_expression.evaluate(**parameters)

    def get_measurement_windows(self, parameters: Optional[Dict[str, Parameter]] = {}) -> List[MeasurementWindow]:
        """Return all measurement windows defined in this PulseTemplate.
       
        A ExpressionPulseTemplate specifies either no measurement windows or exactly one that spans its entire duration,
        depending on whether the measurement_pulse flag was given during construction.
        """
        if not self.__is_measurement_pulse:
            return
        else:
            return [(0, self.get_pulse_length(parameters))]

    @property
    def is_interruptable(self) -> bool:
        """Return true, if this PulseTemplate contains points at which it can halt if interrupted."""
        return False
        
    def build_sequence(self,
                       sequencer: Sequencer,
                       parameters: Dict[str, Parameter],
                       conditions: Dict[str, 'Condition'],
                       instruction_block: InstructionBlock) -> None:
        waveform = FunctionWaveform(parameters, self.__expression, self.__duration_expression)
        instruction_block.add_instruction_exec(waveform)

    def requires_stop(self, parameters: Dict[str, Parameter], conditions: Dict[str, 'Condition']) -> bool:
        return any(parameters[name].requires_stop for name in parameters.keys() if (name in self.parameter_names) and not isinstance(parameters[name], numbers.Number))

    def get_serialization_data(self, serializer: Serializer) -> None:
        root = dict()
        root['type'] = 'FunctionPulseTemplate'
        root['parameter_names'] = self.__parameter_names
        root['duration_expression'] = self.__duration_expression.string
        root['expression'] = self.__expression.string
        root['measurement'] = self.__is_measurement_pulse
        return root

    @staticmethod
    def deserialize(serializer: 'Serializer', **kwargs) -> 'Serializable':
        return FunctionPulseTemplate(kwargs['expression'], kwargs['duration_expression'], kwargs['Measurement'])