Him
Him

Reputation: 5551

Sympy simplify inequalities with square multiples

I have an inequality that is riddled with factors that are a priori positive for real-valued variables. It would be nice if I could get sympy to just 'deal with them'.

For example:

import sympy
x,y = sympy.symbols('x y')
sympy.simplify((x**2 + 1)*y > 0)
# (x**2+1)*y > 0 (sympy does nothing)

Now, it seems pretty clear that (x**2+1)*y > 0 iff y>0 since (x**2+1) is always positive for real x. In other words, some reasonable function of simplifying such things might give:

simplify_positive_terms((x**2+1)*y > 0)
# y > 0 

Is there a sympy function that will allow it to simplify these sort of things?

Note that the above is only a simple example, and I do not, in general, just want to solve for y.

Upvotes: 1

Views: 156

Answers (1)

Yakov Dan
Yakov Dan

Reputation: 3347

Here's what I came up with:

import sympy

def simplify_inequality(e):
    ''' 
    Assume e is an instance of either one of the following:
    sympy.core.relational.StrictGreaterThan
    sympy.core.relational.GreaterThan
    sympy.core.relational.StrictLessThan
    sympy.core.relational.LessThan

    Also, assume that the e is an inequality of the form Mul(f,g..,z) > 0

    '''
    lefthand_side = e.args[0]
    righthand_side= e.args[1]
    if not isinstance(lefthand_side,sympy.mul.Mul):
        return e

    multiplicands = lefthand_side.args
    needed_factors = []
    for factor in multiplicands:
        if len(factor.free_symbols) != 1: # if it has more than one variable, don't try to simplify
            needed_factors.append(factor)

        else:
            result_set = sympy.solveset(factor,factor.free_symbols.pop(),sympy.S.Reals) # see if there are any solutions over the reals   
            if not result_set.is_EmptySet: # there are solutions, this factor is can't be simplified
                needed_factors.append(factor)
            else:    
                free_sym = factor.free_symbols.pop()
                if factor.subs(free_sym,0) > 0: # ok, this factor is always positive, it can go away
                    pass
                else: # we still need it
                    needed_factors.append(factor)

    new_lefthand_side = sympy.mul.Mul(*needed_factors)
    return e.func(*(new_lefthand_side,righthand_side))

This should work on inequalities of the type you provided. This function won't simplify factors that are a priori negative, or that are multivariate. But I think it's a reasonable starting point

Upvotes: 1

Related Questions