Esempio n. 1
0
def _add_splines(c, b1, d, b2, x):
    """Construct c*b1 + d*b2."""

    if S.Zero in (b1, c):
        rv = piecewise_fold(d * b2)
    elif S.Zero in (b2, d):
        rv = piecewise_fold(c * b1)
    else:
        new_args = []
        # Just combining the Piecewise without any fancy optimization
        p1 = piecewise_fold(c * b1)
        p2 = piecewise_fold(d * b2)

        # Search all Piecewise arguments except (0, True)
        p2args = list(p2.args[:-1])

        # This merging algorithm assumes the conditions in
        # p1 and p2 are sorted
        for arg in p1.args[:-1]:
            expr = arg.expr
            cond = arg.cond

            lower = _ivl(cond, x)[0]

            # Check p2 for matching conditions that can be merged
            for i, arg2 in enumerate(p2args):
                expr2 = arg2.expr
                cond2 = arg2.cond

                lower_2, upper_2 = _ivl(cond2, x)
                if cond2 == cond:
                    # Conditions match, join expressions
                    expr += expr2
                    # Remove matching element
                    del p2args[i]
                    # No need to check the rest
                    break
                elif lower_2 < lower and upper_2 <= lower:
                    # Check if arg2 condition smaller than arg1,
                    # add to new_args by itself (no match expected
                    # in p1)
                    new_args.append(arg2)
                    del p2args[i]
                    break

            # Checked all, add expr and cond
            new_args.append((expr, cond))

        # Add remaining items from p2args
        new_args.extend(p2args)

        # Add final (0, True)
        new_args.append((0, True))

        rv = Piecewise(*new_args, evaluate=False)

    return rv.expand()
Esempio n. 2
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d * b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c * b1)
    else:
        new_args = []
        n_intervals = len(b1.args)
        assert (n_intervals == len(b2.args))
        new_args.append((c * b1.args[0].expr, b1.args[0].cond))
        for i in range(1, n_intervals - 1):
            new_args.append((c * b1.args[i].expr + d * b2.args[i - 1].expr,
                             b1.args[i].cond))
        new_args.append((d * b2.args[-2].expr, b2.args[-2].cond))
        new_args.append(b2.args[-1])
        rv = Piecewise(*new_args)

    return rv.expand()
Esempio n. 3
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d * b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c * b1)
    else:
        new_args = []
        n_intervals = len(b1.args)
        if n_intervals != len(b2.args):
            raise ValueError("Args of b1 and b2 are not equal")
        new_args.append((c * b1.args[0].expr, b1.args[0].cond))
        for i in range(1, n_intervals - 1):
            new_args.append((c * b1.args[i].expr + d * b2.args[i - 1].expr,
                             b1.args[i].cond))
        new_args.append((d * b2.args[-2].expr, b2.args[-2].cond))
        new_args.append(b2.args[-1])
        rv = Piecewise(*new_args)

    return rv.expand()
Esempio n. 4
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d*b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c*b1)
    else:
        new_args = []
        n_intervals = len(b1.args)
        assert(n_intervals == len(b2.args))
        new_args.append((c*b1.args[0].expr, b1.args[0].cond))
        for i in range(1, n_intervals - 1):
            new_args.append((
                c*b1.args[i].expr + d*b2.args[i - 1].expr,
                b1.args[i].cond
            ))
        new_args.append((d*b2.args[-2].expr, b2.args[-2].cond))
        new_args.append(b2.args[-1])
        rv = Piecewise(*new_args)

    return rv.expand()
Esempio n. 5
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d*b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c*b1)
    else:
        new_args = []
        n_intervals = len(b1.args)
        if n_intervals != len(b2.args):
            raise ValueError("Args of b1 and b2 are not equal")
        new_args.append((c*b1.args[0].expr, b1.args[0].cond))
        for i in range(1, n_intervals - 1):
            new_args.append((
                c*b1.args[i].expr + d*b2.args[i - 1].expr,
                b1.args[i].cond
            ))
        new_args.append((d*b2.args[-2].expr, b2.args[-2].cond))
        new_args.append(b2.args[-1])
        rv = Piecewise(*new_args)

    return rv.expand()
