# Transform Piecewise[] into sum of indicators

I'm interested in transforming a piecewise defined function into a sum of indicator functions, ultimately with the aim to be better able to integrate them.

As an example I would like to transform the function

f = Piecewise[{{x, 3*x > y && x < 2*y}, {y, 2*x > y && x < 3*y}}, 0]


into

x Boole[3 x > y && x < 2 y] + y Boole[x >= 2 y && x < 3 y].


For this specific example, this could be achieved by

f[[1,1,1]]Boole[f[[1,1,2]]] + f[[1,2,1]]Boole[f[[1,2,2]] && !f[[1,1,2]]]


but I don't know how to efficiently generalize this to functions with more than two cases, in particular how to ensure that the term corresponding to the $n$th case contains the negated conditions of the first $n-1$ cases.

In a second step, assuming that the conditions of the piecewise function are linear inequalities, I would like to decompose each Boole[] into a sum of Boole[]'s of disjoint intervals for, say, the variable $x$.

In my example above this would mean

Boole[3 x > y && x < 2 y] == Boole[y/3 < x < y/2]
Boole[x >= 2 y && x < 3 y] == Boole[2y < x < 3y]


This is maybe a trivial example, but in more complex situations one will have to deal with more than one disjoint interval. In non-Mathematica notation I'd like a decomposition of the form $$f(x) = \sum_i f_i(x) \sum_j\mathbf{1}_{\left\{x_{i,j}^{\min}<x<x_{i,j}^\max\right\}}(x).$$ where the $f_i$ are given by f[[1,All,1]].

-
For a start you can try Cases[Piecewise[{{x, 3*x > y && x < 2*y}, {y, 2*x > y && x < 3*y}}, 0] /. Piecewise -> Plus, {a_, b_} -> a Boole[b]] –  Rorschach Oct 6 '13 at 18:47
Thanks @Blackbird: Does your method also give the correct result if the conditions of the piecewise function are not mutually exclusive? In the example, if x < 2y && 2x > y I think your result would give {x,y} (or x+y) whereas the original function would evaluate to x because of sequential evaluation of cases. –  Eckhard Oct 6 '13 at 19:05
Try to run above snippet and do %/.{x->2,y->4}.I didn't actually understand this mutual exclusion you said,but may be this helps. –  Rorschach Oct 6 '13 at 19:11
%/.{x->2,y->3} gives {2,3} –  Eckhard Oct 6 '13 at 19:13
Boole is deciding what you will get so, may be you need correct combination of x,y that you get only one +ive numerical result,eg {x->2,y->4} .This will get you {2,0}. –  Rorschach Oct 6 '13 at 19:26

Making up a three-piece function,

f = Piecewise[{{x, x < 0}, {x^2, 0 <= x < 3}, {x^3, 3 <= x}}, 0];


we can map Boole onto the conditions of f and use Dot to sum the products of the values and the 0/1 values of the conditions thus:

Dot @@ MapAt[Boole, Transpose @ First @ f, 2]
(* x^2 Boole[0 <= x < 3] + x Boole[x < 0] + x^3 Boole[3 <= x] *)


Check:

% /. x -> 2
(* 4 *)


Update

To get an expression that is equivalent to Piecewise, one needs to nest the expressions similar to the psuedo-formula

Boole[cond] exp + (1 - Boole[cond]) (rest)


Example:

f2 = Piecewise[{{x, x < 0}, {x^2, 0 < x < 3}, {x^3, 2 <= x}}, 1000];

f2exp = Fold[(1 - Boole[Last @ #2]) #1 + Boole[Last @ #2] First[#2] &,
Last @ f2, Reverse @ First @ f2]
(* x Boole[x < 0] +
(1 - Boole[x < 0]) (x^2 Boole[0 < x < 3] +
(1 - Boole[0 < x < 3]) (1000 (1 - Boole[3 <= x]) + x^3 Boole[2 <= x])) *)

Table[f2 /. x -> i, {i, -1, 4}]
Table[f2exp /. x -> i, {i, -1, 4}]
(* {-1, 1000, 1, 4, 27, 64} *)
(* {-1, 1000, 1, 4, 27, 64} *)


Note the default value for x = 0.

-
Thank you. Would this work if the conditions of the piecewise function are not mutually exclusive, as in your example. –  Eckhard Oct 6 '13 at 19:08
No, it wouldn't produce a expression equivalent to Piecewise if the conditions were not mutually exclusive, for the same reason that the method in your example would not work: Order matters in Piecewise but not in Plus. –  Michael E2 Oct 6 '13 at 20:57

Another option is to express Piecewise in terms of UnitStep.

In[1]:= f = Piecewise[{{x,3*x>y&&x<2*y},{y,2*x>y&&x<3*y}},0];

In[2]:= SimplifyPWToUnitStep[f]
Out[2]= x (1-UnitStep[x-2 y]) (1-UnitStep[-3 x+y])+
y ((1-UnitStep[x-3 y]) UnitStep[x-2 y] (1-UnitStep[-2 x+y])+(1-UnitStep[x-3 y])
UnitStep[-3 x+y] (1-UnitStep[-2 x+y])-(1-UnitStep[x-3 y])^2 UnitStep[x-2 y]
UnitStep[-3 x+y] (1-UnitStep[-2 x+y])^2)

-
Thanks. Is this usage documented anywhere? Also, the expression multiplying y seems quite complicated. Can it be further simplified? Simplify transforms the expression back into its piecewise form. –  Eckhard Oct 6 '13 at 19:25
This is an undocumented function. –  Chip Hurst Oct 8 '13 at 15:16
I don't think it can be simplified further. Trying Simplify[x (1 - UnitStep[x - 2 y]) (1 - UnitStep[-3 x + y]) + y ((1 - UnitStep[x - 3 y]) UnitStep[ x - 2 y] (1 - UnitStep[-2 x + y]) + (1 - UnitStep[x - 3 y]) UnitStep[-3 x + y] (1 - UnitStep[-2 x + y]) - (1 - UnitStep[x - 3 y])^2 UnitStep[ x - 2 y] UnitStep[-3 x + y] (1 - UnitStep[-2 x + y])^2), ComplexityFunction -> (LeafCount[#] + 10^4 Count[#, _Piecewise, {0, \[Infinity]}] &)]` doesn't make any changes. –  Chip Hurst Oct 8 '13 at 15:17