Re: Step functions
- To: mathgroup at smc.vnet.net
- Subject: [mg17063] Re: [mg17097] Step functions
- From: "Wolf, Hartmut" <hwolf at debis.com>
- Date: Fri, 23 Apr 1999 02:32:06 -0400
- Organization: debis Systemhaus
- References: <199904170735.DAA04892@smc.vnet.net.>
- Sender: owner-wri-mathgroup at wolfram.com
Alessio Massaro schrieb: > > Can anyone help me to build a step function out of a series of {x,y} pairs? > > For ex.., consider an ordered random {x,y} series like > > data=Sort[Table[{Random[],Random[]}, {10}], First[#1]<First[#2]&] > > I would like to build a function f[ { {x1, y1}, {x2, y2}, ...}, x ], that > evaluates to: > - y[i] if x=x[i] > - y[i+1] if x[i]<x<x[i+1] > Here each point {xi, yi} determines f over the left-open interval > x[i]<x<=x[i+1] of x. > The right-open interval version would be: > - y[i] if x=x[i] > - y[i] if x[i]<x<x[i+1] > Dear Alessio To the data {{x[i],y[i]}..} I'd like to add a point x[0] such that the function to be built is effectively defined as f[x]=y[i] if x[i-1] < x <= x[i] for some i and undefined else. So define In[1]:= n=10 In[2]:= xValues=Sort[Table[Random[],{n+1}]] In[3]:= yValues=Table[Random[],{n}] In[4]:= data=Transpose[{xValues,Prepend[yValues,Undefined]}] Out[4]= {{0.0431649,Undefined},{0.0616376,0.480382},{0.0723096,0.0116564},{0.159794, 0.382128},{0.207832,0.896267},{0.277301,0.922096},{0.404136,0.198678}, {0.527412,0.640826},{0.632598,0.862393},{0.739185,0.250286},{0.923058, 0.134352}} In[5]:= makeStepsFun[defs:{{_,Undefined},{_,_}..}?OrderedQ, f_Symbol]:= Module[{x}, f[x_]=Which[ Evaluate[Sequence@@Flatten[{x<=#[[1]],#[[2]]}& /@ defs]], True,Undefined];] In[6]:= makeStepsFun[data,f] In[7]:= ?f "Global`f" f[x$_] = Which[x$ <= 0.04316494650005128, Undefined, x$ <= 0.06163756347928365, 0.4803820029119135, x$ <= 0.07230960964988714, 0.01165635539654332, x$ <= 0.1597935666518781, 0.3821282405189696, x$ <= 0.2078317731794699, 0.896266906762715, x$ <= 0.2773005862054805, 0.9220959940925965, x$ <= 0.4041356993425461, 0.1986775166791136, x$ <= 0.5274119538346457, 0.6408258258554689, x$ <= 0.6325979692487199, 0.8623933751647133, x$ <= 0.7391845993698257, 0.2502855634611418, x$ <= 0.923057985711199, 0.1343522133259901, True, Undefined] In[8]:= f/@ (data[[5]] + {-10^-4,0,10^-4}) Out[8]= {0.896267,0.896267,0.922096} You can Plot this function: In[9]:= Plot[f[x],{x,First[data][[1]],Last[data][[1]]}] But you can't Integrate it or take its Derivative! To get a quality functional calculus you may use In[10]:= <<Calculus`DiracDelta` In[11]:= makeStepsFun[defs:{{_,Undefined},{_,_}..}?OrderedQ, f_Symbol]:= Module[{x,xValues=Transpose[defs][[1]],yValues=Rest[Transpose[defs][[2]]]}, f[x_]= (Append[yValues,0]-Prepend[yValues,0]).(UnitStep[x-#,ZeroValue->0]& /@ xValues); ] In[12]:= makeStepsFun[data,f] In[13]:= ?f "Global`f" f[x$_] = -0.1343522133259901* UnitStep[-0.923057985711199 + x$, ZeroValue -> 0] - 0.1159333501351517*UnitStep[-0.7391845993698257 + x$, ZeroValue -> 0] - 0.6121078117035715*UnitStep[-0.6325979692487199 + x$, ZeroValue -> 0] + 0.2215675493092443*UnitStep[-0.5274119538346457 + x$, ZeroValue -> 0] + 0.4421483091763553*UnitStep[-0.4041356993425461 + x$, ZeroValue -> 0] - 0.7234184774134828*UnitStep[-0.2773005862054805 + x$, ZeroValue -> 0] + 0.02582908732988153*UnitStep[-0.2078317731794699 + x$, ZeroValue -> 0] + 0.5141386662437453*UnitStep[-0.1597935666518781 + x$, ZeroValue -> 0] + 0.3704718851224264*UnitStep[-0.07230960964988714 + x$, ZeroValue -> 0] - 0.4687256475153702*UnitStep[-0.06163756347928365 + x$, ZeroValue -> 0] + 0.4803820029119135*UnitStep[-0.04316494650005128 + x$, ZeroValue -> 0] In[14]:= f/@ (data[[5]] + {-10^-4,0,10^-4}) Out[14]= {0.896267,0.896267,0.922096} In[15]:= Plot[f[x],{x,0,1}] You can easily differentiate the function In[16]:= D[f[x],x] Out[16]= -0.134352 DiracDelta[-0.923058+x]-0.115933 DiracDelta[-0.739185+x]-0.612108 DiracDelta[-0.632598+x]+0.221568 DiracDelta[-0.527412+x]+0.442148 DiracDelta[-0.404136+x]-0.723418 DiracDelta[-0.277301+x]+0.0258291 DiracDelta[-0.207832+x]+0.514139 DiracDelta[-0.159794+x]+0.370472 DiracDelta[-0.0723096+x]-0.468726 DiracDelta[-0.0616376+x]+0.480382 DiracDelta[-0.0431649+x] You can also integrate it. But obviously I just hit the complexity barrier of Integrate for the sum of 11 UnitStep functions: Try tt=(Integrate[Take[f[x],#],x]//Timing)& /@ Range[11] and then tims=Map[Part[#,1,1]&, tt] I found the values {0.12,0.22,0.3,0.441,0.711,1.432,3.515,9.623,28.1,83.83,264.921} If you load <<Graphics`Graphics` LogListPlot[tims,PlotJoined->True] You'll see the exponential growth of the execution times. But if you really need to integrate a steps function with many points, you can construct the integral by yourself at ease according to the pattern above. In[32]:= tt[[3]] Out[32]= {0.32 Second,-0.134352 (-0.923058+x) UnitStep[-0.923058+x,ZeroValue->0]-0.115933 (-0.739185+x) UnitStep[-0.739185+x,ZeroValue->0]-0.612108 (-0.632598+x) UnitStep[-0.632598+x,ZeroValue->0]} Final remark: if you want the right open interval solution just change the option ZeroValue->1 (which is the default), for the first method of solution change <= to < Kind regards Hartmut Wolf
- References:
- Step functions
- From: Alessio Massaro <alessio.massaro@cern.ch>
- Step functions