       Re: piecewise function

• To: mathgroup at smc.vnet.net
• Subject: [mg109226] Re: piecewise function
• From: Albert Retey <awnl at gmx-topmail.de>
• Date: Sun, 18 Apr 2010 05:57:15 -0400 (EDT)
• References: <hq61qs\$3j0\$1@smc.vnet.net> <hq9c1l\$qen\$1@smc.vnet.net> <hqc109\$ftp\$1@smc.vnet.net>

```Am 17.04.2010 12:02, schrieb Ray Koopman:
> On Apr 16, 2:52 am, Ray Koopman <koop... at sfu.ca> wrote:
>> On Apr 14, 8:40 pm, mircea <mircea.da... at gmail.com> wrote:
>>> I want a define a piecewise constant function on an interval [a,b].
>>> What I did is:
>>>
>>> s[x_] := Module[{out}, out = 0;
>>>    For[i = 1, i <= N, i++,
>>>     If[mesh[[i]] <= x < mesh[[i + 1]],
>>>      out = (mesh[[i]] + mesh[[i + 1]])/2; Break[]]]; out];
>>>
>>> where:
>>>
>>> mesh = {x_1,x_2,..,x_{N+1} }, a = x_1 < x_2 < .. < x_{N+1} = b
>>>
>>> However
>>>
>>> PiecewiseExpand /@ s[x]
>>>
>>> gives me 0.....
>>>
>>> Thanks,
>>> Mirela
>>
>> Here is a translation of your procedural s[x] into functional code:
>>
>> s1[x_] := First[  Cases[ Transpose@{Most@mesh,Rest@mesh},
>>           {a_,b_} /; a <= x < b :> (a+b)/2, {1}, 1] /. {} -> {0} ]
>>
>> If you want it to use Piecewise then this will do it:
>>
>> makefunc[mesh_] := ToExpression["Function[x, Piecewise[" <>
>>          Block[{x}, ToString[{Mean@#, #[] <= x < #[]}& /@
>>                Transpose@{Most@mesh,Rest@mesh}]] <> "]]" ]
>>
>> mesh = Sort@RandomReal[{0,1},10]
>>
>> {0.0731222,0.0955697,0.184462,0.369542,0.476,
>>  0.568679,0.725734,0.784328,0.860571,0.901895}
>>
>> s2 = makefunc[mesh]
>>
>> Function[x, Piecewise[{
>> {0.084346, 0.0731222 <= x < 0.0955697},
>> {0.140016, 0.0955697 <= x < 0.184462 },
>> {0.277002, 0.184462  <= x < 0.369542 },
>> {0.422771, 0.369542  <= x < 0.476    },
>> {0.52234,  0.476     <= x < 0.568679 },
>> {0.647207, 0.568679  <= x < 0.725734 },
>> {0.755031, 0.725734  <= x < 0.784328 },
>> {0.822449, 0.784328  <= x < 0.860571 },
>> {0.881233, 0.860571  <= x < 0.901895 }}]]
>
> This will do the same thing, but a little more efficiently.
>
> makefunk[mesh_] := ToExpression["Function[x, Piecewise[" <>
>          Block[{x}, ToString@MapThread[{#1, x < #2}&,
>                {Prepend[(Most@mesh+Rest@mesh)/2,0],mesh}]] <> "]]" ]
>
> s3 = makefunk[mesh]
>
> Function[x, Piecewise[{
> {0,        x < 0.0955697},
> {0.084346, x < 0.0955697},
> {0.140016, x < 0.184462 },
> {0.277002, x < 0.369542 },
> {0.422771, x < 0.476    },
> {0.52234,  x < 0.568679 },
> {0.647207, x < 0.725734 },
> {0.755031, x < 0.784328 },
> {0.822449, x < 0.860571 },
> {0.881233, x < 0.901895 }}]]
>

It think it has several advantages to not convert to strings and back,
which is hardly ever necessary. Here is a version which does the same
thing without converting to strings:

makefunc2[mesh_] := Block[{x},
Apply[
Function, {x,
Piecewise[{Mean[{##}], #1 <= x < #2} & @@@ Partition[mesh, 2, 1]]}
]
]

If you plot the difference between the two version you will find that
the result differs in the range of about 10^-7 which may or may not be a
problem for your application, but shows one of the problems with the
string conversion. Another problem with converting from strings to
expression is that this will often fail when you decide to make a