Source code for qupulse.program.volatile

from typing import NamedTuple, Mapping
import warnings
import numbers


from qupulse.parameter_scope import Scope, MappedScope, JointScope
from qupulse.expressions import Expression, ExpressionScalar
from qupulse.utils.types import FrozenDict, FrozenMapping
from qupulse.utils import is_integer


__all__ = ['VolatileProperty', 'VolatileValue', 'VolatileRepetitionCount']


VolatileProperty = NamedTuple('VolatileProperty', [('expression', Expression),
                                                   ('dependencies', FrozenMapping[str, Expression])])
VolatileProperty.__doc__ = """Hashable representation of a volatile program property. It does not contain the concrete
value. Using the dependencies attribute to calculate the value might yield unexpected results."""


[docs]class VolatileValue: """Not hashable""" def __init__(self, expression: ExpressionScalar, scope: Scope): self._expression = expression self._scope = scope @property def volatile_property(self) -> VolatileProperty: dependencies = self._scope.get_volatile_parameters() dependencies = FrozenDict({parameter_name: dependencies[parameter_name] for parameter_name in self._expression.variables if parameter_name in dependencies}) return VolatileProperty(expression=self._expression, dependencies=dependencies)
[docs] @classmethod 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 __sub__(self, other: int): return type(self)(self._expression - other, self._scope) def __mul__(self, other: int): return type(self)(self._expression * other, self._scope)
[docs]class VolatileRepetitionCount(VolatileValue): def __int__(self): value = self._expression.evaluate_in_scope(self._scope) if not is_integer(value): warnings.warn("Repetition count is no integer. Rounding might lead to unexpected results.") value = int(round(value)) if value < 0: warnings.warn("Repetition count is negative. Clamping lead to unexpected results.") value = 0 return value
[docs] def update_volatile_dependencies(self, new_constants: Mapping[str, numbers.Number]) -> int: self._scope = self._scope.change_constants(new_constants) return int(self)
def __eq__(self, other): if type(self) == type(other): return self._scope is other._scope and self._expression == other._expression else: return NotImplemented