私の目標は、分数多項式(FP) の係数を受け入れ、指定された入力数値に対して指定された FP を評価するベクトル化された関数を返す関数を R で記述することです。FP 定義には 2 つの重要なルールがあります。
- x^0 は log(x) として定義されます
- べき乗は複数の係数を持つことができます。ここで、べき乗 p の 2 番目の係数は加法項 (x^p*log(x)) に log(x) の係数を追加し、3 番目は log(x)^2 の係数を追加します (x ^p*log(x)^2) など
以下の私の現在のソリューションは、FP 関数を文字列として構築し、文字列を解析して、式を評価する関数を返します。私の質問は、回避するより良い/より高速な方法があるかどうかですeval(parse())
-おそらくいくつかのsubstitute()
魔法を使用します。
関数は、事前に知られていないが、呼び出されたときに指定されたべき乗あたりの係数の数を処理する必要があります。最終的な FP 評価は頻繁に呼び出されるため、高速である必要があります。
標準の累乗 -2、-1、-0.5、0、0.5、1、2、3 に限定されないことが望ましいでしょう。理想的には、目的の関数は一度に 2 つのステップを実行します: 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.5, -14, -13, 6, 1) でべき乗 (-1, 0, 0.5, 0.5, 3) を指定したものがあります。
> 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