예제 #1
0
    def value(self, add):
        for term in add.args:
            if term.is_number or term in self.bounds or len(
                    term.free_symbols) != 1:
                continue
            fs, = term.free_symbols
            if fs not in self.bounds:
                continue
            intrvl = Interval(*self.bounds[fs])
            if is_increasing(term, intrvl, fs):
                self.bounds[term] = (term.subs({fs: self.bounds[fs][0]}),
                                     term.subs({fs: self.bounds[fs][1]}))
            elif is_decreasing(term, intrvl, fs):
                self.bounds[term] = (term.subs({fs: self.bounds[fs][1]}),
                                     term.subs({fs: self.bounds[fs][0]}))
            else:
                return add

        if all(term.is_number or term in self.bounds for term in add.args):
            bounds = [(term, term) if term.is_number else self.bounds[term]
                      for term in add.args]
            largest_abs_guarantee = 0
            for lo, hi in bounds:
                if lo <= 0 <= hi:
                    continue
                largest_abs_guarantee = max(largest_abs_guarantee,
                                            min(abs(lo), abs(hi)))
            new_terms = []
            for term, (lo, hi) in zip(add.args, bounds):
                if max(abs(lo),
                       abs(hi)) >= largest_abs_guarantee * self.reltol:
                    new_terms.append(term)
            return add.func(*new_terms)
        else:
            return add
예제 #2
0
def test_is_increasing():
    assert is_increasing(x**3 - 3*x**2 + 4*x, S.Reals)
    assert is_increasing(-x**2, Interval(-oo, 0))
    assert is_increasing(-x**2, Interval(0, oo)) is False
    assert is_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval(-2, 3)) is False
    assert is_increasing(x**2 + y, Interval(1, oo), x) is True
    assert is_increasing(-x**2*a, Interval(1, oo), x) is True
    assert is_increasing(1) is True
예제 #3
0
def test_is_increasing():
    """Test whether is_increasing returns correct value."""
    a = Symbol('a', negative=True)

    assert is_increasing(x**3 - 3*x**2 + 4*x, S.Reals)
    assert is_increasing(-x**2, Interval(-oo, 0))
    assert not is_increasing(-x**2, Interval(0, oo))
    assert not is_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval(-2, 3))
    assert is_increasing(x**2 + y, Interval(1, oo), x)
    assert is_increasing(-x**2*a, Interval(1, oo), x)
    assert is_increasing(1)

    assert is_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval(-2, 3)) is False
예제 #4
0
def test_is_increasing():
    """Test whether is_increasing returns correct value."""
    a = Symbol('a', negative=True)

    assert is_increasing(x**3 - 3*x**2 + 4*x, S.Reals)
    assert is_increasing(-x**2, Interval(-oo, 0))
    assert not is_increasing(-x**2, Interval(0, oo))
    assert not is_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval(-2, 3))
    assert is_increasing(x**2 + y, Interval(1, oo), x)
    assert is_increasing(-x**2*a, Interval(1, oo), x)
    assert is_increasing(1)
예제 #5
0
    def value(self, add):
        for term in add.args:
            if term.is_number or term in self.bounds or len(term.free_symbols) != 1:
                continue
            fs, = term.free_symbols
            if fs not in self.bounds:
                continue
            intrvl = Interval(*self.bounds[fs])
            if is_increasing(term, intrvl, fs):
                self.bounds[term] = (
                    term.subs({fs: self.bounds[fs][0]}),
                    term.subs({fs: self.bounds[fs][1]})
                )
            elif is_decreasing(term, intrvl, fs):
                self.bounds[term] = (
                    term.subs({fs: self.bounds[fs][1]}),
                    term.subs({fs: self.bounds[fs][0]})
                )
            else:
                return add

        if all(term.is_number or term in self.bounds for term in add.args):
            bounds = [(term, term) if term.is_number else self.bounds[term] for term in add.args]
            largest_abs_guarantee = 0
            for lo, hi in bounds:
                if lo <= 0 <= hi:
                    continue
                largest_abs_guarantee = max(largest_abs_guarantee,
                                            min(abs(lo), abs(hi)))
            new_terms = []
            for term, (lo, hi) in zip(add.args, bounds):
                if max(abs(lo), abs(hi)) >= largest_abs_guarantee*self.reltol:
                    new_terms.append(term)
            return add.func(*new_terms)
        else:
            return add
