Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition diffeqr to JuliaConnectoR? #19

Closed
ChrisRackauckas opened this issue Jul 23, 2020 · 6 comments
Closed

Transition diffeqr to JuliaConnectoR? #19

ChrisRackauckas opened this issue Jul 23, 2020 · 6 comments

Comments

@ChrisRackauckas
Copy link
Member

It seems like it could be beneficial to offer a more direct interface, like we do with diffeqpy (https://github.com/SciML/diffeqpy). This package might mostly become documentation for how to do things, along with a few helper functions. @stefan-m-lenz what do you think?

@stefan-m-lenz
Copy link

Thanks for asking! I'll take a closer look ...

@stefan-m-lenz
Copy link

stefan-m-lenz commented Jul 23, 2020

If you "translate" the example from the documentation of DifferentialEquations to R with the JuliaConnectoR, it looks like this:

Original Julia code:

using DifferentialEquations
f(u,p,t) = 1.01*u
u0 = 1/2
tspan = (0.0,1.0)
prob = ODEProblem(f,u0,tspan)
sol = solve(prob,reltol=1e-6,save_everystep=false)
sol(0.45)

"Translated" R code:

Loading the stuff:

library(JuliaConnectoR)

# if it's not installed already
Pkg <- juliaImport("Pkg")
Pkg$add("DifferentialEquations") 

de <- juliaImport("DifferentialEquations")

Then the real action:

f <- function(u,p,t) {1.01*u}
u0 <- 1/2
tspan <- c(0.0, 1.0)
prob <- de$ODEProblem(f,u0,tspan)
sol <- de$solve(prob, de$Tsit5(), reltol=1e-6, save_everystep=FALSE)
sol[[2]]

The JuliaConnectoR doesn't get (yet) that sol is also usable as function, so we need to use map to evaluate it:

juliaCall("map", sol, 0.45)

It is also possible to specify fas a Julia function. This is much more efficient because no communication between Julia and R is necessary during solving the equation.

f <- juliaEval("(u,p,t) -> 1.01u")
prob <- de$ODEProblem(f,u0,tspan)
sol <- de$solve(prob, de$Tsit5(), reltol=1e-6, save_everystep=FALSE)

There is one caveat: The JuliaConnectoR was designed with convenience and stability for interactive use. That's why we chose TCP as communication mechanism between Julia and R. But, of course, TCP has a higher cost for the communication when making calls between Julia and R. In every step of the iteration some binary numbers must be sent between Julia and R if the function that is to be optimized is an R function. (If it's a Julia function, this doesn't matter.) There would probably be the need for doing some further benchmarking against the current implementation of diffeqr to decide.

@stefan-m-lenz
Copy link

stefan-m-lenz commented Jul 24, 2020

I tried to do some benchmarking, but I got an error in diffeqr. That is the code that I tried:

de <- juliaImport("DifferentialEquations")
f <- function(u,p,t) {1.01*u}
u0 <- 1/2
tspan <- c(0.0, 1.0)
system.time(for (i in 1:100) {
    prob <- de$ODEProblem(f,u0,tspan)
    sol <- de$solve(prob, reltol=1e-6)
})


library(diffeqr)
diffeqr::diffeq_setup() # edit/update (see below)
f <- function(u,p,t) {1.01*u}
u0 <- 1/2
tspan <- list(0.0, 1.0)
system.time(for (i in 1:100) {
    ode.solve(f, u0 = u0, tspan = tspan, reltol=1e-6)
})

I get the following error with diffeqr when running ode.solve:

> diffeqr::ode.solve(f, u0 = u0, tspan = tspan, reltol=1e-6)
Error: Error happens in Julia.
UndefVarError: ODEProblem not defined
Stacktrace:
 [1] top-level scope at none:0
 [2] eval(::Module, ::Any) at ./boot.jl:331
 [3] eval_string(::String) at /opt/R/R-4.0.2/lib/R/library/JuliaCall/julia/setup.jl:195
 [4] docall(::Ptr{Nothing}) at /opt/R/R-4.0.2/lib/R/library/JuliaCall/julia/setup.jl:168

I don't know what is wrong. I use R version 4.0.2, Julia version 1.4.2 and DifferentialEquations version 6.15.0.

@ChrisRackauckas
Copy link
Member Author

Did you run diffeqr::diffeq_setup()?

@stefan-m-lenz
Copy link

stefan-m-lenz commented Jul 25, 2020

No, after running diffeqr::diffeq_setup() it worked. (I added it to the code above.)
The above benchmark shows the following results on my computer (measured after first run):
When executing the code without the loop, the speed difference is not noticable for the human perception, I would say. With the loop, there is a significant difference:

Elapsed time for calling the diffeqr code in the loop above a 100 times: 0.4s

Elapsed time for calling the JuliaConnectoR code in the loop above a 100 times, using an R function: 29s

Elapsed time for calling the JuliaConnectoR code in the loop above a 100 times, using a Julia function: 1.4s

In this case, we have the additional overhead of two calls and one additional assignment for the JuliaConnectoR vs one call in the diffeqr implementation, which explains that there is still a difference when using the Julia function.

I also report that during one time of exeuting the diffeqr code, I had a segfault/system error, which crashed R.

@ChrisRackauckas
Copy link
Member Author

diffeqr is probably more suitable for this specific project, though JuliaConnectoR is great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants