我想要包含在一个包中,我有一个动态生成的函数(如果你好奇的话,在底部的扰流器块中解释的原因)。我想以最小的性能损失并且不使用不受支持的功能来实现。到目前为止,我想这样做的方法是将生成函数的代码放入.onLoad()
,并将函数存储在options()
中,或者作为隐藏对象存储在.GlobalEnv
中。显然,将函数存储在.GlobalEnv
中是有风险的,因为它可能会被无意中修改或删除。它也可能发生options()
,不太可能发生意外。
将生成的函数存储在options()
中是最好的方法吗?
我有一个多变量函数,用长而丑的衍生物称它为
Fn
。我想创建另一个函数,它返回该函数的梯度(即每个变量中的一阶导数的矢量,在给定的X处求值)和一个粗体(即在给定的每个变量组合中的二阶导数的矩阵) X)。为了使代码可维护,我只将原始Fn
手动编码为未评估的表达式,然后让D()
,eval()
和`body<-`()
执行其余工作。我最终得到一个动态生成的函数对象,它返回我想要的结果。
Adam Hyland的评论对这个具体问题有最简单的答案。如果您将其作为答案发布,则会被接受。但是,Richie Cotton的答案在一般情况下非常有用,所以也要感谢你。
答案 0 :(得分:6)
您可以尝试在assignInNamespace
内使用.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)
)
}