3

我有一个动态生成的函数(如果你好奇的话,可以在底部的剧透块中解释原因),我想将它包含在一个包中。我想以最小的性能损失和不使用不受支持的功能这样做。到目前为止,我想到的方法是将生成函数的代码放入.onLoad()并将函数存储options().GlobalEnv. 显然,将函数存储在其中.GlobalEnv是有风险的,因为它可能会被无意修改或删除。它也可能发生options(),不太可能是偶然发生的。

options()以最好的方式存储生成的函数吗?

我有一个多元函数,Fn用又长又丑的导数来调用它。我想创建另一个函数,它返回该函数的梯度(即每个变量中的一阶导数向量,在给定的 X 处评估)和粗麻布(即在给定的每个变量组合中评估的二阶导数矩阵X)。为了使代码可维护,我只将原始代码手动编码Fn为未计算的表达式,然后让D(), eval(),`body<-`()完成其余的工作。我最终得到了一个动态生成的函数对象,它返回我想要的结果。


Adam Hyland 的评论对这个特定问题有最简单的答案。如果您将其作为答案发布,它将被接受。但是,Richie Cotton 的回答在一般情况下非常有用,所以也谢谢你。

4

1 回答 1

6

您可以尝试使用assignInNamespaceinside .onLoad(未经测试),但就像 Adam H 在他的评论中所说的那样,听起来您正在以艰难的方式做事。

如果我正确理解了这个问题,那么您有一个导数表达式,并且您想在给定点评估该表达式,并计算该点的梯度,并计算该点的粗麻布。只需创建一个函数,该函数接受一个表达式和一个数值坐标向量来计算,然后让它吐出你想要的所有东西。像这样的东西:

#' Evaluate an expression, its derivative and its hessian
#' 
#' Evaluates an expression, its derivative and its hessian at a given point.
#' @param expr An expression of derivatives
#' @param x A named numeric vector of coords to evaluate \code{expr} at
#' @param name String giving the name of the variable to differentiate by
#' @return A list with the following values
#' \itemize{
#'   \item{value}{The value of \code{expr} evaluated at \code{x}.}
#'   \item{gradient}{The value of the derivative of \code{expr} evaluated at \code{x}.}
#'   \item{hessian}{The value of the hessian of \code{expr} evaluated at \code{x}.}
#' }
#' @examples
#' expr <- expression(sin(cos(x + y^2)))
#' x <- c(x = pi / 2, y = pi / 3)
#' eval_expr_and_calc_grad_and_hessian(expr, x, "x")
eval_expr_and_calc_grad_and_hessian <- function(expr, x, name = names(x)[1])
{
  x <- as.list(x)
  d_by_dname <- D(expr, name)
  d2_by_dname2 <- D(d_by_dname, name)
  list(
    value    = eval(expr, x),
    gradient = eval(d_by_dname, x),
    hessian  = eval(d2_by_dname2, x)
  )
}
于 2013-06-07T14:40:33.117 回答