我的目标是在 R 中编写一个函数,它接受分数多项式(FP) 的系数并返回一个向量化函数,该函数评估给定输入数字的指定 FP。FP 定义有两个重要的规则:
- x^0 定义为 log(x)
- powers 可以有多个系数,其中 power 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