Edit: I must precise that I am using Mathematica 8
Okay one month later I've faced this problem at a far large scale, and so I resolved to create my own batch of rules. I must have done it in the least elegant way possible, but for the sake of whoever may face the same sort of problems, here is my batch of functions putting this sort of equations under a form agreeable to Reduce.
I have tested them on my own equations but cannot guarantee the absence of a bug, however hopefully the general idea is clear enough for anyone to build their own version.
Only the last function needs to be used explicitly, applied to the expression before Reduce, and right now it is explicitly geared toward Real solutions with no coefficient equal to zero.
First some tools (I swear I did not find convincing alternatives in the doc, but I might be utterly blind):
Logical[exp_] := !
FreeQ[{Greater, Less, Or, And, Not, Equal, Unequal, LessEqual,
GreaterEqual}, Head[exp]]
(*determines whether an expression is logical, obviously*)
MapList[func_, exp_] := Reap[Scan[Sow[func[#]] &, exp]][[2, 1]]
(*returns a list of the elements of an expression (not a list) with func applied to them*)
TrueCoefficient[poly_, var_, x_] :=
Coefficient[ Coefficient[poly, var, x], var, 0]
(* avoids a strange bug in Coefficient*)
TruerCoefficient[poly_, var_, x_] :=
With[{normal = TrueCoefficient[poly, var, x]},
If[normal === 0, TrueCoefficient[Simplify[poly], var, Simplify[x]],
normal]]
(*avoids problem of coefficients associated with exponents formally equal but written differently*)
FullTerm[exp_, var_, x_] :=
var^ex TruerCoefficient[exp, var, x]
(*returns the real term in expression exp where var appears with power x*)
Then the meat :
SymbPower[exp_, pow_] :=
FullSimplify[
If[Logical[exp] || Head[exp] === Times,
Map[SymbPower[#, pow] &, exp], Power[exp, pow]],
Assumptions -> {x_ \[Element] Reals}]
(*Distributes power pow over expression exp to avoid conundrums like (a y^x)^(1/x) not being simplified in y and blocking Reduce*)
RemPower[exp_, var_] :=
PiecewiseExpand[
With[{side =
If[MapList[Count[#, var, Infinity] &, exp] === {1, 0}, 1, 2]},
With[{x = TrueExponent[exp[[side]], var]},
If[x === 0 || x === 1, exp,
With[{result = Map[SymbPower[#, 1/x] &, exp]},
If[x > 0, result,
result /. {Less -> Greater, Greater -> Less,
LessEqual -> GreaterEqual, GreaterEqual -> LessEqual} ] ]]]]]
(*Carelessly takes the root when a formal power is involved and Reduce refuses to do anything. Caution should be applied before use.*)
TwoToOne[exp_, var_] :=
With[{cnt = MapList[Count[#, var, Infinity] &, exp]},
Which[cnt === {1, 1}, Map[#/exp[[2]] &, exp], cnt === {0, 2},
If[exp[[1]] === 0, TwoToOne[Map[# - exp[[2, 2]] &, exp], var],
exp], cnt == {2, 0}, TwoToOne[Head[exp][exp[[2]], exp[[1]]], var],
True, exp]]
(*from y^a - C y^b = 0 to y^(a-b)=C *)
VariableOnHS[exp_, var_] :=
With[{cnt = MapList[Count[#, var, Infinity] &, exp]},
With[{side = If[cnt === {1, 0}, 1, 2]},
Which[Length[TermList[exp[[side]], var ]] == 1, exp,
Plus @@ cnt === 1,
With[{si = FullTerm[exp[[side]], var, 0]}, Map[# - (si) &, exp]],
True, exp]]]
(*puts the variable alone on one hand-side of the equation*)
CanonicalForm[exp_, var_] :=
With[{cnt = MapList[Count[#, var, Infinity] &, exp]},
Which[Plus @@ cnt === 0, exp, Plus @@ cnt === 1,
RemPower[VariableOnHS[exp, var], var], Plus @@ cnt === 2,
With[{simp = TwoToOne[exp, var]},
If[Count[simp, var, Infinity] === 1, CanonicalForm[simp, var],
exp]], FreeQ[MapList[Logical, exp], True], exp, True,
Map[CanonicalForm[#, var] &, exp]]]
(*everything put together, ready to use in Reduce*)
Apologies for the mammoth post.
Any more elegant alternative will be embraced and rewarded with eternal gratitude.
N
as a variable name as it's a Function in Mathematica already. $\endgroup$ – Jonathan Shock May 15 '13 at 5:21Reduce
. The firstReduce
also gets a better solution of(N > 1 && x < y) || (0 < N < 1 && x > y)
. $\endgroup$ – Sjoerd C. de Vries May 15 '13 at 8:06