Оценка строк в Julia_Eval для решения сольвера - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь оценить строки в цикле for в сценарии R, используя JuliaCall::julia_eval. Хотя я смог выполнить это в R с помощью пакета deSolve, у меня возникают проблемы при преобразовании кода в код, совместимый с Джулией. Базовый код для правильно функционирующего кода R deSolve показан ниже.

library(deSolve)
library(dplyr)

 Combine <- c(" - 1*0.4545*(H2O2^1) - 1*27000000*(`$OH`^1)*(H2O2^1)", " - 1*3100000000*(`1,4-dioxane`^1)*(`$OH`^1)", 
    " - 1*33000*(TOC^1)*(`$OH`^1)", "2*0.4545*(H2O2^1) - 1*3100000000*(`1,4-dioxane`^1)*(`$OH`^1) - 1*33000*(TOC^1)*(`$OH`^1) - 1*27000000*(`$OH`^1)*(H2O2^1) - 1*8500000*(`$OH`^1)*(`HCO3-`^1) - 1*390000000*(`$OH`^1)*(`CO3 2-`^1)", 
    " - 1*8500000*(`$OH`^1)*(`HCO3-`^1)", " - 1*390000000*(`$OH`^1)*(`CO3 2-`^1)"
    )

time <- seq(from=0, to=0.01, by = 1E-4)
State <- c(H2O2 = 0.000294117647058824, `1,4-dioxane` = 0.00000113494, 
TOC = 0, `$OH` = 0, `HCO3-` = 0.003766104, `CO3 2-` = 0.0000167638711956647)

ODEcreater2 <- function(t, state, parameters){
  with(as.list(c(state)),{
           for (i in 1:6) { #
            dY[i] <- eval(parse(text=Combine[i]))}
      return(list(dY))
} )}

out1<- ode(y = state, times = time, func = ODEcreater2, parms = NULL)

Я пытаюсь использовать реплицировать код и запустить его в Julia, чтобы повысить скорость решения ODE с помощью diffeqr против. deSolve. К сожалению, я сталкиваюсь с оценкой строки / выражения в цикле for в julia_call.

library(diffeqr)
diffeqr::diffeq_setup()
library(JuliaCall)
julia <- julia_setup()

    ODEcreater <- JuliaCall::julia_eval("
    function (dY,t,state)
        for i in 1:6
          dY[i] = eval(Meta.parse(:Combine[i]))
    end
    end")

    tspan <- list(1E-6, 1E-3)

    sol = diffeqr::ode.solve(ODEcreater,state,tspan, abstol=1e-8, reltol=1e-8)

Кто-нибудь знает, как лучше всего оценивать строки в цикле for? Я изучал метаэкспрессы на сайте JuliaLang, но все еще потерялся.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2019

Как упомянуто в дублирующем вопросе https://stackoverflow.com/a/58766919/1544203, построение строки и затем выполнение

sprintf("function f(du,u,p,t)\n%s\nend", paste(Combine, collapse="\n"))

со стороны R создает единственную строку, которая соответствует формату, который работает. Это также оптимально, поскольку исключает любые дополнительные вызовы функций из сгенерированной функции.

0 голосов
/ 29 октября 2019

из julia docs :

parse(str; raise=true, depwarn=true)

Parse the expression string greedily, returning a single expression. An error is thrown if there are additional
  characters after the first expression. If raise is true (default), syntax errors will raise an error; otherwise, parse
  will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be
  suppressed.

  julia> Meta.parse("x = 3")
  :(x = 3)

, поэтому Meta.parse принимает строку и возвращает выражение. это должно правильно оценить:

eval(Meta.parse(Combine[i]))

Одна проблема, которую я вижу, это использование недопустимых имен переменных julia, например $OH

...