# Sample the data with equal step size

I have the data below. I would like to sample with equal step size. For simplicity lets try unit step size. Here is the desired result. Find the first time exceed the unit time step, and take lower ones second entry. {{1,0},{2,0},{3,3},{4,10},{5,17},{6,27},{7,43},{8,63}} and so on.

This suppose to work but it does not.

iFun = Interpolation[data, InterpolationOrder -> 0];
τ = 1;
range = Range[0, data[[-1, 1]], τ];
data2 = Transpose@{range, iFun@range};

SeedRandom@2
A = 30;
\[Beta] = 0.05;
{a, b} = {72, 1/12};

X = x = 0;

currentTime = 0;
stackTime = {};
data = Prepend[Join @@ Last@Reap@Do[

a1 = A   ;
a2 = \[Beta] X;
a0 = Total@{a1, a2};
reactionVec = 1/a0 Accumulate@{a1, a2};

reaction =
First@FirstPosition[reactionVec - RandomReal[], _?Positive];

tWait = RandomVariate@ExponentialDistribution[a0];

currentTime = currentTime + tWait;

stackTime = Sort@stackTime;

minStack = Min[stackTime];

Which[

currentTime < minStack,

Which[

reaction == 1, {Sow@{currentTime, X},
AppendTo[stackTime, currentTime + tDelay]},

reaction == 2, {Sow@{currentTime, X -= 1}}],

minStack < currentTime,

{Sow@{minStack, X += 1}, currentTime = minStack,
stackTime = Rest@stackTime} ]

, 1000], {0, x}];

• Apr 30, 2018 at 23:35

Also

TimeSeriesResample[data, {Range[1, data[[-1, 1]], τ]}]


{{1, 0}, {2, 0}, {3, 3}, {4, 10}, {5, 17}, {6, 27}, {7, 43}, {8, 63}}

• This method seems slow for large data. Do you know how to speed it up. I found this but don't know how to modify it. mathematica.stackexchange.com/questions/169688/… May 1, 2018 at 23:17
• @Okkes, unfortunately, I don't know how to make tit faster. The linked answer is using TimeSeriesResample with additional processing steps. You can use TimeSeriesResample[TimeSeries[data] , {Range[1, data[[-1, 1]], \[Tau]]}, ResamplingMethod->{"Interpolation",InterpolationOrder->0}]["Path"] but I doubt this would be faster.
– kglr
May 1, 2018 at 23:47
• I meant Carl's solution in the link. May 1, 2018 at 23:50
1. Your range specification should start at $1$ if that is what you want the first abscissa to be; you were starting at $0$ instead.
2. Use Floor to get the floor of your interpolated function value.

In other words, try this:

iFun = Interpolation[data, InterpolationOrder -> 1];
τ = 1;
range = Range[1, data[[-1, 1]], τ];
data2 = Transpose@{range, Floor@iFun@range}

(* Out: {{1, 0}, {2, 0}, {3, 3}, {4, 10}, {5, 17}, {6, 27}, {7, 43}, {8, 63}} *)

• I used to use this approach, but when there is a death Floor is underestimate the population.. See here mathematica.stackexchange.com/questions/165073/… May 1, 2018 at 0:34
• Desired result is {11, 142}, but your solution gives {11, 141}. May 1, 2018 at 0:36

Here is faster way to do it. I modified the code that I found here

SeedRandom@2
A = 30;
\[Beta] = 0.05;
{a, b} = {72, 1/12};

X = x = 0;

currentTime = 0;
stackTime = {};
data = Prepend[Join @@ Last@Reap@Do[a1 = A;
a2 = \[Beta] X;
a0 = Total@{a1, a2};
reactionVec = 1/a0 Accumulate@{a1, a2};

tWait = RandomVariate@ExponentialDistribution[a0];

currentTime = currentTime + tWait;

stackTime = Sort@stackTime;

minStack = Min[stackTime];

Which[

currentTime < minStack,

reaction =
First@FirstPosition[reactionVec - RandomReal[], _?Positive];
Which[reaction == 1,

{Sow@{currentTime, X},
AppendTo[stackTime,

reaction == 2, {Sow@{currentTime, X -= 1}}],

minStack < currentTime, {Sow@{minStack, X += 1},
currentTime = minStack, stackTime = Rest@stackTime}],
500000], {0, x}];


TimeSeriesResample Method:

\[Tau] = 1;
data2 = TimeSeriesResample[
data, {Range[0, data[[-1, 1]], \[Tau]]}]; // AbsoluteTiming


{10.5438, Null}

StepFunction[data_] :=
Module[{sdata, nf}, sdata = Sort@data;
nf = Nearest[sdata[[All, 1]] -> "Index"];
StepFunction[nf, sdata[[All, 1]], sdata[[All, 2]], {-1, 0}]]

StepFunction[nf_NearestFunction, x_, y_, clip_][pt_List] :=
With[{near = nf[pt][[All, 1]]},
Join[List@
pt, {y[[Clip[
near + Clip[Sign[Subtract[pt, x[[near]]]], clip], {1,
Length[x]}]]]}]]
data3 = Transpose@
StepFunction[data][
Range[0, data[[-1, 1]], \[Tau]]]; // AbsoluteTiming


{0.439258, Null}

data2 == data3


True