Esempio n. 1
0
def reduce(diagram, linear=True):
    variables = [t[0] for t in column_variables + row_variables]
    if linear:
        reduction = LinearReduction(diagram.pool)
        result = reduction.reduce(diagram.root_node.node_id, variables)
    else:
        reduction = SmtReduce(diagram.pool)
        result = reduction.reduce(diagram.root_node.node_id, variables)
    return Diagram(diagram.pool, result)
Esempio n. 2
0
def reduce(diagram, linear=True):
    variables = [t[0] for t in column_variables + row_variables]
    if linear:
        reduction = LinearReduction(diagram.pool)
        result = reduction.reduce(diagram.root_node.node_id, variables)
    else:
        reduction = SmtReduce(diagram.pool)
        result = reduction.reduce(diagram.root_node.node_id, variables)
    return Diagram(diagram.pool, result)
Esempio n. 3
0
    def reduce(self, variables=None, method="linear"):
        if method == "linear":
            from pyxadd.reduce import LinearReduction
            reducer = LinearReduction(self.pool)
        elif method == "smt":
            from pyxadd.reduce import SmtReduce
            reducer = SmtReduce(self.pool)
        else:
            raise RuntimeError("Unknown reduction method {} (valid options are 'linear' or 'smt')".format(method))

        return Diagram(self.pool, reducer.reduce(self.root_node.node_id, variables))
Esempio n. 4
0
    def reduce(self, variables=None, method="linear", smt_solver=None):
        if method == "linear":
            from pyxadd.reduce import LinearReduction
            reducer = LinearReduction(self.pool)
        elif method == "smt":
            from pyxadd.reduce import SmtReduce
            reducer = SmtReduce(self.pool, solver=smt_solver)
        else:
            raise RuntimeError(
                "Unknown reduction method {} (valid options are 'linear' or 'smt')"
                .format(method))

        return Diagram(self.pool,
                       reducer.reduce(self.root_node.node_id, variables))
Esempio n. 5
0
    def test_constant(self):
        b = self.builder
        pool = b.pool

        test_d = b.limit("x", 1, 1) * b.exp(5) + b.limit("x", 2, 2) * b.exp(5)
        test_d = pool.diagram(
            LinearReduction(pool).reduce(test_d.root_node.node_id))
        self.exporter.export(test_d, "test_d")

        # Test with profile
        add_profile_cache(pool)
        get_profile(self.diagram)

        self.exporter.export(self.diagram, "to_constant")
        constant = to_constant(self.diagram)
        get_profile(constant)

        self.exporter.export(constant, "constant")

        def t(_, node):
            self.assertTrue(is_constant(node),
                            msg="{} still contains variables".format(
                                node.expression))

        walk_leaves(t, constant)
Esempio n. 6
0
    def test_mixed_symbolic(self):
        diagram_y = Diagram(self.diagram.pool, SummationWalker(self.diagram, "x").walk())
        diagram_y = Diagram(diagram_y.pool, LinearReduction(diagram_y.pool).reduce(diagram_y.root_node.node_id, ["y"]))

        for y in range(0, 12):
            row_result = 0
            for x in range(0, 12):
                row_result += self.diagram.evaluate({"x": x, "y": y})
            self.assertEqual(diagram_y.evaluate({"y": y}), row_result)
Esempio n. 7
0
    def test_linear_reduce_2(self):
        diagram2 = self.build_diagram_2()
        # self.exporter.export(diagram2, "diagram2")
        variables = [("x", 0, 11), ("y", 0, 11)]

        reduced_linear2 = diagram2.pool.diagram(LinearReduction(diagram2.pool).reduce(diagram2.root_id))
        # self.exporter.export(reduced_linear2, "reduced_linear2")
        self.control(variables, diagram2, reduced_linear2)

        reduced_smt2 = diagram2.pool.diagram(SmtReduce(diagram2.pool).reduce(diagram2.root_id))
        # self.exporter.export(reduced_smt2, "reduced_smt2")
        self.control(variables, diagram2, reduced_smt2)