예제 #6
0
def test_issue_23401():
    x = Symbol('x')
    expr = (x + 1) / (-1.0e-3 * x**2 + 0.1 * x + 0.1)
    assert is_increasing(expr, Interval(1, 2), x)
예제 #7
0
def check_constraints(model,
                      constraints,
                      intervals,
                      characteristic_vals=None,
                      verbose=0):
    """WIP function for Tc project.
    UseS Sympy to check for singularities and other limits."""
    intervals = dict(intervals)
    feature_set = list(constraints.keys())
    if characteristic_vals is None:
        characteristic_vals = {
            feature: i / 10
            for i, feature in enumerate(feature_set)
        }
    for feature in feature_set:
        if feature not in intervals.keys():
            intervals[feature] = sympy.Reals
            continue
        interval_min, interval_max = intervals[feature]
        if interval_min == "-oo" or interval_min == -np.inf:
            interval_min = -oo
        elif interval_max == "oo" or interval_max == np.inf:
            interval_max = oo
        interval = Interval(interval_min, interval_max)
        intervals[feature] = interval

    symbol_dict = {
        k: v
        for k, v in zip(
            feature_set,
            sympy.symbols(
                feature_set, positive=True, finite=True, infinite=False))
    }
    expr = parse_expr(model.replace('^', '**'), local_dict=symbol_dict)

    passed = True
    checks = {k: {} for k in constraints.keys()}
    for feature, symbol in symbol_dict.items():
        symbol_set = list(symbol_dict.values())
        variable = symbol_set.pop(symbol_set.index(symbol))
        interval = intervals[feature]

        univariate_expr = expr.subs([(symbol, characteristic_vals[str(symbol)])
                                     for symbol in symbol_set])
        if verbose > 1:
            print(univariate_expr)

        if constraints[feature].get('increasing', None) is not None:
            try:
                increasing = is_increasing(univariate_expr, interval=interval)
            except TypeError:
                increasing = False
            if increasing is None:  # bug?
                increasing = False
            checks[feature]['increasing'] = increasing
            if increasing != constraints[feature]['increasing']:
                passed = False

        if constraints[feature].get('decreasing', None) is not None:
            try:
                decreasing = is_decreasing(univariate_expr, interval=interval)
            except TypeError:
                decreasing = False
            if decreasing is None:  # bug?
                decreasing = False
            checks[feature]['decreasing'] = decreasing
            if decreasing != constraints[feature]['decreasing']:
                passed = False

        if constraints[feature].get('monotonic', None) is not None:
            try:
                monotonic = is_monotonic(univariate_expr, interval=interval)
            except TypeError:
                monotonic = False
            checks[feature]['monotonic'] = monotonic
            if monotonic != constraints[feature]['monotonic']:
                passed = False

        if constraints[feature].get('singularities', None) is not None:
            try:
                singularity_set = singularities(expr,
                                                variable,
                                                domain=interval)
            except TypeError:
                singularity_set = sympy.EmptySet
            checks[feature]['singularities'] = singularity_set
            # has_singularities = singularity_set is not sympy.EmptySet
            if singularity_set != constraints[feature]['singularities']:
                passed = False

        if constraints[feature].get('zero limit', None) is not None:
            try:
                zero_limit = sympy.limit(expr, variable, 0)
            except TypeError:
                zero_limit = None
            checks[feature]['zero limit'] = zero_limit
            if zero_limit != constraints[feature]['zero limit']:
                passed = False
    if verbose == 0:
        return passed
    else:
        return checks, passed