# Does Solve make internally assumptions about the domain of the variables?

I recently tried to invert the innocent looking function

$$\frac{x}{(1+\sqrt{1-x})^2}$$

So I tried the command

 Solve[x/(1 + Sqrt[1 - x])^2 == y, x],

which effectively immediately gives the result

{{x -> (4 y)/(1 + y)^2}} .

But now the problems begin. When I tried to verify the solution, it did not work out for all values. Inserting the solution results in

$$\frac{4 y}{(1 + y)^2 \left(1 + \sqrt{1 -\frac{4y}{(1 + y)^2} }\right)^2}$$,

which does not reduce to y by simple applications of //FullSimplify, //FunctionExpand, //PowerExpand etc. After some playing around, I realized that this expression is actually equal to y only inside of the unit disc, and outside of it to 1/y. So the solution holds only for some values of y and not globally.

I was rather surprised by this behaviour. The same happens if one tries InverseFunction, giving the same answer as Solve (as a function). Any ideas why this is happening or what can be done to obtain the correct solutions (without manually studying the function)? In this case this was rather easely repaired, but in general this can become quite complicated.

• Have you tried Reduce? That usually gives more detailed information about these sort of things. Also, Solve for me raises a warning message that the solution may not be completely general. Jun 3, 2021 at 7:52
• Reduce gives an unsolved equation. Which version of Mathematica are you using that you get this warning massage? In 12.0 I do not get it. Or is there a setting to produce more warnings? Even if I set the VerifySolutions->True option I do not get any warnings. Jun 3, 2021 at 8:08
• I'm on V12.3 right now. Jun 3, 2021 at 8:15
• At the end of the documentation for Solve, under "Possible Issues", you'll see that Solve gives "generic solutions", which means they work for most (but not necessarily all) values of the vars and params [See "Generic and Non-Generic Cases" at reference.wolfram.com/language/tutorial/… ] To obtain a genl result that includes the restrictions on the vars and params, you can use either Reduce, or Solve with the Method->Reduce option. [MaxExtraConditions->All will give all restrictions on the displayed solns, but not necessarily all solns.] Jun 3, 2021 at 8:27
• Can you formulate that comment as an answer such that I can accept it? The MaxExtraConditions->All option was exactly what I was looking for, in this case it results in a warning that the result depends on the branchcuts. Jun 3, 2021 at 9:01

At the end of the documentation for Solve, under "Possible Issues", you'll see that Solve gives "generic solutions", which means they work for most (but not necessarily all) values of the variables and parameters.

For more on this, see "Generic and Non-Generic Cases" at https://reference.wolfram.com/language/tutorial/MathematicalFunctions.html#16439

To see the restrictions on the parameters and variables, you can use Solve with the MaxExtraConditions->All option:

Solve[x/(1 + Sqrt[1 - x])^2 == y, x, MaxExtraConditions -> All]


But there are some caveats:

1)MaxExtraConditions->All will sometimes prevent Solve from giving a solution; in that case, you can instead try Solve with the Method->Reduce option, or Reduce; these will usually (but not always—see below) give a complete solution set with all the restrictions:

Solve[x Log[x] == a, x]
Solve[x Log[x] == a, x, MaxExtraConditions -> All]
Solve[x Log[x] == a, x, Method -> Reduce]
Reduce[x Log[x] == a, x]


2)While the documentation (Solve: Details and Options) says "With Method->Reduce, Solve uses only equivalent transformations and finds all solutions" [emphasis mine], this does not appear to always be the case. For instance, in the following, Method->Reduce misses the solution $$x = 1$$ when $$a = 0$$. This solution is found by Solve with the MaxExtraConditions->All option, and by Reduce:

Solve[a x^2 + x == 1, x]
Solve[a x^2 + x == 1, x, MaxExtraConditions -> All]
Solve[a x^2 + x == 1, x, Method -> Reduce]
Reduce[a x^2 + x == 1, x]


3)The above might appear to suggest that you're safest using Reduce, since the documentation (Solve: Possible Issues) says "Reduce gives all solutions, including those that require equations on parameters" [emphasis mine]. However, here's an example in which Solve returns a result, while Reduce, and Solve with MaxExtraCondtions->All or Method->Reduce do not:

Solve[5 == x*2^(x^2), x]
Solve[5 == x*2^(x^2), x, MaxExtraConditions -> All]
Solve[5 == x*2^(x^2), x, Method -> Reduce]
Reduce[5 == x*2^(x^2), x]


We can get the latter three to supply Solve's solution by imposing a domain restriction:

Solve[5 == x*2^(x^2) && x \[Element] Reals, x, MaxExtraConditions->All]
Solve[5 == x*2^(x^2) && x \[Element] Reals, x, Method -> Reduce]
Reduce[5 == x*2^(x^2) && x \[Element] Reals, x]


So perhaps it's more accurate to say "When Reduce returns a result, it gives all solutions; but sometimes Solve will return a result when Reduce does not".

N.B.: The above were run on:

Make a plot of the function (Abs value because it is complex):

f[x_] = x/(1 + Sqrt[1 - x])^2;
Plot[Abs@f[x], {x, -2, 2}, Exclusions -> None]


As you can see, the inverse function is multivalued. If you need a single valued function, you must restrict the definition domain.

If you define the inverse function as f1:

f1[y_] = 4 y/(1 + y)^2;
f1[f[x]] // Simplify
(* x *)


Therefore, this is a true inverse.

Similar to @DanielHuber's answer ContourPlot visualizes the completeness of the real solution x==(4 y)/(1 + y)^2

Show[{ContourPlot[x/(1 + Sqrt[1 - x])^2 == y, {x, -2, 2}, {y, -1, 1}] ,
ParametricPlot[{ (4 y)/(1 + y)^2, y}, {y, -1, 1},PlotStyle -> {Dashed, Thickness[.01], Red}]}]