[R-sig-dyn-mod] lsodes with jacobian
Daniel Kaschek
daniel.kaschek at physik.uni-freiburg.de
Mon Jul 7 16:38:12 CEST 2014
Hi Karline,
On Mo, 2014-07-07 at 08:09 +0000, Karline Soetaert wrote:
> Hello Daniel,
>
> Sorry for answering this late; I was at the useR conference.
I am glad that you respond :-)
>
> I think specifiying inz is enough. You have to set sparsetype =
> "sparsejan", and then specify the vector inz such that it has the
> necessary information about where to find the nonzero elements in the
> jacobian. It is to contain two vectors in the original FORTRAN code of
> lsodes: ian and jan. How to do this is explained in the "details"
> section of lsodes ( use ?lsodes).
I had a look at the documentation of sparsetype="sparsejan". I don't
understand why "ian" should have n+1 elements. Let's assume the jacobian
matrix
0 1 0
0 0 1
1 1 1
Then, I have
jan = c(3, 1, 3, 2, 3) #third element in column 1, first and third
element in column 2, ...
ian = c(1, 2, 4) #column1 starts at element 1 of jan, column2 starts at
element 2 of jan, column3 starts at element 4 of jan.
In case, I did not understand the documentation correctly. Could you
tell me "jan" and "ian" for the above example?
>
> As your model with the explicit jacobian runs longer than in the other
> case, this probably means that the jacobian itself is not correctly
> specified.
> One way to see this is to ask for the diagnostics of both runs. This
> will tell you the number of steps it took; it should be comparable.
I tried to run my exmample with verbose=TRUE. However, when specifying
jacvec, I get the following error:
--------------------
Integration method
--------------------
Error in cat(message, "\n") : object 'txt' not found
>
> For large problems, the explicit specification should be faster.
I have one more question about the correct arguments of jacvec in the C
code. In the fortran code (odepack.f from
http://people.sc.fsu.edu/~jburkardt/f77_src/odepack/odepack.f) I find
the specifications
SUBROUTINE JAC (NEQ, T, Y, J, IAN, JAN, PDJ)
DOUBLE PRECISION T, Y(*), IAN(*), JAN(*), PDJ(*)
In contrast, in the deSolve package in the file "call_lsoda.c", I find
static void C_jac_vec (int *neq, double *t, double *y, int *j,
int *ian, int *jan, double *pdj, double *yout, int *iout)
My point is, that IAN and JAN are double in fortran and integers in C.
Is this a contradiction?
Sorry for so many questions.
Best regards,
Daniel
>
> Hope this helps,
>
>
> Karline
>
> -----Original Message-----
> From: r-sig-dynamic-models-bounces at r-project.org [mailto:r-sig-dynamic-models-bounces at r-project.org] On Behalf Of Daniel Kaschek
> Sent: zaterdag 28 juni 2014 16:31
> To: r-sig-dynamic-models at r-project.org
> Subject: [R-sig-dyn-mod] lsodes with jacobian
>
> Hi again,
>
> by looking at call_losda.c in the source code of the deSolve package, I found the necessary call. You can find my fist example at the end of the mail.
>
> Next, I tried this out for an ODE with 600 equations. Unfortunately, it takes 60 times longer with jacobian than without :-( I suppose, this has to do with the sparsity specifications. Or is it the "if"-lines in the jacobian?
>
> * What would be the correct specification of sparsetype, nnz and inz in case of an explicitly given jacvec function?
> * Knowing the zeros of my jacobian, does it make sens to write down the jacvec function explicitly or is it sufficient to specify nnz and inz?
>
> Cheers,
> Daniel
>
> #include <R.h>
> #include <math.h>
>
> static double parms[6];
> static double forc[2];
>
> #define rGrow parms[0]
> #define K parms[1]
> #define rIng parms[2]
> #define rMort parms[3]
> #define y0_0 parms[4]
> #define y1_0 parms[5]
> #define assEff forc[0]
> #define assEffDot forc[1]
>
> void initmod(void (* odeparms)(int *, double *)) {
> int N=6;
> odeparms(&N, parms);
> }
>
> void initforc(void (* odeforcs)(int *, double *)) {
> int N=2;
> odeforcs(&N, forc);
> }
>
> /** Derivatives (ODE system) **/
> void derivs (int *n, double *t, double *y, double *ydot, double *RPAR, int *IPAR) {
>
>
> ydot[0] = rGrow*y[0]*(1-y[0]/K)-rIng*y[0]*y[1];
> ydot[1] = rIng*y[0]*y[1]*assEff-rMort*y[1];
>
> }
>
> /** Jacobian vector of the ODE system **/ void jacvec (int *neq, double *t, double *y, int *j, int *ian, int *jan, double *pdj, double *yout, int *iout) {
>
> int i;
> for(i=0; i<*neq; i++) pdj[i] = 0.;
> if(*j == 0 ) {
> pdj[0] = rGrow*(1-y[0]/K)-rGrow*y[0]*(1/K)-rIng*y[1];
> pdj[1] = rIng*y[1]*assEff;
> }
> else if(*j == 1 ) {
> pdj[0] = -(rIng*y[0]);
> pdj[1] = rIng*y[0]*assEff-rMort;
> }
>
> }
>
> _______________________________________________
> R-sig-dynamic-models mailing list
> R-sig-dynamic-models at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-dynamic-models
>
> _______________________________________________
> R-sig-dynamic-models mailing list
> R-sig-dynamic-models at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-dynamic-models
--
Daniel Kaschek
Institute of Physics, Freiburg
Office: 210
Phone: +49-761-203-8531
More information about the R-sig-dynamic-models
mailing list