MathGroup Archive 1999

[Date Index] [Thread Index] [Author Index]

Search the Archive

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:
  • Prev by Date: Re: Step functions
  • Next by Date: Re: Infinite precision
  • Previous by thread: Step functions
  • Next by thread: Re: Step functions