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

Arrays of arrays in parameters cannot JIT compile #25

Open
fkrauer opened this issue Sep 29, 2020 · 4 comments
Open

Arrays of arrays in parameters cannot JIT compile #25

fkrauer opened this issue Sep 29, 2020 · 4 comments

Comments

@fkrauer
Copy link

fkrauer commented Sep 29, 2020

Hi

I have extended my epidemic SIR model to two age groups, which have some contact rates among each other (captured with a mixing matrix), and some transition rates (ageing, demo matrix). Since diffeqr does not accept additional arguments, I have wrapped the two matrices in "p" with an R list. However, diffeqr seems to have a problem with the array or matrix type in R.

The following code:

library(diffeqr)

maxtime <- 3650.0

# Make up some demography data
lifespan <- 80
steps <- 40
alower <- seq(0,lifespan-steps,steps) # lower boundary of age groups
alength <- c(diff(alower), steps) # duration in years in age group
ngroups <- length(alower)
demo <- matrix(data=NA, nrow=ngroups, ncol=5)

demo[,1] <- alower
demo[,2] <- 100000/lifespan*alength # Popsizes
demo[,3] <- demo[,2]/sum(demo[,2]) # proportions in each age group
demo[,4] <- c(1/(alength*365)) # ageing rates out of compartment
demo[,5] <- c(demo[nrow(demo),4], demo[1:(nrow(demo)-1),4]) # ageing rates into compartment
demo

# Make up some social mixing data
mixmat <- matrix(data=c(10.9, 4.5, 4.5, 6.1), nrow=2)

# Theta
beta <- 0.02
gamma <- 1/5
mu <- 1/(70*365)
sigma <- 1/365
k <- 5
eta <- 0.2 
phi <- 10

init <- log(c(demo[,"N"], rep(1, ngroups), rep(1e-12, ngroups))) 

theta <- c(beta=beta, gamma=gamma, sigma=sigma, eta=eta, phi=phi, ngroups=ngroups, k=k)
theta <- list(theta, demo, mixmat)

enviro <- diffeqr::diffeq_setup()

model <- function(logstate, parms, times) {
  
  # this doesnt work
  theta = as.vector(parms[[1]]) # this should be a vector
  demo = as.array(parms[[2]]) # this should be matrix/array
  mixmat = as.array(parms[[3]]) # this should be matrix/array
  
  ageout = demo[,4]
  agein = demo[,5]
  
  beta = theta[1]
  gamma = theta[2]
  sigma = theta[3]
  eta = theta[4]
  phi = theta[5]
  ngroups = theta[6]
  
  # states
  state = exp(logstate)
  S = state[(1:ngroups)+0*ngroups]
  I = state[(1:ngroups)+1*ngroups]
  R = state[(1:ngroups)+2*ngroups] 
  N = S + I + R
  
  Slower <- c(N[ngroups], S[-ngroups])
  Ilower <- c(0, I[-ngroups])
  Rlower <- c(0, R[-ngroups])
  
  # calculate FOI
  beta_eff = beta * (1+eta*sin(pi*(times-phi)/365.0)^2)
  FOI = beta_eff*colSums(mixmat*I/N)
  
  dSdt = -FOI*S + sigma*R - ageout*S  + agein*Slower
  dIdt = FOI*S - gamma*I - ageout*I + agein*Ilower
  dRdt = gamma*I - sigma*R - ageout*R + agein*Rlower
  
  return(list(cbind(dSdt/S, dIdt/I, dRdt/R)))
  
}

problem <- enviro$ODEProblem(model, init, c(0.0, maxtime), theta)
problemacc <- diffeqr::jitoptimize_ode(enviro,problem) 
solution <- enviro$solve(problemacc, enviro$AutoVern7(enviro$KenCarp4()), 
                         saveat=1.0, abstol=1e-8, reltol=1e-8) # default tolerance leads to weird behaviour with this model (generation of individuals)

throws this error:

Error: Error happens in Julia.
MethodError: no method matching reshape(::Operation, ::Int64)
Closest candidates are:
  reshape(!Matched::FillArrays.AbstractFill, ::Union{Colon, Int64}...) at C:\Users\fabienne\.julia\packages\FillArrays\RM6r2\src\FillArrays.jl:204
  reshape(!Matched::OffsetArrays.OffsetArray, ::Union{Colon, Int64}...) at C:\Users\fabienne\.julia\packages\OffsetArrays\7j7P7\src\OffsetArrays.jl:240
  reshape(!Matched::AbstractMultiScaleArray, ::Int64...) at C:\Users\fabienne\.julia\packages\MultiScaleArrays\c9WNi\src\diffeq.jl:49
  ...
Stacktrace:
 [1] simple_call(::String, ::Operation, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{,Tuple{}}}) at C:\Users\fabienne\Documents\R\win-library\4.0\JuliaCall\julia\interface1.jl:11
 [2] simple_call(::String, ::Operation, ::Vararg{Any,N} where N) at C:\Users\fabienne\Documents\R\win-library\4.0\JuliaCall\julia\interface1.jl:2
 [3] julia_extptr_callback(::Ptr{ListSxp}) at C:\Users\fabienne\.julia\packages\ Error: Error happens in Julia.
REvalError:

Is there a way around this? If not it might be necessary to write the function as JuliaCall::julia_eval. Is there an example of an ODE function that uses array/matrix calculation in Julia lang (doesn't have to be an SIR, any compartmental model will do)? Thanks

@ChrisRackauckas
Copy link
Member

Arrays and matrices are fine. The issue here seems to be that the parameters theta are an array of arrays. The JIT compilation portion cannot handle that yet. That's on the list but it'll take some time.

@ChrisRackauckas ChrisRackauckas changed the title arrays/matrix in R function not recognized in diffeqr Arrays of arrays in parameters cannot JIT compile Sep 29, 2020
@fkrauer
Copy link
Author

fkrauer commented Sep 29, 2020

ok, thanks for the info

@mbkoltai
Copy link

Hi,
I have a problem when passing a matrix as input too:
p <- c(10,28,8/3); K_lor=matrix(c(-p[1],p[1],0,p[2],-1,0,0,0,-p[3]),3,3)
f_ode_julia_vect <- function(u,x,t) {du=x%*%u + c(0,-u[1]*u[3],u[1]*u[2]); return(du) }
prob<-de_jul$ODEProblem(f_ode_julia_vect, u0,tspan,K_lor); fastprob=diffeqr::jitoptimize_ode(de_jul,prob)

gives me:
Error in x %*% u : requires numeric/complex matrix/vector arguments

(if I write 'x*u' in the equation then it's not a vector product I get.)

Does 'jitoptimize_ode' use some other notation for vector multiplication?
Thanks for any info.

@ChrisRackauckas
Copy link
Member

It tries to scalarize it. I assume the issue might be the fact that R is using a BLAS for the matmul which isn't getting properly traced and replaced. If it was using an algorithm with indexing under the hood it would.

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

3 participants