Arrays 一种计算数组求和雅可比矩阵的简洁方法
我在R中做一些优化,与之相关,我需要编写一个返回雅可比矩阵的函数。这是一个非常简单的雅可比矩阵——只有0和1——但我想快速、干净地填充它。我当前的代码可以工作,但非常草率 我有一个四维的概率数组。按Arrays 一种计算数组求和雅可比矩阵的简洁方法,arrays,r,derivative,matrix-indexing,Arrays,R,Derivative,Matrix Indexing,我在R中做一些优化,与之相关,我需要编写一个返回雅可比矩阵的函数。这是一个非常简单的雅可比矩阵——只有0和1——但我想快速、干净地填充它。我当前的代码可以工作,但非常草率 我有一个四维的概率数组。按i、j、k、l索引尺寸。我的限制是,对于每个i,j,k,索引l上的概率之和必须等于1 我计算约束向量如下: get_prob_array_from_vector <- function(prob_vector, array_dim) { return(array(prob_vector,
i、j、k、l
索引尺寸。我的限制是,对于每个i,j,k
,索引l
上的概率之和必须等于1
我计算约束向量如下:
get_prob_array_from_vector <- function(prob_vector, array_dim) {
return(array(prob_vector, array_dim))
}
constraint_function <- function(prob_vector, array_dim) {
prob_array <- get_prob_array_from_vector(prob_vector, array_dim)
prob_array_sums <- apply(prob_array, MARGIN=c(1, 2, 3), FUN=sum)
return(as.vector(prob_array_sums) - 1) # Should equal zero
}
我的函数以
prob\u vector
作为输入,即概率数组的平坦表示,因为优化函数需要向量参数。花一些时间来理解您试图做的事情,但这里有一个命题来替换您的约束函数\u jacobian
:
enhanced <- function(prob_vector,array_dim) {
firstdim <- Reduce("*", array_dim[1:3])
seconddim <- length(prob_vector)
jacobian <- matrix(0, firstdim, seconddim)
idxs <- split(1:seconddim,cut(1:seconddim,array_dim[4],labels=F))
for( i in seq_along(idxs)) {
diag(jacobian[, idxs[[i]] ]) <- 1
}
stopifnot(sum(jacobian) == length(prob_vector))
stopifnot(all(jacobian == 0 | jacobian == 1))
jacobian
}
根据benchmark,它提供了极大的加速:
> microbenchmark(constraint_function_jacobian(my_prob_vector,array_dim),enhanced(my_prob_vector,array_dim),times=100)
Unit: microseconds
expr min lq mean median uq max neval cld
constraint_function_jacobian(my_prob_vector, array_dim) 16946.979 18466.491 20150.304 19066.7410 19671.4100 28148.035 100 b
enhanced(my_prob_vector, array_dim) 678.222 737.948 799.005 796.3905 834.5925 1141.773 100 a
谢谢,这是一个坚实的进步!
> identical(constraint_function_jacobian(my_prob_vector,array_dim),enhanced(my_prob_vector,array_dim))
[1] TRUE
> microbenchmark(constraint_function_jacobian(my_prob_vector,array_dim),enhanced(my_prob_vector,array_dim),times=100)
Unit: microseconds
expr min lq mean median uq max neval cld
constraint_function_jacobian(my_prob_vector, array_dim) 16946.979 18466.491 20150.304 19066.7410 19671.4100 28148.035 100 b
enhanced(my_prob_vector, array_dim) 678.222 737.948 799.005 796.3905 834.5925 1141.773 100 a