# How to define a sequence of piecewise functions and then plot them altogether?

The following is the piecewise functions I want to define

${f_k(x)} = \left\{ {\begin{array}{*{20}{c}} {\frac{{j - 1}}{{{2^k}}}}&{\frac{{j - 1}}{{{2^k}}} \le f(x) \le \frac{j}{{{2^k}}}}\\ k&{f(x) \ge k} \end{array}} \right.$

where $j=1,2,3,...,k2^k$. We can let $f(x)=e^x$ and let $k$ to be from 1 to 6.

They are basically simple functions. The problem is that the number of pieces are increasing with $k$, and it would be too tedious to define them manually. For example, $f_4$ has 64+1 intervals.

I believe there is some syntax that allows me to define them all at once and draw them altogether, but I don't know how to do it. Hope someone can help. Thank you!

• $f_k$ is kind of inverse function. For example, ${f_1} = \left\{ {\begin{array}{*{20}{c}} 0&{x < \ln 0.5}\\ {0.5}&{\ln 0.5 \le x < 1}\\ 1&{x \ge 1} \end{array}} \right.$ – Tony Jul 23 '15 at 16:38
• When $k=2$, $f_k(x)=2$ when $x>=2$, $k=3$, $f_k(x)=3$ when $x>=3$ etc. When $x<k$, $f_k$ is like dividing [0,k] into 2^k parts, while its piecewise domain is determined by $f$. – Tony Jul 23 '15 at 16:49
• I missed the $k2^k$ and thought it was a $2^k$. I see now. – march Jul 23 '15 at 16:59

Study this and see if you can adapt the idea

list=Join[Table[{(j-1)/2^k, (j-1)/2^k<=E^x<=j/2^k}, {k,1,5}], {{k,E^x>=k}}];
pw[x_] := Piecewise[list]

• Thank you! I still has a problem to ask. When I try list = Join[ Table[{(j - 1)/2^4, (j - 1)/2^4 <= E^x <= j/2^4}, {j, 1, 64}], {{4, E^x >= 4}}]; it gives the desired function for $k=4$. But when I try to make it a function of $k$ by list[k_] = Join[Table[{(j - 1)/2^k, (j - 1)/2^k <= E^x <= j/2^k}, {j, 1, k*2^k}], {{k, E^x >= k}}]; it gives an error message. – Tony Jul 23 '15 at 17:29
• @Tony. Use := instead of =. – march Jul 23 '15 at 18:08
• @march Thank you for your reply, It still gives an error, which says "Tag List in \ {{0,0<=E^x<=1/16},{1/16,1/16<=E^x<=1/8},{1/8,1/8<=E^x<=3/16},{3/16,3/\ 16<=E^x<=1/4},{1/4,1/4<=E^x<=5/16},{5/16,5/16<=E^x<=3/8},{3/8,3/8<=E^\ x<=7/16},{7/16,7/16<=E^x<=1/2},{1/2,1/2<=E^x<=9/16},{9/16,9/16<=E^x<=\ 5/8},{5/8,5/8<=E^x<=11/16},{11/16,11/16<=E^x<=3/4},{3/4,3/4<=E^x<=13/\ 16},{13/16,13/16<=E^x<=7/8},{7/8,7/8<=E^x<=15/16},{15/16,15/16<=E^x<=\ 1},... is Protected." – Tony Jul 23 '15 at 18:58
• Do Clear[list] and try again ;) – Marius Ladegård Meyer Jul 23 '15 at 19:37

You can define a function that evaluates to the needed piecewise function while evaluating it.

f[x_] := E^x

fp[foo_, x_, k_Integer?Positive, j_Integer?Positive] /; j <= k 2^k :=
Piecewise[{
{(j - 1)/(2^k), (j - 1)/(2^k) <= foo[x] <= j/(2^k)},
{k, foo[x] >= k}
}]


fp creates the Piecewise function series item for a k and j. It checks that j and k are integers with the addition of checking that j is in the correct range. When fp is called it both builds the function and evaluates it.

fp[f, 0.5, 2, #] & /@ Range[2 2^2]
(* {0, 0, 0, 0, 0, 0, 3/2, 0} *)


With Table we can generate the set of Piecewise functions for a particular k.

With[{k = 1}, Table[fp[f, x, k, j], {j, k 2^k}]]
(*
{Piecewise[{{0, 0 <= E^x <= 1/2}, {1, E^x >= 1}}, 0],
Piecewise[{{1/2, 1/2 <= E^x <= 1}, {1, E^x >= 1}}, 0]}
*)


This can be used in Plot to show the set of functions.

plotIt[foo_, k_Integer?Positive] :=
Plot[Evaluate@Table[fp[foo, x, k, j], {j, 2^k k}], {x, -2, 2},
PlotStyle -> (ColorData["SolarColors"][#] & /@ Rescale@Range[2^k k])]


The Evaluate is needed because of Plots HoldAll attribute.

plotIt[f, 3]


Of course you know you need to take some care with parameter k in plotIt as the sequence of gets very long for small k. You can help mitigate this with the PlotPoints option.

Hope this helps.

## Update

Plotting performance for larger k can be greatly increased by plotting each piecewise function individually and spreading the plots over the available kernels in parallel. parallelPlotIt does this and significantly reduces the plot time.

parallelPlotIt[foo_, k_Integer?Positive] :=
Module[{fpList, colors, mapList, plots},
fpList = Table[fp[foo, x, k, j], {j, 2^k k}];
colors = ColorData["SolarColors"][#] & /@ Rescale@Range[2^k k];
mapList = Transpose@{fpList, colors};
plots =
ParallelMap[
Plot[#[[1]], {x, -2, 2}, PlotStyle -> #[[2]],
PlotRange -> {Full, {0, Automatic}}] &, mapList, 1];
Show[plots]
]


The plots and their plot style are paired up in mapList before ParallelMap is used to spread the plotting over the kernels. The plot range of each has been tweaked a bit as it was going negative on the y-axis for some reason.