[Date Index]
[Thread Index]
[Author Index]
Re: piecewise function
*To*: mathgroup at smc.vnet.net
*Subject*: [mg109250] Re: piecewise function
*From*: Ray Koopman <koopman at sfu.ca>
*Date*: Mon, 19 Apr 2010 02:49:39 -0400 (EDT)
*References*: <hq61qs$3j0$1@smc.vnet.net> <hq9c1l$qen$1@smc.vnet.net>
On Apr 18, 2:57 am, Albert Retey <a... at gmx-topmail.de> wrote:
> 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.....
>>>>
>>>> Can you please help me?
>>>> 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@#, #[[1]] <= x < #[[2]]}& /@
>>> 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
> package of your functionb ...
>
> hth,
>
> albert
You're right, it is a little kludgy, and converting & reconverting
Reals does lose precision. Here's a revised version of makefunk:
makefunk2[mesh_] := Block[{x}, Function @@ {x, Piecewise@Transpose@
{Prepend[(Most@mesh+Rest@mesh)/2,0], Thread[x < mesh]} } ]
Prev by Date:
**Re: ArrayPlot coordinates scaling for overlays**
Next by Date:
**Re: Nest and Fold don't respect HoldFirst?**
Previous by thread:
**Re: piecewise function**
Next by thread:
**Re: Equation problem**
| |