Сначала создайте функцию для смещения вектора влево и вправо (обратите внимание - почти наверняка есть библиотека или функция, которая уже делает это, но я не смог ее найти!)
shiftSeq <- function(n, shift){
#return vector 1:n, but start shifted
# e.g. shiftSeq(5,shift=1) returns c(2,3,4,5,1)
# e.g. shiftSeq(5,shift=-1) returns c(5,1,2,3,4)
if(shift>=1){
res <- c((shift+1):n, 1:(shift))
} else if(shift==0){
res <- 1:n
} else{
res <- c((n+1+shift):n, 1:(n+shift))
}
return(res)
}
> shiftSeq(5,shift=1)
[1] 2 3 4 5 1
МыЯ буду использовать эту функцию shiftSeq
внутри другой функции (ниже).Идея состоит в том, чтобы использовать apply
с shiftSeq
для смещения каждого из столбцов в диагональной матрице «строительного блока» вверх и вниз, что мы делаем несколько раз, каждый раз накапливая эту смещенную матрицу в матрице результатов.
Ключ для правильной установки rowShift
и colShift
аргументов ...
createTranProb <- function(n, prob, rowShift, colShift){
# create transition probability matrix of size nxn
# - prob is non-zero prob
# - rowShift is number of rows to move prob down
# - colShift is number of cols to move prob to right
shifts = setdiff(c(-rowShift:colShift), 0)
matDiag <- diag(n)*prob
matRes <- matDiag
for(i in shifts){
matRes <- matRes +
apply(matDiag, 2,
function(x) x[shiftSeq(n,i)])
}
return(matRes)
}
Работает для случая prob = 0.5:
> createTranProb(10, 0.5, rowShift=0, colShift=1)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0.5 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
[2,] 0.0 0.5 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0
[3,] 0.0 0.0 0.5 0.5 0.0 0.0 0.0 0.0 0.0 0.0
[4,] 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.0 0.0 0.0
[5,] 0.0 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.0 0.0
[6,] 0.0 0.0 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.0
[7,] 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.5 0.0 0.0
[8,] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.5 0.0
[9,] 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.5
[10,] 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5
Как это происходитдля prob = 0.2, если мы установим rowShift=2
и colShift=2
:
> createTranProb(10, 0.2, 2, 2)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0.2 0.2 0.2 0.0 0.0 0.0 0.0 0.0 0.2 0.2
[2,] 0.2 0.2 0.2 0.2 0.0 0.0 0.0 0.0 0.0 0.2
[3,] 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 0.0 0.0
[4,] 0.0 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 0.0
[5,] 0.0 0.0 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0
[6,] 0.0 0.0 0.0 0.2 0.2 0.2 0.2 0.2 0.0 0.0
[7,] 0.0 0.0 0.0 0.0 0.2 0.2 0.2 0.2 0.2 0.0
[8,] 0.0 0.0 0.0 0.0 0.0 0.2 0.2 0.2 0.2 0.2
[9,] 0.2 0.0 0.0 0.0 0.0 0.0 0.2 0.2 0.2 0.2
[10,] 0.2 0.2 0.0 0.0 0.0 0.0 0.0 0.2 0.2 0.2
Ради интереса, я добавил один с prob = 0.33333:
> createTranProb(10, 0.33333, 1, 1)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0.33333 0.33333 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.33333
[2,] 0.33333 0.33333 0.33333 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
[3,] 0.00000 0.33333 0.33333 0.33333 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
[4,] 0.00000 0.00000 0.33333 0.33333 0.33333 0.00000 0.00000 0.00000 0.00000 0.00000
[5,] 0.00000 0.00000 0.00000 0.33333 0.33333 0.33333 0.00000 0.00000 0.00000 0.00000
[6,] 0.00000 0.00000 0.00000 0.00000 0.33333 0.33333 0.33333 0.00000 0.00000 0.00000
[7,] 0.00000 0.00000 0.00000 0.00000 0.00000 0.33333 0.33333 0.33333 0.00000 0.00000
[8,] 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.33333 0.33333 0.33333 0.00000
[9,] 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.33333 0.33333 0.33333
[10,] 0.33333 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.33333 0.33333