有多種問題在這裏:
- 你的方程是不標準C代碼。來自Mathematica的
CForm[]
不會將您的代碼轉換爲正確的C語法。也許你可以關注this answer並用SymbolicC
來解決這部分問題
- 你的問題更多的是關於從語言A到語言B的解析。正如在評論中提到的@Olaf:你可能會更好或者使用一個真正的C函數和來自R調用或手動轉換它,這取決於你做這個
多久不過,按你的請求(如果我正確理解你想達到的目的)和教育目的;這裏的中,我們將用R轉換你的「僞C」字符串,並創建一個內聯cfunction()
注意一個例子:這是沒有意思的意圖是優雅或實用的,但總的思路應該希望能幫助你起步
假設下面的公式:
v1 <- "4 * Power(Omega * (-(R * Gamma) + R),(Tau + R))"
摘自原始字符串的所有變量和函數
n1 <- stringi::stri_extract_all_words(v1)[[1]]
創建的「功能重新編寫」一個名爲向量(如果沒有他們,沒有NUMERICS一個子集)
newFunc <- c("Power" = "pow")
n2 <- setdiff(n1, names(newFunc))
n3 <- n2[is.na(as.numeric(n2))]
構建替換列表養活gsubfn()
。對於這個例子的目的,我們用新的取代舊的功能和包裝asReal()
周圍的變量
toreplace <- setNames(
as.list(c(newFunc, paste0("asReal(", n3, ")"))),
c(names(newFunc), n3)
)
v2 <- gsubfn::gsubfn(paste(names(toreplace), collapse = "|"), toreplace, v1)
然後,您可以通過這個新的字符串到cfunction()
R中執行
#install.packages("inline")
library(inline)
foo <- cfunction(
sig = setNames(rep("integer", length(n3)), n3),
body = paste0(
"SEXP result = PROTECT(allocVector(REALSXP, 1));
REAL(result)[0] = ", v2, ";
UNPROTECT(1);
return result;"
)
)
這應該是比使用eval(parse("..."))
與^
或限定Power()
函數更快
Tau = 21; Omega = 22; R = 42; Gamma = 34
Power <- function(x,y) {x^y}
microbenchmark::microbenchmark(
C = foo(Omega, R, Gamma, Tau),
R1 = eval(parse(text="4 * ((Omega * (-(R * Gamma) + R))^(Tau + R))")),
R2 = eval(parse(text="4 * Power(Omega * (-(R * Gamma) + R),(Tau + R))")),
times = 10L
)
#Unit: microseconds
# expr min lq mean median uq max neval
# C 1.233 2.194 5.9555 2.9955 3.302 34.194 10
# R1 190.012 202.781 230.5187 218.1035 243.891 337.209 10
# R2 189.162 191.798 374.5778 207.6875 225.078 1868.746 10
這不是標準的C代碼,甚至不是一個表達式。 – Olaf
我提供的第一個代碼是Mathematica的CForm []輸出的一部分,作爲字符串導入到R中。其餘全部是R代碼。謝謝。 – TK2013
@Olaf是對的。這不是標準的C代碼。不要相信'CForm []'將Mathematica表達式轉換爲C ...看看[this](https://mathematica.stackexchange.com/questions/46844/real-and-or-improved-cform-的表達式) –