Dear Stan users:
I have been having difficulty in constructing a row-wise Kronecker product in Stan.
Suppose my two matrices are
A<- matrix(c(1,2,3,4,0,0),nrow=2,byrow=TRUE)
B <- matrix(c(0,5,6,7),nrow=2,byrow=TRUE)
Then a row-wise Kronecker product in R can be coded as
A[, rep(seq(ncol(A)), each = ncol(B))] * B[, rep(seq(ncol(B)),ncol(A))]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 5 0 10 0 15
[2,] 24 28 0 0 0 0
Now, I would like to construct the same thing using Rstan, but I cannot get my head around the index. I know how to construct the normal Kronecker in Stan between two matrices
The following code credited a fellow Stan user Tanner Sorensen
data{
int<lower=1> m; // in GAM model, m=p=num_data
int<lower=1> n;
int<lower=1> p; //in GAM model, m=p=num_data
int<lower=1> q;
matrix[m,n] A;
matrix[p,q] B;
}
parameters{real<lower=0,upper=1> DUMMY;}
model{}
generated quantities{
matrix[m*p,n*q] C;
for (i in 1:m)
for (j in 1:n)
for (k in 1:p)
for (l in 1:q)
C[p*(i-1)+k,q*(j-1)+l] = A[i,j]*B[k,l];
}
As the row-wise Kron matrix in R is
B_true_int= matrix(nrow=dim(A)[1], ncol=dim(A)[2]*dim(B)[2])
for(i in 1:dim(A)[1]){
B_true_int[i,]=kronecker(A[i,],B[i,])
}
Then my initial thought was to replicate Tanner’s code through first extracting the row of A and row of B.
I define
generated quantities{
matrix[m,n*q] M;
for (i in 1:m)
for (j in 1:n)
for (k in 1:p)
for (l in 1:q)
M[i, q*(j-1)+l] = to_matrix( row(A,i)) [i, j] * to_matrix( row(B, i))[k,l];
}
I have figured out a naive way of constructing a row-wise Kron product matrix.
In order to construct a row-wise Kron matrix, both matrices should have the same number of rows and thus through inspection, the relationship between a row-wise Kron and a full Kron matrix is as follows:
generated quantities{
//m is # of rows in matrix A
//n is # of cols in matrix A
//p is # of rows in matrix B
//q is # of rows in matrix B
matrix[m*p,n*q] C; // full Kron product matrix
matrix[m,n*q] M; //row-wise Kron product matrix
for (i in 1:m)
for (j in 1:n)
for (k in 1:p)
for (l in 1:q)
C[p*(i-1)+k,q*(j-1)+l] = A[i,j]*B[k,l];
for(i in 1:m)
M[i,] = C[m*(i-1)+i,];
}
However, currently I just experiment using a very small simulated data but my real dataset is quite large and I feel like it is quite redundant to first construct a full kronecker matrix and then extract desired rows from the matrix to construct the row-wise kronecker matrix.
Any ideas or advice that I can alternatively speed up the construction process?
Thanks in advance
Jaslene