# What is the difference between Reduce and Solve?

Solve and Reduce both can be used for solving equations.

Just by working with them, I know there are some differences between them. but that is about all I know, and I want to know what the differences are.

In Some Notes on Internal Implementation especially in Algebra and Calculus one finds interesting subtleties and differences between these two functions, e.g.

The code for Solve and related functions is about 500 pages long.

Reduce and related functions use about 350 pages of Mathematica code
and 1400 pages of C code.


There is much more than a little difference between them. The most important is :

• Reduce returns results of computation as boolean formulae and gives complete description of solution sets.
• Solve returns lists of replacement rules yielding generic solutions.

An important step toward more complete description of solution sets was a new option of Solve in Mathematica 8, namely MaxExtraConditions (default value 0). Using MaxExtraConditions -> All in Solve provides complete solutions for algebraic equations, nevertheless we have to emphasize that sometimes we might better work with Reduce rather than Solve (regardless of any options added) because replacement rules may appear not a good fit in description of solutions in the real or complex domain to algebraic equations as well as to trancendental equations˛ Distinction between genericity and completness does not make sense in the Integers, an example provided below.

Solve[expr,vars] assumes by default that quantities appearing algebraically in
inequalities are real, while all other quantities are complex.
We have the same issue with Reduce[expr,vars].


## Example : Solve cannot find solutions in the real domain

Consider a simple symbolic case in the real domain where Solve does not work even with MaxExtraConditions -> All :

Solve[ x^2 + y^2 <= r^2, {x, y}, MaxExtraConditions -> All]

Solve::fdimc: When parameter values satisfy the condition r ∈ Reals, the solution set
contains a full-dimensional component; use Reduce for complete solution information. >>

{}

Reduce[ x^2 + y^2 <= r^2, {x, y}]

r ∈ Reals && ((x == -Sqrt[r^2] && y == 0) ||
(-Sqrt[r^2] < x < Sqrt[r^2] && -Sqrt[r^2 - x^2] <= y <= Sqrt[r^2 - x^2]) ||
(x == Sqrt[r^2] && y == 0))


We have found none solutions with Solve. We should remember that we can find instances in the real domain with :

fi = FindInstance[ x^2 + y^2 <= 9, {x, y}, 5]

{{x -> 83/84, y -> 31/18}, {x -> 3, y -> 0}, {x -> 83/84, y -> (13 Sqrt[335])/84},
{x -> 5/28, y -> -(Sqrt[7031]/28)}, {x -> 37/21, y -> (10 Sqrt[26])/21}}


However for the same inequality we can find all solutions with Solve in the integers.

## Example : Solve provides solutions in the integer domain

s = {x, y} /. Solve[ x^2 + y^2 <= 9, {x, y}, Integers];
r = (List @@@ List @@ Reduce[ x^2 + y^2 <= 9, {x, y}, Integers])[[All, All, 2]]
r == s

True


Here the blue region represents solutions described by Reduce while the red points on the left plot are instances found with FindInstance in the real domain, whereas on the right plot there are all solutions found by Solve in the Integers :

GraphicsRow[{ RegionPlot[ x^2 + y^2 <= 9, {x, -5, 5}, {y, -5, 5},
Epilog -> {Red, PointSize[0.015], Point[fi[[All, All, 2]]]}],
RegionPlot[ x^2 + y^2 <= 9, {x, -5, 5}, {y, -5, 5},
Epilog -> {Red, PointSize[0.015], Point[s]}]}]


## Example : Genericity can be advantageous for symbolic transcendental equations

Genericity of Solve output sometimes can be advantageous, e.g. compare

Solve[ x^c == 5, x]

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be
found; use Reduce for complete solution information. >>

{{x -> 5^(1/c)}}


Solve yields this solution immediately, while Reduce after ~ 10 seconds yields a huge boolean formula, here is a little part of it :

Reduce[ x^c == 5, x][[3, 2]]

C[1] <= -1 && (2 π  C[1] - Sqrt[4 π ^2 C[1]^2 + Log[5]^2])/( 2 π ) < Re[c] < 2 C[1] &&
Im[c] <= (-Log[5] - Sqrt[ Log[5]^2 + 8 π ^2 C[1] Re[c] - 4 π ^2 Re[c]^2])/(2 π ) &&
x == E^((2 I π  C[1] + Log[5])/c)


There are another examples where we would rather use Reduce rather than Solve with specification MaxExtraConditions -> All because a list of replacement rules cannot express the full solution unlike a boolean form.

## Example : Solve cannot find the complete solution set

Even with MaxExtraConditions -> All option Solve sometimes fails which may be seen when we work e.g. with real variables, e.g. :

Normal @ Solve[ a x^2 == c && b x^3 == d, x, Reals, MaxExtraConditions -> All]

Solve::fdimc: When parameter values satisfy the condition d == 0 && b== 0 &&
c == 0 && a == 0,
the solution set contains a full-dimensional component; use Reduce for complete
solution information. >>