Esempio n. 6
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d * b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c * b1)
    else:
        new_args = []
        # Just combining the Piecewise without any fancy optimization
        p1 = piecewise_fold(c * b1)
        p2 = piecewise_fold(d * b2)

        # Search all Piecewise arguments except (0, True)
        p2args = list(p2.args[:-1])

        # This merging algorithm assumes the conditions in
        # p1 and p2 are sorted
        for arg in p1.args[:-1]:
            # Conditional of Piecewise are And objects
            # the args of the And object is a tuple of two
            # Relational objects the numerical value is in the .rhs
            # of the Relational object
            expr = arg.expr
            cond = arg.cond

            lower = cond.args[0].rhs

            # Check p2 for matching conditions that can be merged
            for i, arg2 in enumerate(p2args):
                expr2 = arg2.expr
                cond2 = arg2.cond

                lower_2 = cond2.args[0].rhs
                upper_2 = cond2.args[1].rhs

                if cond2 == cond:
                    # Conditions match, join expressions
                    expr += expr2
                    # Remove matching element
                    del p2args[i]
                    # No need to check the rest
                    break
                elif lower_2 < lower and upper_2 <= lower:
                    # Check if arg2 condition smaller than arg1,
                    # add to new_args by itself (no match expected
                    # in p1)
                    new_args.append(arg2)
                    del p2args[i]
                    break

            # Checked all, add expr and cond
            new_args.append((expr, cond))

        # Add remaining items from p2args
        new_args.extend(p2args)

        # Add final (0, True)
        new_args.append((0, True))

        rv = Piecewise(*new_args)

    return rv.expand()
Esempio n. 7
0
def _add_splines(c, b1, d, b2):
    """Construct c*b1 + d*b2."""
    if b1 == S.Zero or c == S.Zero:
        rv = piecewise_fold(d*b2)
    elif b2 == S.Zero or d == S.Zero:
        rv = piecewise_fold(c*b1)
    else:
        new_args = []
        n_intervals = len(b1.args)
        if n_intervals != len(b2.args):
            # Args of b1 and b2 are not equal. Just combining the Piecewise without any fancy optimisation
            p1 = piecewise_fold(c*b1)
            p2 = piecewise_fold(d*b2)

            # Search all Piecewise arguments except (0, True)
            p2args = list(p2.args[:-1])

            # This merging algorithm assume the conditions in p1 and p2 are sorted
            for arg in p1.args[:-1]:
                # Conditional of Piecewise are And objects
                # the args of the And object is a tuple of two Relational objects
                # the numerical value is in the .rhs of the Relational object
                expr = arg.expr
                cond = arg.cond

                lower = cond.args[0].rhs

                # Check p2 for matching conditions that can be merged
                for i, arg2 in enumerate(p2args):
                    expr2 = arg2.expr
                    cond2 = arg2.cond

                    lower_2 = cond2.args[0].rhs
                    upper_2 = cond2.args[1].rhs

                    if cond2 == cond:
                        # Conditions match, join expressions
                        expr += expr2
                        # Remove matching element
                        del p2args[i]
                        # No need to check the rest
                        break
                    elif lower_2 < lower and upper_2 <= lower:
                        # Check if arg2 condition smaller than arg1, add to new_args by itself (no match expected in p1)
                        new_args.append(arg2)
                        del p2args[i]
                        break

                # Checked all, add expr and cond
                new_args.append((expr, cond))

            # Add remaining items from p2args
            new_args.extend(p2args)

            # Add final (0, True)
            new_args.append((0, True))
        else:
            new_args.append((c*b1.args[0].expr, b1.args[0].cond))
            for i in range(1, n_intervals - 1):
                new_args.append((
                    c*b1.args[i].expr + d*b2.args[i - 1].expr,
                    b1.args[i].cond
                ))
            new_args.append((d*b2.args[-2].expr, b2.args[-2].cond))
            new_args.append(b2.args[-1])

        rv = Piecewise(*new_args)

    return rv.expand()