# Converting ConditionalExpression to Piecewise

I have Solve[] return a list like {{F->ConditionalExpression[EXPR1, 0<z<a1]},{F->ConditionalExpression[EXPR2, a1<z<a2]},...} and so on -- EXPR* and a1,a2,... are somewhat complicated expressions, containing things like Root[]:

EQ = F^4 (138880 z + 318688 F z + 98415 F^10 z + 6561 F^9 (5 + 4 z) +
405 F^5 (625 + 1136 z) + 243 F^6 (-2500 + 5077 z)) ==
1024 z + 11008 F z + 40192 F^2 z + 33536 F^3 z + 46944 F^6 z +
709776 F^7 z + 368388 F^8 z + 4374 F^12 (50 + 43 z) +
4374 F^11 (-125 + 202 z);

ftz = Solve[EQ && 0 < F < 1 && 0 < z < 1, F];


e.g. the first conditional:

In[100]:= N[(F /. ftz[[1]])]

Out[100]= ConditionalExpression[
Root[-1024 z - 11008 z #1 - 40192 z #1^2 - 33536 z #1^3 +
138880 z #1^4 + 318688 z #1^5 - 46944 z #1^6 - 709776 z #1^7 -
368388 z #1^8 + (253125 + 460080 z) #1^9 + (-607500 +
1233711 z) #1^10 + (546750 - 883548 z) #1^11 + (-218700 -
188082 z) #1^12 + (32805 + 26244 z) #1^13 + 98415 z #1^14 &,
2], 0. < z < 0.674139]


I need to (numerically) integrate this function for given parameter values, which Mathematica refuses to do. However, if I convert the expression into a Piecewise function: for example as

ff = Piecewise[{{ftz[[1]][[1]][[2]][[1]], ftz[[1]][[1]][[2]][[2]]},
{ftz[[2]][[1]][[2]][[1]], ftz[[2]][[1]][[2]][[2]]},
{0, z == 0},
{1, z == 1}}];


it easily computes the integral. Unfortunately, the number of intervals and the breakpoints are parameter dependent, and this must be done automatically as the function is called inside another function.

Does anyone have any suggestions on how to convert such a list of conditionals into a Piecewise function, or how to otherwise compute the integral? Thanks!

-
This is an interesting question, however it is not clear what is the function, what are parameters, what is your expected Piecewise form etc. More details are needed to give a constructive answer. ConditionalExpression is new in M8 and I suspect it is not quite seamlessly integrated with the rest of the system. –  Artes Jun 15 '12 at 17:14
Thanks, I added an example equation. Unfortunately I do not have an earlier version of Mathematica installed to see what Solve returns there :( –  laxxy Jun 15 '12 at 18:04
By the way, when multiple indexing, you can use a single call to Part. It'll be more efficient and neater. x[[1]][[2]]==x[[1, 2]] –  Rojo Jun 16 '12 at 15:27

That conversion is straightforward, in this case. It is a one-liner

Piecewise[List @@@ Flatten[N@ftz][[All, 2]] ]


Now let me explain. As you have noticed, Solve returns solutions of the form:

{ {_ -> _}, {_ -> _}, ...}


which is what Flatten reduces to

{_ -> _, _ -> _, ...}


Then, I take only the right hand side of each Rule via Flatten[...][[All,2]] leaving us with something of the form

{ConditionalExpression[...], ...}


So, we need to replace ConditionalExpression with List to make it palatable to Piecewise, and the it is done using the shorthand form of Apply at level 1, @@@. Finally, we feed the result into Piecewise and get what you want.

As pointed out in the comments, the simpler form

Piecewise[List @@@ Last @@@ N@ftz]


works just as well.

-
Thanks, this works! :) –  laxxy Jun 15 '12 at 21:56
(+1) could also apply Apply twice: Piecewise[List @@@ Last @@@ N@ftz] or List @@@ Last @@@ N@ftz // Piecewise :) –  kguler Jun 15 '12 at 21:56
@kguler updated my answer with that form. –  rcollyer Jun 15 '12 at 21:58

It may not always be appropriate to convert a ConditionalExpression into Piecewise, because the two are not equivalent, and you may be changing the meaning. This is because Piecewise IMPOSES a default value of 0 if the conditions are not satisfied, whereas ConditionalExpression leaves the expression as undefined.

For example, given:

In[1]:=  expr = ConditionalExpression[1, x > 3]

In[2]:=  Simplify[expr, x < -2]
Out[2]=  Undefined


whereas:

In[3]:=  Simplify[Piecewise[{{1, x > 3}}],  x < -2]
Out[3]=  0


But, if you do want to impose the swap, say given:

In[4]:=  sol = Integrate[x^n, {x, 0, 1}]
Out[4]=  ConditionalExpression[1/(1 + n), Re[n] > -1]


... then an easy way to do it is:

In[5]:=  sol /. ConditionalExpression[xx_, yy_] :> Piecewise[{{xx, yy}}]


-