# How to convert output from Reduce into a piecewise function?

Reduce often provides a much fuller solution than Solve. But it's always in the form of a true statement rather than functions or replacement rules, e.g.

Input:

Reduce[Sin[x^2] + Cos[a] == 0 && -π/2 <= x <= π/2, x]


Output:

(Cos[a] == -1 && (x == -Sqrt[(π/2)] || x == Sqrt[π/2])) ||
(-1 < Cos[a] <= Sin[1/4 (-4 π + π^2)] &&
(x == -Sqrt[π + ArcSin[Cos[a]]] || x == Sqrt[π + ArcSin[Cos[a]]])) ||
(Cos[a] == 0 && x == 0) ||
(-1 < Cos[a] < 0 && (x == -Sqrt[-ArcSin[Cos[a]]] || x == Sqrt[-ArcSin[Cos[a]]]))


What I need is a function that takes the variable solved for (i.e. x here) as its input and gives corresponding value (or a list of values/separate functions for non-unique solutions) as the output. For example, the above output would be represented similarly to the following:

solution[x_] = Piecewise[{
{{-Sqrt[Pi/2], Sqrt[Pi/2]}, Cos[a] == -1},
{{-Sqrt[Pi + ArcSin[Cos[a]]], Sqrt[Pi + ArcSin[Cos[a]]]},
-1 < Cos[a] <= Sin[(1/4)*(-4*Pi + Pi^2)]},
{0, Cos[a] == 0},
{{-Sqrt[-ArcSin[Cos[a]]], Sqrt[-ArcSin[Cos[a]]]},
-1 < Cos[a] < 0}}]


What is a good way to transform the expression returned by Reduce to such a function?

• Removing In[..] and Out[..] has been discussed here, and it was accepted as a consensus. You are welcome to add comments at the post there if you think that discussion should be restarted. – rhermans Jul 25 '19 at 13:05
• @rhermans I've changed it to a less controversial variant, where both your and my concerns are both addressed. – Ruslan Jul 25 '19 at 13:07

Convert it to string and solve it.

convert[x_] :=
x /. (Or[(a_) && (b_)]) :> {b, a} // InputForm // ToString //
StringReplace[#, "||" -> ","] & // "Piecewise[{" ~~ # ~~ "}]" & //
ToExpression;


this works for easy situation, for example:

convert[(a <= -2 && 1 + 2 a <= y <= 1) || (-2 < a <= 2 (1 - Sqrt) &&
1/4 (4 a - a^2) <= y <= 1) || (2 (1 - Sqrt) < a <=
2 (-1 + Sqrt) && -1 <= y <= 1) || (2 (-1 + Sqrt) < a <=
2 && -1 <= y <= 1/4 (4 a + a^2)) || (a > 2 && -1 <=
y <= -1 + 2 a)]


gives $$\begin{cases} 2 a+1\leq y\leq 1 & a\leq -2 \\ \frac{1}{4} \left(4 a-a^2\right)\leq y\leq 1 & -22 \end{cases}$$

but for complex situations,someone told me a better solution.

/. (Or[a_ && b_]) :> {b, a} // Apply[Piecewise[{##}] &]


for example

(Cos[a] == -1 && (x == -Sqrt[(\[Pi]/2)] ||
x == Sqrt[\[Pi]/2])) || (-1 < Cos[a] <=
Sin[1/4 (-4 \[Pi] + \[Pi]^2)] && (x == -Sqrt[\[Pi] +
ArcSin[Cos[a]]] ||
x == Sqrt[\[Pi] + ArcSin[Cos[a]]])) || (Cos[a] == 0 &&
x == 0) || (-1 < Cos[a] <
0 && (x == -Sqrt[-ArcSin[Cos[a]]] ||
x == Sqrt[-ArcSin[Cos[a]]])) /. (Or[a_ && b_]) :> {b, a} //
Apply[Piecewise[{##}] &]


gives

$$\begin{cases} x=-\sqrt{\frac{\pi }{2}}\lor x=\sqrt{\frac{\pi }{2}} & \cos (a)=-1 \\ x=-\sqrt{\sin ^{-1}(\cos (a))+\pi }\lor x=\sqrt{\sin ^{-1}(\cos (a))+\pi } & -1<\cos (a)\leq \sin \left(\frac{1}{4} \left(\pi ^2-4 \pi \right)\right) \\ x=0 & \cos (a)=0 \\ x=-\sqrt{-\sin ^{-1}(\cos (a))}\lor x=\sqrt{-\sin ^{-1}(\cos (a))} & -1<\cos (a)<0 \\ \end{cases}$$

At least for the OP's specific case, here is one possibility:

Piecewise[Append[
KeyValueMap[{#2, #1} &,
GroupBy[Cases[
BooleanConvert[Reduce[Sin[x^2] + Cos[a] == 0 &&
-π/2 <= x <= π/2, x], "DNF"],
x == expr_ && cond_ :> {expr, cond}, {1}],
Last -> First]], {Indeterminate, True}]] • OK, so this works fine for the OP case. But can you think of a case when this would fail? – Ruslan Jan 30 at 17:00
• It would surely fail if Reduce[] encounters a function it can't invert. – J. M.'s technical difficulties Jan 30 at 22:40