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