from symbulate import *
from matplotlib import pyplot as plt
Introduction to Continuous Time Markov Chains
Seagull
= [[-1, 0.4, 0.6],
Q 0.8 / 3, -1 / 3, 0.2 / 3],
[0.9 / 5, 0.1 / 5, -1 / 5]]
[
= [1, 0, 0]
pi0
= [1, 2, 3]
states
= ContinuousTimeMarkovChain(Q, pi0, states) X
;
plt.figure()1).plot()
X.sim(; plt.show()
;
plt.figure()3).plot()
X.sim(; plt.show()
;
plt.figure()1 / 60].sim(10000).plot()
X[; plt.show()
;
plt.figure()0.5].sim(10000).plot()
X[; plt.show()
;
plt.figure()1].sim(10000).plot()
X[; plt.show()
;
plt.figure()5].sim(10000).plot()
X[; plt.show()
;
plt.figure()60].sim(10000).plot()
X[; plt.show()
Times between jumps
= ContinuousTimeMarkovChainProbabilitySpace(Q, pi0, states)
P = RV(P, interarrival_times) W
;
plt.figure()0].sim(10000).plot()
W[; plt.show()
;
plt.figure()1].sim(10000).plot()
W[; plt.show()
;
plt.figure()0] & W[1]).sim(10000).plot()
(W[; plt.show()
A few paths from scratch
= 1:3 # state space
states
= c(1, 0, 0) # initial distribution
pi0
= rbind(
P c(0, 0.6, 0.4),
c(0.8, 0, 0.2),
c(0.9, 0.1, 0)
# transition matrix of embedded DTMC
)
= c(1, 1 / 3, 1 / 5) # transition rates for each state
lambda
= 3 # number of paths to simulate
Nruns = 10 # number of transitions to sim for each path
Njump
= matrix(rep(NA, Nruns * (Njump + 1)), nrow = Njump + 1) # +1 to include time 0
Xt = Xt
Wn
for (r in 1:Nruns){
1, r] = sample(states, 1, prob = pi0) # initial state
Xt[1, r] = 0 # time 0
Wn[for (n in 2:(Njump+1)){
= rexp(1) / lambda[Xt[n - 1, r]] # time between jumps, exp(lambda_i)
Tn = sample(states, 1, prob = P[Xt[n - 1, r], ]) # new state
Xt[n, r] = Wn[n - 1, r] + Tn # time of nth jump
Wn[n,r]
}
}# Plot the paths
= Nruns
Npaths = c(0, -.1, .1)
plotadj plot(range(Wn),
range(states)+range(plotadj),
type = 'n',
ylab = "X(t)", xlab = "t",
main = paste(Npaths," paths of a CTMC"))
= c("black","orange","skyblue")
colors
for (r in 1:Npaths){
segments(y0 = Xt[-(Njump + 1), r] + plotadj[r],
x0 = Wn[-(Njump + 1), r],
y1 = Xt[-(Njump + 1), r] + plotadj[r],
x1 = Wn[-1, r], col = colors[r], lty = r, lwd = 2)
points(Wn[, r], Xt[,r] + plotadj[r], pch = 16, col = colors[r])
points(Wn[-1, r], Xt[-(Njump + 1), r] + plotadj[r], col = colors[r])
}
M/M/1 Queue: Sample Path
= 0.2
lambda
= 0.5
mu
= 20
n_jumps
= rep(NA, n_jumps + 1)
X_t = rep(NA, n_jumps + 1)
T_n
1] = 0
X_t[1] = 0
T_n[
for (n in 2:n_jumps){
if (X_t[n - 1] == 0){
= T_n[n - 1] + rexp(1) / lambda
T_n[n] = X_t[n - 1] + 1
X_t[n] else {
} = T_n[n - 1] + rexp(1) / (lambda + mu)
T_n[n] = X_t[n - 1] + sample(c(-1, 1), 1, prob = c(mu, lambda))
X_t[n]
}
}
plot(T_n, X_t,
type = "s",
xlab = "t", ylab = "X(t)",
main = "Sample path of M/M/1 queue")
M/M/s Queue: Sample path
= 2.3
lambda
= 0.5
mu
= 5
s
= 20
n_jumps
= rep(NA, n_jumps + 1)
X_t = rep(NA, n_jumps + 1)
W_n
1] = 0
X_t[1] = 0
W_n[
for (n in 2:n_jumps){
= W_n[n - 1] + rexp(1) / (lambda + mu * min(s, X_t[n - 1]))
W_n[n] = X_t[n - 1] + sample(c(-1, 1), 1,
X_t[n] prob = c(mu * min(s, X_t[n - 1]), lambda))
}
plot(W_n, X_t,
type = "s",
xlab = "t", ylab = "X(t)",
main = paste("Sample path of M/M/s queue with s = ", s))