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