Preamble¶
The code is written in Julia programming language. However, I think that the code is readable without any knowledge in Julia and can be easily adapted to Python or R for instance.
Here is the preamble to load the Distributions and Plots packages.
using Distributions
using Plots
Here is a function used in the following in order to get the x and y coordinates to plot the graph of a counting process.
function pointprocess_withintensity(tmin, tmax, points, intensity)
npoints = length(points)
scatter(points, zeros(npoints))
tvec = LinRange(tmin, tmax, 1000)
intensityvec = Float64[]
for i in eachindex(tvec)
append!(intensityvec, intensity(tvec[i], points[points .< tvec[i]]))
end
plot!(tvec, intensityvec, legend = false)
end
pointprocess_withintensity (generic function with 1 method)
Exercise 4 (Thinning simulation)¶
Use the idea of the thinning representation to write an algorithm which gives a simulation of a point process.
The function below gives the simulation of a point process via the thinning algorithm. It assumes that a bound for the intensity (at least up to some future time) is known.
The arguments intensity
and intensity bound
are functions of t
and of the previous points.
intensity
returns a scalar value,intensitybound
returns a scalar value and a future time after which the bound is not valid anymore.
function thinning(tmax, intensity, intensitybound)
t = 0
points = Real[]
while t < tmax
(bound, tbound) = intensitybound(t, points)
IEI = rand(Exponential(1/bound))
t += IEI
t > tmax && break
if t > tbound
t = tbound
continue
end
truerate = intensity(t, points)
truerate > bound && error("intensitybound must be an upperbound of the function intensity")
truerate < 0 && error("intensity must be non negative")
U = rand(Uniform(0,bound))
U <= truerate && append!(points, t)
end
return points
end
thinning (generic function with 1 method)
Question 1¶
Simulation of a renewal process. Its intensity depends on the time elapsed since the last point, i.e. $\lambda_{t} = q(t-T_{N_{t-}})$, with $q(x) = K/(a+x)$. $K$ and $a$ are positive real parameters.
Here is the implementation of the corresponding functions intensity
and intensitybound
.
function intensityQ1(t, history; K=1, a=1)
isempty(history) ? lastpoint = 0 : lastpoint = last(history)
s = t-lastpoint
return K/(a+s)
end
function intensityboundQ1(t, history; K=1, a=1)
isempty(history) ? lastpoint = 0 : lastpoint = last(history)
s = t-lastpoint
return (K/(a+s), Inf)
end
intensityboundQ1 (generic function with 1 method)
Here is how to call the thinning simulation of the model.
K=2; a=2; tmax = 20;
points = thinning(tmax, (t,history)->intensityQ1(t, history; K=K, a=a), (t,history)->intensityboundQ1(t, history; K=K, a=a))
5-element Vector{Real}: 8.515874360074603 8.890720529968261 10.143785017869178 13.995783357566346 14.707134526905278
Here are two functions to simplify notation.
thinningQ1(tmax; K=1, a=1) = thinning(tmax, (t,history)->intensityQ1(t, history; K=K, a=a), (t,history)->intensityboundQ1(t, history; K=K, a=a))
graphQ1(tmax, points; K=1, a=1) = pointprocess_withintensity(0, tmax, points, (t,history)->intensityQ1(t, history; K=K, a=a))
tmax=50.
K=1; a=1;
points = thinningQ1(tmax; K=K, a=a)
graphQ1(tmax, points; K=K, a=a)
display(title!("K="*string(K)*", a="*string(a)))
K=3; a=1;
points = thinningQ1(tmax; K=K, a=a)
graphQ1(tmax, points; K=K, a=a)
display(title!("K="*string(K)*", a="*string(a)))
K=1; a=.5;
points = thinningQ1(tmax; K=K, a=a)
graphQ1(tmax, points; K=K, a=a)
display(title!("K="*string(K)*", a="*string(a)))
K=1; a=2;
points = thinningQ1(tmax; K=K, a=a)
graphQ1(tmax, points; K=K, a=a)
display(title!("K="*string(K)*", a="*string(a)))
The parameter $K$ mainly controls the mean number of points whereas $a$ controls the clustering: $a$ small implies high clustering.
Question 2¶
Simulation of a linear Wold process. Its intensity depends on the time elapsed since the last point and the interval between the last two points, i.e. $\lambda_{t} = \mu+\alpha_{1}(t-T_{N_{t-}}) + \alpha_{2}(T_{N_{t-}} - T_{N_{t-}-1})$, with the convention that $T_{-1}=0$. $\mu$, $\alpha_{1}$ and $\alpha_{2}$ are positive real parameters.
Here is the implementation of the corresponding functions intensity
and intensitybound
.
function intensityQ2(t, history; mu=1, alpha1=1, alpha2=1)
if length(history)==0
twolastpoints = [0,0]
elseif length(history)==1
twolastpoints = [0,last(history)]
else
twolastpoints = last(history,2)
end
s1 = t-last(twolastpoints)
s2 = diff(twolastpoints)[1]
return mu + alpha1*s1 + alpha2*s2
end
function intensityboundQ2(t, history; mu=1, alpha1=1, alpha2=1)
if length(history)==0
twolastpoints = [0,0]
elseif length(history)==1
twolastpoints = [0,last(history)]
else
twolastpoints = last(history,2)
end
tbound = t+1
s1bound = tbound-last(twolastpoints)
s2 = diff(twolastpoints)[1]
return (mu + alpha1*s1bound + alpha2*s2, tbound)
end
intensityboundQ2 (generic function with 1 method)
Here is how to call the thinning simulation of the model.
mu=1; alpha1=1; alpha2=1; tmax = 20;
points = thinning(tmax, (t,history)->intensityQ2(t, history; mu=mu, alpha1=alpha1, alpha2=alpha2), (t,history)->intensityboundQ2(t, history; mu=mu, alpha1=alpha1, alpha2=alpha2))
37-element Vector{Real}: 0.553088990277999 0.824341109663302 1.9188777037418356 2.45955736995026 3.1933187933546083 3.3681597398293897 3.4713465701326145 4.002077522103385 4.936640016423601 5.47147419008879 ⋮ 17.065232383132095 17.12923985667036 17.50784394718668 18.10855055028872 18.549716856353715 18.726905772781564 18.877959688498436 19.21935635688563 19.39282671970031
Here are two functions to simplify notation.
thinningQ2(tmax; mu=1, alpha1=1, alpha2=1) = thinning(tmax, (t,history)->intensityQ2(t, history; mu=mu, alpha1=alpha1, alpha2=alpha2), (t,history)->intensityboundQ2(t, history; mu=mu, alpha1=alpha1, alpha2=alpha2))
graphQ2(tmax, points; mu=1, alpha1=1, alpha2=1) = pointprocess_withintensity(0, tmax, points, (t,history)->intensityQ2(t, history; mu=mu, alpha1=alpha1, alpha2=alpha2))
graphQ2 (generic function with 1 method)
tmax=20.
mu=1; alpha1=1; alpha2=1;
points = thinningQ2(tmax; mu=mu, alpha1=alpha1, alpha2=alpha2)
graphQ2(tmax, points; mu=mu, alpha1=alpha1, alpha2=alpha2)
display(title!("mu="*string(mu)*", α₁="*string(alpha1)*", α₂="*string(alpha2)))
mu=3; alpha1=1; alpha2=1;
points = thinningQ2(tmax; mu=mu, alpha1=alpha1, alpha2=alpha2)
graphQ2(tmax, points; mu=mu, alpha1=alpha1, alpha2=alpha2)
display(title!("mu="*string(mu)*", α₁="*string(alpha1)*", α₂="*string(alpha2)))
mu=1; alpha1=.5; alpha2=2;
points = thinningQ2(tmax; mu=mu, alpha1=alpha1, alpha2=alpha2)
graphQ2(tmax, points; mu=mu, alpha1=alpha1, alpha2=alpha2)
display(title!("mu="*string(mu)*", α₁="*string(alpha1)*", α₂="*string(alpha2)))
mu=1; alpha1=2; alpha2=.5;
points = thinningQ2(tmax; mu=mu, alpha1=alpha1, alpha2=alpha2)
graphQ2(tmax, points; mu=mu, alpha1=alpha1, alpha2=alpha2)
display(title!("mu="*string(mu)*", α₁="*string(alpha1)*", α₂="*string(alpha2)))