Example #1
0
class Subject(object):
    """
    Base class for the subject in an observer design pattern.
    """
    def __init__(self):
        self._observers = OrderedSet()

    def subscribe(self, observer):
        self._observers.add(observer)

    def unsubscribe(self, observer):
        self._observers.remove(observer)

    def notify(self):
        for o in self._observers:
            o.update(self)
Example #2
0
 def _register_constraint(self, con):
     if type(con.expr) == ConditionalExpression:
         self._register_conditional_constraint(con)
         return None
     ccon = self._evaluator.add_constraint()
     con._c_obj = ccon
     self._con_ccon_map[con] = ccon
     leaf_ndx_map = OrderedDict()
     referenced_vars = OrderedSet()
     referenced_params = OrderedSet()
     referenced_floats = OrderedSet()
     ndx = 0
     for v in con.expr.get_vars():
         leaf_ndx_map[v] = ndx
         ndx += 1
         cvar = self._increment_var(v)
         ccon.add_leaf(cvar)
         referenced_vars.add(v)
     for p in con.expr.get_params():
         leaf_ndx_map[p] = ndx
         ndx += 1
         cparam = self._increment_param(p)
         ccon.add_leaf(cparam)
         referenced_params.add(p)
     for f in con.expr.get_floats():
         leaf_ndx_map[f] = ndx
         ndx += 1
         cfloat = self._increment_float(f)
         ccon.add_leaf(cfloat)
         referenced_floats.add(f)
     fn_rpn = con.expr.get_rpn(leaf_ndx_map)
     for term in fn_rpn:
         ccon.add_fn_rpn_term(term)
     jac = con.expr.reverse_sd()
     for v in con.expr.get_vars():
         jac_v = jac[v]
         if type(jac_v) in native_numeric_types:
             jac_v = Float(jac_v)
         for f in jac_v.get_floats():
             if f not in leaf_ndx_map:
                 leaf_ndx_map[f] = ndx
                 ndx += 1
                 cfloat = self._increment_float(f)
                 ccon.add_leaf(cfloat)
                 referenced_floats.add(f)
         jac_rpn = jac_v.get_rpn(leaf_ndx_map)
         cvar = self._var_cvar_map[v]
         for term in jac_rpn:
             ccon.add_jac_rpn_term(cvar, term)
     self._vars_referenced_by_con[con] = referenced_vars
     self._params_referenced_by_con[con] = referenced_params
     self._floats_referenced_by_con[con] = referenced_floats
Example #3
0
class expression(ExpressionBase):

    __slots__ = ('_operators', '_n_opers', '_vars', '_params', '_floats')

    def __init__(self, expr=None):
        """

        Parameters
        ----------
        expr: expression
        """
        if expr is not None:
            if expr._operators[-1] is not expr.last_node():
                self._operators = expr.list_of_operators()
            else:
                self._operators = expr._operators
        else:
            self._operators = []
        self._n_opers = len(self._operators)
        self._vars = None
        self._params = None
        self._floats = None

    def append_operator(self, oper):
        self._operators.append(oper)
        self._n_opers += 1

    def last_node(self):
        """
        Returns
        -------
        last_node: Operator
        """
        return self._operators[self._n_opers - 1]

    def list_of_operators(self):
        return self._operators[:self._n_opers]

    def is_leaf(self):
        return False

    def operators(self):
        return itertools.islice(self._operators, 0, self._n_opers)

    def _binary_operation_helper(self, other, cls):
        if type(other) in native_numeric_types:
            other = Float(other)
        new_operator = cls(self.last_node(), other.last_node())
        expr = expression(self)
        for oper in other.operators():
            expr.append_operator(oper)
        expr.append_operator(new_operator)
        return expr

    def _unary_operation_helper(self, cls):
        new_operator = cls(self.last_node())
        expr = expression(self)
        expr.append_operator(new_operator)
        return expr

    def evaluate(self):
        val_dict = dict()
        for oper in self.operators():
            oper.evaluate(val_dict)
        return val_dict[self.last_node()]

    def get_vars(self):
        if self._vars is None:
            self._collect_leaves()
        for i in self._vars:
            yield i

    def get_params(self):
        if self._params is None:
            self._collect_leaves()
        for i in self._params:
            yield i

    def get_floats(self):
        if self._floats is None:
            self._collect_leaves()
        for i in self._floats:
            yield i

    def _collect_leaves(self):
        self._vars = OrderedSet()
        self._params = OrderedSet()
        self._floats = OrderedSet()
        for oper in self.operators():
            for operand in oper.operands():
                if operand.is_leaf():
                    if operand.is_variable_type():
                        self._vars.add(operand)
                    elif operand.is_parameter_type():
                        self._params.add(operand)
                    elif operand.is_float_type():
                        self._floats.add(operand)
                    elif operand.is_expression_type():
                        self._vars.update(operand.get_vars())
                        self._params.update(operand.get_params())
                        self._floats.update(operand.get_floats())
                    else:
                        raise ValueError('operand type not recognized: ' +
                                         str(operand))

    def get_leaves(self):
        if self._vars is None:
            self._collect_leaves()
        for i in self._vars:
            yield i
        for i in self._params:
            yield i
        for i in self._floats:
            yield i

    def _str(self):
        return str(self)

    def __str__(self):
        val_dict = dict()
        for oper in self.operators():
            oper._str(val_dict)
        return val_dict[self.last_node()]

    def is_variable_type(self):
        return False

    def is_parameter_type(self):
        return False

    def is_float_type(self):
        return False

    def is_expression_type(self):
        return True

    def reverse_ad(self):
        val_dict = dict()
        der_dict = dict()
        for oper in self.operators():
            oper.diff_up(val_dict, der_dict)
        der_dict[self.last_node()] = 1
        for oper in reversed(self.list_of_operators()):
            oper.diff_down(val_dict, der_dict)
        return der_dict

    def reverse_sd(self):
        val_dict = dict()
        der_dict = dict()
        for oper in self.operators():
            oper.diff_up_symbolic(val_dict, der_dict)
        der_dict[self.last_node()] = 1
        for oper in reversed(self.list_of_operators()):
            oper.diff_down(val_dict, der_dict)
        return der_dict

    def is_relational(self):
        if type(self.last_node()) in {InequalityOperator}:
            return True
        return False

    def get_rpn(self, leaf_ndx_map):
        rpn_map = dict()
        for oper in self.operators():
            oper.get_rpn(rpn_map, leaf_ndx_map)
        return rpn_map[self.last_node()]