In the R Package deSolve, Writing Code in Compiled Languages there is a prototype and example
void derivs (int *neq, double *t, double *y, double *ydot,double *yout, int *ip)
The documentation says:
*ip points to an integer vector whose length is at least 3; the first element (ip[0]) contains the number of output values (which should be equal or larger than nout), its second element contains the length of *yout, and the third element contains the length of *ip; next are integer values, as passed by parameter ipar when calling the integrator.
But in fact there is no way to pass *ip to your C or Fortran derivs subroutine. To get code to run you have to call ode() with a named parameter nout because the routine that checks and loads the DLL requires it. However, the value passed for nout becomes ip(1) in the Fortran derivs subroutine.
It is not clear to me what is going on. The output from the example in the vignette is a matrix dim(13,7) while the values in ip() in the derivs() subroutine is always ip(1) = nout, ip(2) = nout+2, ip(3) = 4. The output is exactly the same independent of the value of nout.
If have the deSolve source code and grep searches for ip being declared or set yield NULL.
Does ip have any role in the actual calculation?
The
*ip
argument is passed to thederivs
function by the solver. The solver is initialized by the initializer, e.g.N
in theodec
function below that callsodeparms
with the number of parameters.The number of external outputs
*ip
is initialized from R by thenout
argument:Here a C example using
yout
. The full source code of the example can be found in filesodec.c
andodedll.R
on R-Forge.