{{x -> 0}, {x -> -Sqrt[(c/a)]}, {x -> Sqrt[c/a]}, {x -> Root[-d + b #1^3 &, 1]}}


We have used here Normal to get rid of ConditionalExpressions.

 Reduce[ a x^2 == c && b x^3 == d, x, Reals]


For a nice discussion of these topics see this presentation Getting the Most from Algebraic Solvers in Mathematica by Adam Strzeboński during Wolfram Technology Conference 2011.

## Example : Further issues

Solve yields exlicit formulae for the solutions (in terms of radicals) to equations whenever it is possible (it is always possible for univariate algebraic (polynomial) equations up to the order four). For more detailed discussion see e.g. : How do I work with Root objects?.

You can find more specific differences examining carefully this :

Options /@ {Reduce, Solve} // Column

{ Backsubstitution -> False, Cubics -> False, GeneratedParameters -> C,
Method -> Automatic, Modulus -> 0, Quartics -> False,
WorkingPrecision -> Infinity}
{ Cubics -> True, GeneratedParameters -> C, InverseFunctions -> Automatic,
MaxExtraConditions -> 0, Method -> Automatic, Modulus -> 0, Quartics -> True,
VerifySolutions -> Automatic, WorkingPrecision -> Infinity }


And even more systematic discussion of the differences might include SystemOptions["ReduceOptions"]. For some sketches of their usage take a look at this reference Real Polynomial Systems.

SystemOptions["ReduceOptions"] // Short[#, 5] &

{ "ReduceOptions" -> {"ADDSolveBound" -> 8, "AlgebraicNumberOutput" -> True,
"BDDEliminate" -> Automatic, "BooleanInstanceMethod" -> Automatic, <<21>>,
"UseNestedRoots" -> Automatic, "UseOldReduce" -> False,
"UseTranscendentalRoots" -> Automatic, "UseTranscendentalSolve" -> True}}


These issues could be systematically discussed only with concrete examples, so that the main question has to be investigated on a case-by-case basis. See e.g. Solving/Reducing equations in $\mathbb{Z}/p\mathbb{Z}$ for a discussion of ExhaustiveSearchMaxPoints.

Edit

Another answer by Itai Seggev says that by specifying Method -> Reduce in Solve, Solve will use Reduce behind the scenes to produce an answer. That is not quite true. Here is an example : Solve with Method -> Reduce gives a different result than Reduce.

Another statement therein not precise or incorrect is :

"Reduce can deal with the following logical conjunction of inequalities, while Solve cannot."

Solve works well with logical conjunction of inequalities (see e.g. Solve an equation in $\mathbb{R}^+$), let's slightly modify the system :

Solve[ x^2 < 1 && Sin[x] == Cos[x], x]
Reduce[ x^2 < 1 && Sin[x] == Cos[x], x]
Reduce[x^2 < 1 && Sin[x] < Cos[x], x]

{{x -> -2 ArcTan[1 - Sqrt[2]]}}
x == -2 ArcTan[1 - Sqrt[2]]
-1 < x < -2 ArcTan[1 - Sqrt[2]]


whereas the issue here is just mentioned above that the solution set contains a full-dimensional component (in the real domain). For comparison let's see how it works in the integer domain :

Solve[ x^2 < 2 && Sin[x] < Cos[x], x, Integers]
Reduce[ x^2 < 2 && Sin[x] < Cos[x], x, Integers]

{{x -> -1}, {x -> 0}}
x == -1 || x == 0

• I don't know how I missed this answer until today, but a hearty +1. Nice presentation. :-) – Mr.Wizard Aug 11 '17 at 22:48
• @Mr.Wizard Thanks. I guess I still could improve this answer since a few important details I have in mind to add. – Artes Aug 12 '17 at 20:27

Since version 8, Solve and Reduce share a great deal of code. In fact, by Specifying Method -> Reduce in Solve, Solve will use Reduce behind the scenes to produce an answer. Off the top of my head, the key differences are as follows:

1) Reduce simplifies logical statements, while Solve solves equations. This means that given a logical statement (equations, inequalities or quantified statements), Reduce will attempt to give you an equivalent, but simpler, statement. For equations, these statements can often directly be solutions, but are still expression as logical expressions like x==0. Solve, on the other hand, tries to give you solutions, so it returns a list of replacement rules like x -> 0 which you can substitute back into your equation to verify its correctness.

Simple example: Reduce can deal with the following logical conjunction of inequalities, while Solve cannot.

Reduce[x^2 < 1 && Sin[x] < Cos[x], x]
(* Out: -1 < x < -2 ArcTan[1 - Sqrt[2]] *)


2) By default, Solve will only give you answers which are generically correct, meaning they don't rely on special values of parameters and may not be completely equivalent to the original equations. Reduce, on the other hand, does not do any transformations which might cause the logical statement to be changed or solutions to be missed.

Simple example: Reduce considers the possibility that the parameter a is zero, while Solve does not.

Solve[a*x == 0, x]
(* Out: {{x -> 0}} *)

Reduce[a*x == 0, x]
(* Out: a == 0 || x == 0 *)


3) Solve tends to be less thorough than Reduce in order to return an answer faster (somewhat like Simplify vs. FullSimplify).

• This is a nice answer. Could you please give an example for point 2 on this part: "[...] may not be completely equivalent to the original equations"? – István Zachar Dec 31 '12 at 9:51
• @IstvánZachar I added simple examples for both points 1 and 2. Of course, Itai, is free to change or modify those, but I do think some example is helpful. – Mark McClure Dec 31 '12 at 10:06
• Interestingly, Reduce and Solve work even without variable specification and in this case may return identical answers: Reduce[a*x == 0], Solve[a*x == 0]. – Alexey Popkov Dec 31 '12 at 14:57