问题描述
考虑以下我通过RStan使用的Stan脚本:
data {
int K; //outcome classes
int N; //rows
int D; //input dimensions
int y[N];
matrix[N,D] X;
real days[N];
}
parameters {
matrix[D,K] C;
matrix[D,K] B;
}
model {
matrix[N,K] pred = X*C + days*X*B; //If I remove days,it works fine.
to_vector(pred) ~ normal(0,5);
for (n in 1:N)
y[n] ~ categorical_logit(pred[n]');
}
一个不受欢迎的解决方案是,仅复制R中的days列,使其成为矩阵,并可以用于矩阵乘法。但这真的有必要吗?应该很容易通过标量值“缩放”矩阵。
错误是:
编辑:我也将天数转换为矩阵matrix[N,1] days[N]
。虽然确实通过了“清理”,但由于尺寸不匹配而在编译时被拒绝。
Edit2:我已经调整了代码,现在可以执行了。但是我感到困惑,为什么甚至有必要使用嵌套的for循环。应该有一种简单的方法将所有矢量元素乘以相同的标量值。
data {
int K; //outcome classes,3
int N; //num rows
int D; //input dimensions,5
int Y[N];
matrix[N,D] X;
int days[N];
}
parameters {
matrix[D,K] C; //[5,3]
matrix[D,K] B; //[5,3]
}
model {
for (n in 1:N){
vector[K] pred;
vector[D] ipt;
matrix[K,K] day_diag;
for (i in 1:K){
for (j in 1:K){
if (i == j)
day_diag[i,j] = days[n];
else
day_diag[i,j] = 0;
}
}
ipt = X[n]'; // Now row_vector [1xD]
// [D,K] x [1,D] + [D,D]
pred = C * ipt + B * (day_diag * ipt);
Y[n]~categorical_logit(pred);
}
}
解决方法
要按向量的相应值缩放矩阵的每一行,可以使用diag_pre_multiply()
,因此它将为diag_pre_multiply(days,B)
。天将需要以vector[N] days
而不是真实的形式读入。
顺便说一句,Stan定义了许多矩阵运算,请参见:https://mc-stan.org/docs/2_25/functions-reference/matrix-operations.html