def solve_inequality(user_input): inequality_sign = get_inequality_sign(user_input, False) split_input = user_input.split(inequality_sign) left_side = parse_expr(split_input[0]) right_side = parse_expr(split_input[1]) inequality = Relational(left_side, right_side, inequality_sign) variable = get_variable(str(inequality)) answer = remove_infinities( str(reduce_inequalities(inequality, symbols=variable))) if answer == "True" or answer == "False": raise Exception("no parallel functions allowed") return answer
def __init__(self, entries: Dict[ChannelID, Sequence[EntryInInit]], identifier: Optional[str] = None, *, parameter_constraints: Optional[List[Union[ str, ParameterConstraint]]] = None, measurements: Optional[List[MeasurementDeclaration]] = None, consistency_check: bool = True, registry: PulseRegistryType = None) -> None: """ Construct a `TablePulseTemplate` from a dict which maps channels to their entries. By default the consistency of the provided entries is checked. There are two static functions for convenience construction: from_array and from_entry_list. Args: entries: A dictionary that maps channel ids to a list of entries. An entry is a (time, voltage[, interpolation strategy]) tuple or a TableEntry identifier: Used for serialization parameter_constraints: Constraint list that is forwarded to the ParameterConstrainer superclass measurements: Measurement declaration list that is forwarded to the MeasurementDefiner superclass consistency_check: If True the consistency of the times will be checked on construction as far as possible """ AtomicPulseTemplate.__init__(self, identifier=identifier, measurements=measurements) ParameterConstrainer.__init__( self, parameter_constraints=parameter_constraints) if not entries: raise ValueError( "Cannot construct an empty TablePulseTemplate (no entries given). There is currently no " "specific reason for this. Please submit an issue if you need this 'feature'." ) self._entries = dict((ch, list()) for ch in entries.keys()) for channel, channel_entries in entries.items(): if len(channel_entries) == 0: raise ValueError('Channel {} is empty'.format(channel)) for entry in channel_entries: self._add_entry(channel, TableEntry(*entry)) self._duration = self.calculate_duration() self._table_parameters = set( var for channel_entries in self.entries.values() for entry in channel_entries for var in itertools.chain(entry.t.variables, entry.v.variables )) | self.constrained_parameters if self.duration == 0: warnings.warn( 'Table pulse template with duration 0 on construction.', category=ZeroDurationTablePulseTemplate) if consistency_check: # perform a simple consistency check. All inequalities with more than one free variable are ignored as the # sympy solver does not support them # collect all conditions inequalities = [eq.sympified_expression for eq in self._parameter_constraints] +\ [sympy.Le(previous_entry.t.underlying_expression, entry.t.underlying_expression) for channel_entries in self._entries.values() for previous_entry, entry in zip(channel_entries, channel_entries[1:])] # test if any condition is already dissatisfied if any( isinstance(eq, BooleanAtom) and bool(eq) is False for eq in inequalities): raise ValueError( 'Table pulse template has impossible parametrization') # filter conditions that are inequalities with one free variable and test if the solution set is empty inequalities = [ eq for eq in inequalities if isinstance(eq, sympy.Rel) and len(eq.free_symbols) == 1 ] if not sympy.reduce_inequalities(inequalities): raise ValueError( 'Table pulse template has impossible parametrization') self._register(registry=registry)