我的目标是编写一个R函数,接受分数多项式(FP)的系数,并返回一个向量化的函数,该函数可以为给定的输入数字计算指定的FP。FP定义有两个重要规则:
一个例子是
- x ^ 0被定义为log(x)
- 幂可以有多个系数,其中幂p的第二个系数将一个log(x)因子添加到加法项(x ^ p * log(x)),第三个系数添加一个log(x)^ 2因子(x ^ p * log(x)^ 2),依此类推
我的当前解决方案是构建FP函数作为字符串,解析字符串并返回评估表达式的函数。我的问题是是否有更好/更快的方法,可以避免使用eval(parse())
- 可能使用一些substitute()
魔法。
该函数必须处理在调用时未知每个幂的系数数量,但在调用时指定。最终的FP评估需要快速,因为它经常被调用。
希望不仅限于标准的幂次-2,-1,-0.5,0,0.5,1,2,3,这将是一个好的选择。理想情况下,所需函数可以同时执行两个步骤:接受FP系数和数字向量,并返回输入的FP值,同时仍然保持快速。
getFP <- function(p_2, p_1, p_0.5, p0, p0.5, p1, p2, p3, ...) {
p <- as.list(match.call(expand.dots=TRUE)[-1]) # all args
names(p) <- sub("^p", "", names(p)) # strip "p" from arg names
names(p) <- sub("_", "-", names(p)) # replace _ by - in arg names
## for one power and the i-th coefficient: build string
getCoefStr <- function(i, pow, coefs) {
powBT <- ifelse(as.numeric(pow), paste0("x^(", pow, ")"), "log(x)")
logFac <- ifelse(i-1, paste0("*log(x)^", i-1), "")
paste0("(", coefs[i], ")*", powBT, logFac)
}
onePwrStr <- function(pow, p) { # for one power: build string for all coefs
coefs <- eval(p[[pow]])
pwrStr <- sapply(seq(along=coefs), getCoefStr, pow, coefs)
paste(pwrStr, collapse=" + ")
}
allPwrs <- sapply(names(p), onePwrStr, p) # for each power: build string
fpExpr <- parse(text=paste(allPwrs, collapse=" + "))
function(x) { eval(fpExpr) }
}
一个例子是
-1.5*x^(-1) - 14*log(x) - 13*x^(0.5) + 6*x^0.5*log(x) + 1*x^3
,其中指定了幂次 (-1, 0, 0.5, 0.5, 3),对应的系数为 (-1.5, -14, -13, 6, 1)。> fp <- getFP(p_1=-1.5, p0=-14, p0.5=c(-13, 6), p3=1)
> fp(1:3)
[1] -13.50000000 -14.95728798 0.01988127
function(pwrs,coeffs)
,其中pwrs
和coeffs
是幂和系数的等长向量? - Carl Witthoftexpression
包装的方程,然后使用substitute
在适当的位置交换值,例如substitute(expression(p1*x + p2*x),list(p1=p1, p0=p0))
。 - Thomasfor()
循环。 - caracallog(x)
来替换某些内容。您可以替换任何幂和系数...我将上面留下的作为注释,因为它远非完整的解决方案。 - Thomas