20
$\begingroup$

I have an inequality expression that I would like to express in terms of the relation of the parameters to zero. More simply, I want to have mathematica move all the terms to one side of the inequality so that it is expressed as $x - y \geq 0$. Currently it is expressed as $x \geq y$. The expressions inside $x$ and $y$ are much more complex, of course.

Is this possible? It seems I need to provide some assumptions about the relations between variables, but it isn't clear to me how to do this.

$\endgroup$
1
  • 2
    $\begingroup$ have you tried a rule like : x > y /. (Greater[x_, y_] -> Greater[x - y, 0]) $\endgroup$ May 1, 2012 at 15:19

5 Answers 5

19
$\begingroup$

Are you looking for Subtract?

eq=x>=y
Subtract@@eq>=0

gives:

x-y>=0

Edit

If one wants a function, which keeps the order sign and adds the 0, one may use:

oneSide=(Head[#][Subtract@@#,0]&)

and call e.g. eq//oneSide

$\endgroup$
2
  • 3
    $\begingroup$ Subtract @@ is a clever answer, +1. $\endgroup$
    – rcollyer
    May 1, 2012 at 15:35
  • 3
    $\begingroup$ This solution requires you to put the inequality back by hand after the Subtract. It shouldn't be necessary to do that. $\endgroup$
    – Jens
    May 1, 2012 at 15:54
13
$\begingroup$

Since Mathematica 11.3 you can use SubtractSides, that works for equations and inequalities, for example

eqns = {
   x >= y,
   x^2 == b c + c,
   2 x < x + 1
   };

SubtractSides /@ eqns
(* {x - y >= 0, -c - b c + x^2 == 0, -1 + x < 0} *)

Mathematica graphics

$\endgroup$
12
$\begingroup$

This approach works by using the fact that an inequality or equality can be traversed by Map in the same way that a regular list can. It can take an arbitrary inequality or equation eqn, and you don't have to know in advance whether it's >, < or anything else. First I define the equation eqn, and then I use the fact that the second part of eqn is the right-hand side (eqn[[2]]) which I want to subtract from both sides:

eqn = (x > y + z)
Map[(# - eqn[[2]]) &, eqn]

-y - z > 0

You could adapt it to bring only part of the right-hand side to the left, e.g. the y but not z:

Map[(# - eqn[[2, 1]]) &, eqn]

x - y > z

Edit

By the way, using Map on an equation is a "natural" choice in this situation, because manipulating equations always involves doing the same thing on both sides. That "thing" can be formulated as applying a function f[...] to both sides. In this example it's a subtraction operation, but it could also be the operation of squaring both sides, multiplying them by a factor, expanding in a power series, and whatever else you might think of. In Mathematica, Map is the operation that corresponds to this type of manipulation.

With inequalities, you just have to be more careful than with equalities because doing the same thing on both sides doesn't always leave the relation unchanged (think of multiplying by a negative number). In this question, that problem didn't arise because addition and subtraction don't cause inequalities to break.

Edit 2

One should also realize that inequalities and equations (i.e., Equal and Greater etc.) can have two or more arguments, as in

eqn = (x > y > z)

The answers by Peter and Pillsy do not take this into account, whereas the Map approach works naturally in these cases, too:

Map[(# - Last[eqn]) &, eqn]

x - z > y - z > 0

There has in fact been some discussion long ago if one should make the Equal function in Mathematica "listable" so that it applies this Map process automatically when you type eqn - Last[eqn], but there are cases when that's not desirable (e.g., when taking the square root on both sides due to multi-valuedness), so we have to do it ourselves when needed.

In the spirit of hiding the Map code from the user, one can of course define a function like Peter does, i.e., in my case

Clear[oneSide]; oneSide[e_] := Map[(# - Last[e]) &, e]
$\endgroup$
8
$\begingroup$

I think that this problem (like most algebraic manipulations) is best approached with pattern matching and rule replacement than by directly exploiting the index/list structure that inequalities share with practically every Mathematica expression. Both approaches will work, but rule replacement is, in my opinion, clearer, more precise, more flexible, and more extensible. For example:

moveTermRule =
  (ineq : Less | Greater | LessEqual | GreaterEqual)[lhs_, rhs_] :>
   ineq[lhs - rhs, 0];

In[137]:= x <= y /. moveTermRule
Out[137]= x - y <= 0

This won't do anything to expressions that aren't inequalities, or that have more than two arguments, and everything ends up with a name by the nature of RuleDelayed, which makes it more obvious what's happening.

$\endgroup$
6
$\begingroup$

An alternative to Jens's solution makes use of Thread[] to subtract the rightmost entity of a relation from both sides:

oneSide[ineq : (_Equal | _Unequal | _Less | _Greater | _LessEqual | _GreaterEqual)] := 
        Thread[ineq - Last[ineq], Head[ineq]]

None of the solutions given thus far will work on more general Inequality[] objects like x < y <= z, though Jens's approach can be modified somewhat:

Map[If[FreeQ[#, Less | Greater | GreaterEqual | LessEqual], # - z, #] &, x < y <= z]
   x - z < y - z <= 0

Thus,

oneSide[ineq_Inequality] :=
     Map[If[FreeQ[#, Less | Greater | GreaterEqual | LessEqual], # - Last[ineq], #] &, ineq]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.