Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]].

share|improve this question
    
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
show 3 more comments

2 Answers

up vote 1 down vote accepted

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.

share|improve this answer
    
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
add comment

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]:= Simplify`PWToUnitStep[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)
share|improve this answer
    
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. –  RiemannZeta 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. –  RiemannZeta Oct 8 '13 at 15:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.