Esempio n. 8
0
class ConstantWalker(DownUpWalker):
    def __init__(self, diagram, diagram_vars):
        DownUpWalker.__init__(self, diagram)
        self._diagram_vars = diagram_vars
        self._reduction = LinearReduction(self.diagram.pool)

    def visit_internal_aggregate(self, internal_node, true_result, false_result):
        node_id = self._reduction.reduce((true_result + false_result).root_node.node_id, self._diagram_vars)
        return self.diagram.pool.diagram(node_id)

    def visit_internal_down(self, internal_node, parent_message):
        if parent_message is None:
            parent_message = self._initial_message()

        bounds, path = parent_message
        bounds_t = dict(bounds)
        bounds_f = dict(bounds)

        # Avoiding having to find all integer points in complex areas by only looking at "simple" constraints
        operator = internal_node.test.operator
        if operator.is_singular():
            var = operator.variables[0]
            lb, ub = bounds[var] if var in bounds else (-oo, oo)
            bounds_t[var] = internal_node.test.update_bounds(var, lb, ub, test=True)
            bounds_f[var] = internal_node.test.update_bounds(var, lb, ub, test=False)

        pool = self.diagram.pool
        path_t = path & pool.diagram(pool.internal(LinearTest(operator), pool.one_id, pool.zero_id))
        path_f = path & pool.diagram(pool.internal(LinearTest(~operator), pool.one_id, pool.zero_id))

        return (bounds_t, path_t), (bounds_f, path_f)

    def visit_terminal(self, terminal_node, parent_message):
        print(parent_message, terminal_node.expression)
        if parent_message is None:
            parent_message = self._initial_message()

        bounds, path = parent_message

        pool = self.diagram.pool
        if terminal_node.expression == 0:
            return pool.diagram(pool.zero_id)
        elif len(terminal_node.expression.free_symbols) == 0:
            return path * pool.diagram(terminal_node.node_id)
        else:
            variables_present = terminal_node.expression.free_symbols
            # FIXME todo
            return pool.diagram(pool.zero_id)

    def _initial_message(self):
        return {}, self.diagram.pool.diagram(self.diagram.pool.one_id)
Esempio n. 9
0
    def test_linear_reduce_1(self):
        diagram1 = self.build_diagram_1()
        # self.exporter.export(diagram1, "diagram1")
        variables = [("x", 0, 11)]

        reduced_linear1 = diagram1.pool.diagram(LinearReduction(diagram1.pool).reduce(diagram1.root_id))
        # self.exporter.export(reduced_linear1, "reduced_linear1")
        self.control(variables, diagram1, reduced_linear1)

        reduced_smt1 = diagram1.pool.diagram(SmtReduce(diagram1.pool).reduce(diagram1.root_id))
        # self.exporter.export(reduced_smt1, "reduced_smt1")
        self.control(variables, diagram1, reduced_smt1)

        reduced_simple1 = diagram1.pool.diagram(SimpleBoundReducer(diagram1.pool).reduce(diagram1.root_id))
        # self.exporter.export(reduced_simple1, "reduced_simple1")
        self.control(variables, diagram1, reduced_simple1)
Esempio n. 10
0
 def test_reduce(self):
     self.exporter.export(self.diagram, "to_reduce")
     result = LinearReduction(self.diagram.pool).reduce(
         self.diagram.root_node.node_id, ["x"])
     self.exporter.export(Diagram(self.diagram.pool, result), "result")
Esempio n. 11
0
 def __init__(self, diagram, diagram_vars):
     DownUpWalker.__init__(self, diagram)
     self._diagram_vars = diagram_vars
     self._reduction = LinearReduction(self.diagram.pool)
Esempio n. 12
0
 def test_reduce(self):
     diagram = build_diagram_1()
     result = LinearReduction(diagram.pool).reduce(diagram.root_id, ["r", "c"])
     result = diagram.pool.diagram(result)
     self.assertEqual(3, get_terminal_count(result))