I am having trouble to convert a Matlab loop into R.
For every {t,tau}, calculate the o indexed with a value that refers to the value of [t,tau]
from within the loop. In the matlab code it is done via a cell structure that applies from outside the loop.
o{1,1} = [1 0]';
o{1,2} = [0 0]';
o{2,1} = [1 0]';
o{2,2} = [0 1]';
Within the loop something like this is calculated:
nat_log(A'*o{t,tau})
How can I manage the loop to use the values of t and tau that I set within the loop in order to adress certain "o" within a list?
First my attempt:
Timesteps = 2 # total timesteps/iterations
Tau = 2 # amounts of observations o within 1 timestep; at t=1 and tau-1 = o = [0 0], above denoted {1,2}
for(t in 1:length(Timesteps)){
qs[,t] = matrix(c(.5,.5)) # This is the posterior distribution to be updated,
for (t in 1:length(Timesteps)){ # but that's not that important
for (tau in 1:length(Timesteps)){
****some more math****
y = x * o[[t,tau]] # THIS is the important part!
etc. .... ..... .... ....
I tried something like
o<- vector("list", length = 2 * 2)
dim(o) <- matrix(c(2, 2))
o[[1,1]] <- matrix(c(1, 0), nrow = 2, ncol =1, byrow = TRUE)
o[[1,2]] <- matrix(c(0, 0), nrow = 2, ncol =1, byrow = TRUE)
o[[2,1]] <- matrix(c(1, 0), nrow = 2, ncol =1, byrow = TRUE)
o[[2,2]] <- matrix(c(0, 1), nrow = 2, ncol =1, byrow = TRUE)
The orginial matlab code that I am trying to reproduce can be found here:
https://github.com/rssmith33/Active-Inference-Tutorial-Scripts/blob/main/Pencil_and_paper_exercise_solutions.m
Line: 46-103 (it is essentially Bayes inference with Markov property...)
If someone has an idea, I would be very thankful. I am just a med student interested in math and would love to see this available for R as well.
Related
I am totally new to R and I am struggling to write a code to find the numerical derivatives of vector fields. I have two matrices U and V, e.g.,
U <- matrix(runif(9), nrow = 3, ncol = 3, byrow = T)
V <- matrix(runif(9), nrow = 3, ncol = 3, byrow = T)
These matrices (not actual values obviously) represents the components of a 2D wind vector field. I would like to code the numerical derivatives of the 2 vector components du/dy and dv/dx. I have no idea how to do this in R. Please help. Sorry in advance if this question has been answered already.
What you are looking for is the diff() function. You can apply it efficiently over a dimension of a matrix using an apply
U <- matrix(runif(9), nrow = 3, ncol = 3, byrow = T) #Your wind component
apply(U,2,diff) #change the '1' by '2' to apply diff over the other dim
Hope this helped.
to put it simply, I have a list of DFMs created by quanteda package(LD1). each DFM has different texts of different lengths.
now, I want to calculate and compare lexical diversity for each text within DFMs and among DFMs.
lex.div <-lapply(LD1, function(x) {textstat_lexdiv(x,measure = "all")})
this leaves me with a list of S3 type data, and within each of which, there are different attributes that are lexical diversity measures.
lex.div[[1]]$TTR
[1] 0.2940000 0.2285000 0.2110000 0.1912500 0.1802000 0.1671667 0.1531429 0.1483750 0.1392222
[10] 0.1269000
lex.div[[2]]$TTR
[1] 0.3840000 0.2895000 0.2273333 0.2047500 0.1922000 0.1808333 0.1677143 0.1616250 0.1530000
[10] 0.1439000 0.1352727 0.1279167 0.1197692 0.1125000 0.1069333
here comes the problem. I need all the TTR values in one matrix. i want lex.div[[1]]$TTR to be the first row of the matrix, lex.div[[2]]$TTR to be the second, and so on. note that the length of lex.div[[1]]$TTR ≠ lex.div[[2]]$TTR.
here is what I've done so far:
m1 <-matrix(lex.div[[1]]$TTR, nrow = 1, ncol = length(lex.div[[1]]$TTR))
m.sup <- if(ncol(m1) < 30) {mat.to.add = matrix(NA, nrow = nrow(m1), ncol = 30 - ncol(m1))}
m1 <-cbind(m1, m.sup)
m2 <-matrix(lex.div[[2]]$TTR, nrow = 1, ncol = length(lex.div[[2]]$TTR))
m.sup <- if(ncol(m2) < 30) {mat.to.add = matrix(NA, nrow = nrow(m2), ncol = 30 - ncol(m2))}
m2 <-cbind(m2, m.sup)
m3 <-matrix(lex.div[[3]]$TTR, nrow = 1, ncol = length(lex.div[[3]]$TTR))
m.sup <- if(ncol(m3) < 30) {mat.to.add = matrix(NA, nrow = nrow(m3), ncol = 30 - ncol(m3))}
m3 <-cbind(m3, m.sup)
...
m.total <-rbind (m1,m2,m3...)
but I cannot do it this way. can you help me write a for loop or sth to get it done easier and quicker?
You can try the code below
TTRs <- lapply(lex.div, `[[`, "TTR")
m <- t(sapply(TTRs, `length<-`, max(lengths(TTRs))))
I want to quantify the structural effect of an event in a Time Series analysis. For doing so I'm using what the KFAS package has to offer.
The problem is that the code seems to get a bit tricky if I want to model simultaneously n different dates, so n different events.
Here's some example that should clarify, I hope:
library(fpp2)
library(KFAS)
# required libraries
y <- hyndsight # just for the example
plot(hyndsight)
abline(v = c(19, 35, 47), col = "red", lwd = 2)
Let's say that I want to check if each of the "red-line" event is a "permanent shock" (ie: it changes the level of the hyndsight series). Now here's the model that can do that with KFAS functions:
# Z and T component for event on pos 19
aZ1 <- array(0, c(1, 1, length(y)))
aZ1[1, 1, (19 + 1):length(y)] <- 1 # 1s from pos 19(+1) forward
aT1 <- array(1, c(1, 1, length(y)))
# Z and T component for event on pos 35
aZ2 <- array(0, c(1, 1, length(y)))
aZ2[1, 1, (35 + 1):length(y)] <- 1 # 1s from pos 35(+1) forward
aT2 <- array(1, c(1, 1, length(y)))
# Z and T component for event on pos 47
aZ3 <- array(0, c(1, 1, length(y)))
aZ3[1, 1, (47 + 1):length(y)] <- 1 # 1s from pos 47(+1) forward
aT3 <- array(1, c(1, 1, length(y)))
And here's the actual model:
mod <- SSModel(y~0+SSMtrend(2, list(NA, NA))+SSMseasonal(12, NA)+
SSMcustom(Z = aZ1, T = aT1,
R = matrix(0, 1, 0), Q = matrix(0, 0, 0),
a1 = 0, P = matrix(0), P1inf = matrix(1))+ # first event
SSMcustom(Z = aZ2, T = aT2,
R = matrix(0, 1, 0), Q = matrix(0, 0, 0),
a1 = 0, P = matrix(0), P1inf = matrix(1))+ # second event
SSMcustom(Z = aZ3, T = aT3,
R = matrix(0, 1, 0), Q = matrix(0, 0, 0),
a1 = 0, P = matrix(0), P1inf = matrix(1)), # third event
H = NA)
initial_val <- c(0,0,0,0,0,0,0) # the first 4 are always there
fit <- fitSSM(mod, intits = initial_val)
Now, the question is, how can I "automate" this process depending on the number of events that I want to model?
As you can see, for each event, I need to create a vector aZ and a vector aT. Those need to be passed in the model via the SSMcustom function, what if I have a new time series and I need to evaluate just two events, or four or more.
The problem is that I cannot keep adding SSMcustom to the model, I want to pass a new time series with a vector of n events, and automatically build the same model, except for the number of events to evaluate. Can I build a unique SSMcustom for all the events?
Also initial_val has to change, but that's less complicate it's always 4 + n, with n the number of events.
I know this question is a lot specific, maybe it's more for CrossValidated, but I'm not so sure.
Introduce "permanent shock" variables equals to 0 before the shock and equals to 1 after the shock (one variable per shock). Then add these variables as explanatory variables (regressors) in you model and look if they are significant.
Take care that each of these variables will reduce the degree of freedom. So you may want to test the model with the same coefficient for all the shocks.
I'm trying to create a block matrix using a loop in R, which depend on some variable I call T. The two matrices used to construct the block matrix could look like this:
A=matrix(c(1,0.3,0.3,1.5),nrow=2)
B=matrix(c(0.5,0.3,0.3,1.5),nrow=2)
So depending on what i set T to, I need different results. For T=2:
C=rbind(cbind(A,B),cbind(B,A))
For T=3:
C=rbind(cbind(A,B,B),cbind(B,A,B),cbind(B,B,A))
For T=5:
C=rbind(cbind(A,B,B,B,B),cbind(B,A,B,B,B),cbind(B,B,A,B,B),cbind(B,B,B,A,B),cbind(B,B,B,B,A))
So basically, I'm just trying to create a loop or something similar, where I can just specify my T and it will create the block matrix for me depending on T.
Thanks
You can do that:
N <- nrow(A)
C <- matrix(NA,N*T,N*T)
for (i in 1:T){
for (j in 1:T){
if (i == j)
C[(i-1)*N+1:N, (j-1)*N+1:N] <- A
else
C[(i-1)*N+1:N, (j-1)*N+1:N] <- B
}
}
From your explanation I suppose that you want single A and T-1 Bs in your final matrix.
If that is correct then here is a quick try using the permn function from the combinat library. All I am doing is generating the expression using the permutation and then evaluating it.
A = matrix(c(1,0.3,0.3,1.5),nrow=2)
B = matrix(c(0.5,0.3,0.3,1.5),nrow=2)
T = 5
x = c("A", rep("B",T-1))
perms = unique(permn(x)) #permn generates non-unique permutations
perms = lapply(perms, function(xx) {xx=paste(xx,collapse=","); xx=paste("cbind(",xx,")")})
perms = paste(perms, collapse=",")
perms = paste("C = rbind(",perms,")",collapse=",")
eval(parse(text=perms))
With the blockmatrix package this is pretty straightforward.
library(blockmatrix)
# create toy matrices (block matrix elements)
# with values which makes it easier to track them in the block matrix in the example here
A <- matrix("a", nrow = 2, ncol = 2)
B <- matrix("b", nrow = 2, ncol = 2)
# function for creating the block matrix
# n: number of repeating blocks in each dimension
# (I use n instead of T, to avoid confusion with T as in TRUE)
# m_list: the two matrices in a list
block <- function(n, m_list){
# create a 'layout matrix' of the block matrix elements
m <- matrix("B", nrow = n, ncol = n)
diag(m) <- "A"
# build block matrix
as.matrix(blockmatrix(dim = dim(m_list[[1]]), value = m, list = m_list))
}
# try with different n
block(n = 2, m_list = list(A = A, B = B))
block(n = 3, m_list = list(A = A, B = B))
block(n = 5, m_list = list(A = A, B = B))
I have a list of data.frames, and would like to operate on their columns, using various weights.
For example, subtracting the first columns from the second column (solved, see below); or subtracting the first and third from twice the second (unsolved).
Thanks to the generous help obtained in response to this question, I have a solution to the the problem in two dimensions without weights using Reduce.
I would like to have the flexibility to operate with weights - and in higher dimesions.
What I have so far is:
priceList <- data.frame(aaa = rnorm(100, 100, 10), bbb = rnorm(100, 100, 10),
ccc = rnorm(100, 100, 10), ddd = rnorm(100, 100, 10),
eee = rnorm(100, 100, 10), fff = rnorm(100, 100, 10),
ggg = rnorm(100, 100, 10)
)
colDiff <- function(x)
{
Reduce('-', rev(x))
}
tradeLegsList <- combn(names(priceList), 3, function(x) priceList[x], simplify = FALSE)
tradeList <- lapply(tradeLegsList, colDiff)
From what I can tell, Reduce is not designed to take multiple arguments.
I can do this the long way with 2* tradeLegsList[[1]]$bbb - tradeLegsList[[1]]$aaa - tradeLegsList[[1]]$ccc, and some loops, but it doesn't seem like the R way.
Is there a way to pass in a weight vector?
Ideally, I would to pass an argument such as w = c(-1, 2, -1) to the colDiff (or Reduce) function ... or something similar.
True, Reduce is not geared to allow multiple arguments, just two for each reduction. Therefore it is easiest to premultiply the elements in the list you are Reduce-ing.
Below is a solution that does this using mapply within your colDiff function definition.
Change your definifion of colDiff to allow a weight vector, and apply this using mapply
with SIMPLIFY = F.
EDIT
In light of the comments, weighting depends on the number of columns and there being no need for the rev
The weighting by length
length(x) == 1 -> w = 1
length(x) == 2 -> w = c(-1, 1),
length(x) == 3 -> w = c(-1, 2, -1),
length(x) == 4 -> w = c(-1, 1, -1, +1)
weighting <- function(i){
switch(i, 1, c(-1,1), c(-1,2,-1), c(-1,1,-1, 1))
}
colDiff <- function(x)
{
w = weighting(length(x))
Reduce('+', mapply('*', x, e2 = w, SIMPLIFY = F))
}
Then something like this would work
tradeList <- lapply(tradeLegsList, colDiff)
you could also keep with the functional programming theme and use Map which is a simple wrapper for mapply with SIMPLIFY = F
colDiff <- function(x)
{
w = weighting(length(x))
Reduce('+', Map('*', x , e2 = w))
}
you could also prefine the weighting within the function colDiff (which may be easier).
weighting[[2]] is weighting for when there are 2 columns, weighting[[3]] when there are 3.
colDiff <- function(x)
{
weighting <- list(1, c(-1,1), c(-1,2,-1), c(-1,1,-1, 1))
w = weighting[[length(x)]]
Reduce('+', Map('*', x , e2 = w))
}