]> henry.ined.fr Git - .git/commitdiff
Summary: looking at better estimation of the hessian
authorN. Brouard <brouard@ined.fr>
Wed, 30 Sep 2015 17:45:14 +0000 (17:45 +0000)
committerN. Brouard <brouard@ined.fr>
Wed, 30 Sep 2015 17:45:14 +0000 (17:45 +0000)
Also a better criteria for convergence to the period prevalence And
therefore adding the number of years needed to converge. (The
prevalence in any alive state shold sum to one

src/imach.c

index a356e1464f3a32c800114c84d7f8607331416ad6..67f5fe3f03e68e509b157f7cc02a6d70d84b30c4 100644 (file)
@@ -1,6 +1,9 @@
 /* $Id$
   $State$
   $Log$
+  Revision 1.202  2015/09/22 19:45:16  brouard
+  Summary: Adding some overall graph on contribution to likelihood. Might change
+
   Revision 1.201  2015/09/15 17:34:58  brouard
   Summary: 0.98r0
 
 
 /* #define DEBUG */
 /* #define DEBUGBRENT */
-#define DEBUGLINMIN
+/* #define DEBUGLINMIN */
+/* #define DEBUGHESS */
+#define DEBUGHESSIJ
+/* #define LINMINORIGINAL  /\* Don't use loop on scale in linmin (accepting nan)*\/ */
 #define POWELL /* Instead of NLOPT */
 #define POWELLF1F3 /* Skip test */
 /* #define POWELLORIGINAL /\* Don't use Directest to decide new direction but original Powell test *\/ */
@@ -1599,8 +1605,11 @@ void linmin(double p[], double xi[], int n, double *fret,double (*func)(double [
   double xx,xmin,bx,ax; 
   double fx,fb,fa;
 
-  double scale=10., axs, xxs, xxss; /* Scale added for infinity */
+#ifdef LINMINORIGINAL
+#else
+  double scale=10., axs, xxs; /* Scale added for infinity */
+#endif
+  
   ncom=n; 
   pcom=vector(1,n); 
   xicom=vector(1,n); 
@@ -1610,12 +1619,15 @@ void linmin(double p[], double xi[], int n, double *fret,double (*func)(double [
     xicom[j]=xi[j]; /* Former scale xi[j] of currrent direction i */
   } 
 
-  /* axs=0.0; */
-  /* xxss=1; /\* 1 and using scale *\/ */
-  xxs=1;
-  /* do{ */
-    ax=0.;
+#ifdef LINMINORIGINAL
+  xx=1.;
+#else
+  axs=0.0;
+  xxs=1.;
+  do{
     xx= xxs;
+#endif
+    ax=0.;
     mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,f1dim);  /* Outputs: xtx[j]=pcom[j]+(*xx)*xicom[j]; fx=f(xtx[j]) */
     /* brackets with inputs ax=0 and xx=1, but points, pcom=p, and directions values, xicom=xi, are sent via f1dim(x) */
     /* xt[x,j]=pcom[j]+x*xicom[j]  f(ax) = f(xt(a,j=1,n)) = f(p(j) + 0 * xi(j)) and  f(xx) = f(xt(x, j=1,n)) = f(p(j) + 1 * xi(j))   */
@@ -1623,12 +1635,19 @@ void linmin(double p[], double xi[], int n, double *fret,double (*func)(double [
     /* Given input ax=axs and xx=xxs, xx might be too far from ax to get a finite f(xx) */
     /* Searches on line, outputs (ax, xx, bx) such that fx < min(fa and fb) */
     /* Find a bracket a,x,b in direction n=xi ie xicom, order may change. Scale is [0:xxs*xi[j]] et non plus  [0:xi[j]]*/
-  /*   if (fx != fx){ */
-  /*   xxs=xxs/scale; /\* Trying a smaller xx, closer to initial ax=0 *\/ */
-  /*   printf("\nLinmin NAN : input [axs=%lf:xxs=%lf], mnbrak outputs fx=%lf <(fb=%lf and fa=%lf) with xx=%lf in [ax=%lf:bx=%lf] \n",  axs, xxs, fx,fb, fa, xx, ax, bx); */
-  /*   } */
-  /* }while(fx != fx); */
-
+#ifdef LINMINORIGINAL
+#else
+    if (fx != fx){
+       xxs=xxs/scale; /* Trying a smaller xx, closer to initial ax=0 */
+       printf("|");
+       fprintf(ficlog,"|");
+#ifdef DEBUGLINMIN
+       printf("\nLinmin NAN : input [axs=%lf:xxs=%lf], mnbrak outputs fx=%lf <(fb=%lf and fa=%lf) with xx=%lf in [ax=%lf:bx=%lf] \n",  axs, xxs, fx,fb, fa, xx, ax, bx);
+#endif
+    }
+  }while(fx != fx);
+#endif
+  
 #ifdef DEBUGLINMIN
   printf("\nLinmin after mnbrak: ax=%12.7f xx=%12.7f bx=%12.7f fa=%12.2f fx=%12.2f fb=%12.2f\n",  ax,xx,bx,fa,fx,fb);
   fprintf(ficlog,"\nLinmin after mnbrak: ax=%12.7f xx=%12.7f bx=%12.7f fa=%12.2f fx=%12.2f fb=%12.2f\n",  ax,xx,bx,fa,fx,fb);
@@ -1647,14 +1666,23 @@ void linmin(double p[], double xi[], int n, double *fret,double (*func)(double [
   fprintf(ficlog,"linmin end ");
 #endif
   for (j=1;j<=n;j++) { 
-    /* printf(" before xi[%d]=%12.8f", j,xi[j]); */
-    xi[j] *= xmin; /* xi rescaled by xmin: if xmin=-1.237 and xi=(1,0,...,0) xi=(-1.237,0,...,0) */
-    /* if(xxs <1.0) */
-    /*   printf(" after xi[%d]=%12.8f, xmin=%12.8f, ax=%12.8f, xx=%12.8f, bx=%12.8f, xxs=%12.8f", j,xi[j], xmin, ax, xx, bx,xxs ); */
+#ifdef LINMINORIGINAL
+    xi[j] *= xmin; 
+#else
+#ifdef DEBUGLINMIN
+    if(xxs <1.0)
+      printf(" before xi[%d]=%12.8f", j,xi[j]);
+#endif
+    xi[j] *= xmin*xxs; /* xi rescaled by xmin and number of loops: if xmin=-1.237 and xi=(1,0,...,0) xi=(-1.237,0,...,0) */
+#ifdef DEBUGLINMIN
+    if(xxs <1.0)
+      printf(" after xi[%d]=%12.8f, xmin=%12.8f, ax=%12.8f, xx=%12.8f, bx=%12.8f, xxs=%12.8f", j,xi[j], xmin, ax, xx, bx,xxs );
+#endif
+#endif
     p[j] += xi[j]; /* Parameters values are updated accordingly */
   } 
-  /* printf("\n"); */
 #ifdef DEBUGLINMIN
+  printf("\n");
   printf("Comparing last *frec(xmin=%12.8f)=%12.8f from Brent and frec(0.)=%12.8f \n", xmin, *fret, (*func)(p));
   fprintf(ficlog,"Comparing last *frec(xmin=%12.8f)=%12.8f from Brent and frec(0.)=%12.8f \n", xmin, *fret, (*func)(p));
   for (j=1;j<=n;j++) { 
@@ -1665,6 +1693,7 @@ void linmin(double p[], double xi[], int n, double *fret,double (*func)(double [
       fprintf(ficlog,"\n");
     }
   }
+#else
 #endif
   free_vector(xicom,1,n); 
   free_vector(pcom,1,n); 
@@ -1742,10 +1771,10 @@ void powell(double p[], double **xi, int n, double ftol, int *iter, double *fret
       for (j=1;j<=n;j++) xit[j]=xi[j][i]; /* Directions stored from previous iteration with previous scales */
       fptt=(*fret); 
 #ifdef DEBUG
-         printf("fret=%lf, %lf, %lf \n", *fret, *fret, *fret);
-         fprintf(ficlog, "fret=%lf, %lf, %lf \n", *fret, *fret, *fret);
+      printf("fret=%lf, %lf, %lf \n", *fret, *fret, *fret);
+      fprintf(ficlog, "fret=%lf, %lf, %lf \n", *fret, *fret, *fret);
 #endif
-         printf("%d",i);fflush(stdout); /* print direction (parameter) i */
+      printf("%d",i);fflush(stdout); /* print direction (parameter) i */
       fprintf(ficlog,"%d",i);fflush(ficlog);
       linmin(p,xit,n,fret,func); /* Point p[n]. xit[n] has been loaded for direction i as input.*/
                                    /* Outputs are fret(new point p) p is updated and xit rescaled */
@@ -1914,10 +1943,10 @@ void powell(double p[], double **xi, int n, double ftol, int *iter, double *fret
 
 /**** Prevalence limit (stable or period prevalence)  ****************/
 
-double **prevalim(double **prlim, int nlstate, double x[], double age, double **oldm, double **savm, double ftolpl, int ij)
+double **prevalim(double **prlim, int nlstate, double x[], double age, double **oldm, double **savm, double ftolpl, int *ncvyear, int ij)
 {
   /* Computes the prevalence limit in each live state at age x by left multiplying the unit
-     matrix by transitions matrix until convergence is reached */
+     matrix by transitions matrix until convergence is reached with precision ftolpl */
   
   int i, ii,j,k;
   double min, max, maxmin, maxmax,sumnew=0.;
@@ -1925,7 +1954,7 @@ double **prevalim(double **prlim, int nlstate, double x[], double age, double **
   double **out, cov[NCOVMAX+1], **pmij();
   double **newm;
   double agefin, delaymax=100 ; /* Max number of years to converge */
-  long int ncvyear=0, ncvloop=0;
+  int ncvloop=0;
   
   for (ii=1;ii<=nlstate+ndeath;ii++)
     for (j=1;j<=nlstate+ndeath;j++){
@@ -1976,17 +2005,19 @@ double **prevalim(double **prlim, int nlstate, double x[], double age, double **
        min=FMIN(min,prlim[i][j]);
         /* printf(" age= %d prevalim i=%d, j=%d, prmlim[%d][%d]=%f, agefin=%d max=%f min=%f\n", (int)age, i, j, i, j, prlim[i][j],(int)agefin, max, min); */
       }
-      maxmin=max-min;
+      maxmin=(max-min)/(max+min)*2;
       maxmax=FMAX(maxmax,maxmin);
     } /* j loop */
+    *ncvyear= (int)age- (int)agefin;
+    /* printf("maxmax=%lf maxmin=%lf ncvloop=%ld, age=%d, agefin=%d ncvyear=%d \n", maxmax, maxmin, ncvloop, (int)age, (int)agefin, *ncvyear); */
     if(maxmax < ftolpl){
-      /* printf("maxmax=%lf maxmin=%lf ncvloop=%ld, ncvyear=%d \n", maxmax, maxmin, ncvloop, (int)age-(int)agefin); */
+      /* printf("maxmax=%lf maxmin=%lf ncvloop=%ld, age=%d, agefin=%d ncvyear=%d \n", maxmax, maxmin, ncvloop, (int)age, (int)agefin, *ncvyear); */
       return prlim;
     }
   } /* age loop */
-  printf("Warning: the stable prevalence did not converge with the required precision ftolpl=6*10^5*ftol=%g. \n\
-Earliest age to start was %d-%d=%d, ncvloop=%ld, ncvyear=%d\n\
-Try to lower 'ftol', for example from 1.e-8 to 6.e-9.\n", ftolpl, (int)age, (int)delaymax, (int)agefin, ncvloop, (int)age-(int)agefin);
+  printf("Warning: the stable prevalence at age %d did not converge with the required precision %g > ftolpl=%g. \n\
+Earliest age to start was %d-%d=%d, ncvloop=%d, ncvyear=%d\n", (int)age, maxmax, ftolpl, (int)age, (int)delaymax, (int)agefin, ncvloop, *ncvyear);
+/* Try to lower 'ftol', for example from 1.e-8 to 6.e-9.\n", ftolpl, (int)age, (int)delaymax, (int)agefin, ncvloop, (int)age-(int)agefin); */
   return prlim; /* should not reach here */
 }
 
@@ -2691,32 +2722,32 @@ void mlikeli(FILE *ficres,double p[], int npar, int ncovmodel, int nlstate, doub
 #endif
   free_matrix(xi,1,npar,1,npar);
   fclose(ficrespow);
-  printf("#Number of iterations & function calls = %d & %d, -2 Log likelihood = %.12f\n",iter, countcallfunc,func(p));
-  fprintf(ficlog,"#Number of iterations & function calls = %d & %d, -2 Log likelihood = %.12f\n",iter, countcallfunc,func(p));
+  printf("\n#Number of iterations & function calls = %d & %d, -2 Log likelihood = %.12f\n",iter, countcallfunc,func(p));
+  fprintf(ficlog,"\n#Number of iterations & function calls = %d & %d, -2 Log likelihood = %.12f\n",iter, countcallfunc,func(p));
   fprintf(ficres,"#Number of iterations & function calls = %d & %d, -2 Log likelihood = %.12f\n",iter, countcallfunc,func(p));
 
 }
 
 /**** Computes Hessian and covariance matrix ***/
-void hesscov(double **matcov, double p[], int npar, double delti[], double ftolhess, double (*func)(double []))
+void hesscov(double **matcov, double **hess, double p[], int npar, double delti[], double ftolhess, double (*func)(double []))
 {
   double  **a,**y,*x,pd;
-  double **hess;
+  /* double **hess; */
   int i, j;
   int *indx;
 
   double hessii(double p[], double delta, int theta, double delti[],double (*func)(double []),int npar);
-  double hessij(double p[], double delti[], int i, int j,double (*func)(double []),int npar);
+  double hessij(double p[], double **hess, double delti[], int i, int j,double (*func)(double []),int npar);
   void lubksb(double **a, int npar, int *indx, double b[]) ;
   void ludcmp(double **a, int npar, int *indx, double *d) ;
   double gompertz(double p[]);
-  hess=matrix(1,npar,1,npar);
+  /* hess=matrix(1,npar,1,npar); */
 
   printf("\nCalculation of the hessian matrix. Wait...\n");
   fprintf(ficlog,"\nCalculation of the hessian matrix. Wait...\n");
   for (i=1;i<=npar;i++){
-    printf("%d",i);fflush(stdout);
-    fprintf(ficlog,"%d",i);fflush(ficlog);
+    printf("%d-",i);fflush(stdout);
+    fprintf(ficlog,"%d-",i);fflush(ficlog);
    
      hess[i][i]=hessii(p,ftolhess,i,delti,func,npar);
     
@@ -2727,9 +2758,9 @@ void hesscov(double **matcov, double p[], int npar, double delti[], double ftolh
   for (i=1;i<=npar;i++) {
     for (j=1;j<=npar;j++)  {
       if (j>i) { 
-       printf(".%d%d",i,j);fflush(stdout);
-       fprintf(ficlog,".%d%d",i,j);fflush(ficlog);
-       hess[i][j]=hessij(p,delti,i,j,func,npar);
+       printf(".%d-%d",i,j);fflush(stdout);
+       fprintf(ficlog,".%d-%d",i,j);fflush(ficlog);
+       hess[i][j]=hessij(p,hess, delti,i,j,func,npar);
        
        hess[j][i]=hess[i][j];    
        /*printf(" %lf ",hess[i][j]);*/
@@ -2763,53 +2794,78 @@ void hesscov(double **matcov, double p[], int npar, double delti[], double ftolh
   fprintf(ficlog,"\n#Hessian matrix#\n");
   for (i=1;i<=npar;i++) { 
     for (j=1;j<=npar;j++) { 
-      printf("%.3e ",hess[i][j]);
-      fprintf(ficlog,"%.3e ",hess[i][j]);
+      printf("%.6e ",hess[i][j]);
+      fprintf(ficlog,"%.6e ",hess[i][j]);
     }
     printf("\n");
     fprintf(ficlog,"\n");
   }
 
+  /* printf("\n#Covariance matrix#\n"); */
+  /* fprintf(ficlog,"\n#Covariance matrix#\n"); */
+  /* for (i=1;i<=npar;i++) {  */
+  /*   for (j=1;j<=npar;j++) {  */
+  /*     printf("%.6e ",matcov[i][j]); */
+  /*     fprintf(ficlog,"%.6e ",matcov[i][j]); */
+  /*   } */
+  /*   printf("\n"); */
+  /*   fprintf(ficlog,"\n"); */
+  /* } */
+
   /* Recompute Inverse */
-  for (i=1;i<=npar;i++)
-    for (j=1;j<=npar;j++) a[i][j]=matcov[i][j];
-  ludcmp(a,npar,indx,&pd);
+  /* for (i=1;i<=npar;i++) */
+  /*   for (j=1;j<=npar;j++) a[i][j]=matcov[i][j]; */
+  /* ludcmp(a,npar,indx,&pd); */
+
+  /*  printf("\n#Hessian matrix recomputed#\n"); */
+
+  /* for (j=1;j<=npar;j++) { */
+  /*   for (i=1;i<=npar;i++) x[i]=0; */
+  /*   x[j]=1; */
+  /*   lubksb(a,npar,indx,x); */
+  /*   for (i=1;i<=npar;i++){  */
+  /*     y[i][j]=x[i]; */
+  /*     printf("%.3e ",y[i][j]); */
+  /*     fprintf(ficlog,"%.3e ",y[i][j]); */
+  /*   } */
+  /*   printf("\n"); */
+  /*   fprintf(ficlog,"\n"); */
+  /* } */
+
+  /* Verifying the inverse matrix */
+#ifdef DEBUGHESS
+  y=matprod2(y,hess,1,npar,1,npar,1,npar,matcov);
 
-  /*  printf("\n#Hessian matrix recomputed#\n");
+   printf("\n#Verification: multiplying the matrix of covariance by the Hessian matrix, should be unity:#\n");
+   fprintf(ficlog,"\n#Verification: multiplying the matrix of covariance by the Hessian matrix. Should be unity:#\n");
 
   for (j=1;j<=npar;j++) {
-    for (i=1;i<=npar;i++) x[i]=0;
-    x[j]=1;
-    lubksb(a,npar,indx,x);
     for (i=1;i<=npar;i++){ 
-      y[i][j]=x[i];
-      printf("%.3e ",y[i][j]);
-      fprintf(ficlog,"%.3e ",y[i][j]);
+      printf("%.2f ",y[i][j]);
+      fprintf(ficlog,"%.2f ",y[i][j]);
     }
     printf("\n");
     fprintf(ficlog,"\n");
   }
-  */
+#endif
 
   free_matrix(a,1,npar,1,npar);
   free_matrix(y,1,npar,1,npar);
   free_vector(x,1,npar);
   free_ivector(indx,1,npar);
-  free_matrix(hess,1,npar,1,npar);
+  /* free_matrix(hess,1,npar,1,npar); */
 
 
 }
 
 /*************** hessian matrix ****************/
 double hessii(double x[], double delta, int theta, double delti[], double (*func)(double []), int npar)
-{
+{ /* Around values of x, computes the function func and returns the scales delti and hessian */
   int i;
   int l=1, lmax=20;
-  double k1,k2;
+  double k1,k2, res, fx;
   double p2[MAXPARM+1]; /* identical to x */
-  double res;
   double delt=0.0001, delts, nkhi=10.,nkhif=1., khi=1.e-4;
-  double fx;
   int k=0,kmax=10;
   double l1;
 
@@ -2825,9 +2881,9 @@ double hessii(double x[], double delta, int theta, double delti[], double (*func
       p2[theta]=x[theta]-delt;
       k2=func(p2)-fx;
       /*res= (k1-2.0*fx+k2)/delt/delt; */
-      res= (k1+k2)/delt/delt/2.; /* Divided by because L and not 2*L */
+      res= (k1+k2)/delt/delt/2.; /* Divided by because L and not 2*L */
       
-#ifdef DEBUGHESS
+#ifdef DEBUGHESSII
       printf("%d %d k1=%.12e k2=%.12e xk1=%.12e xk2=%.12e delt=%.12e res=%.12e l=%d k=%d,fx=%.12e\n",theta,theta,k1,k2,x[theta]+delt,x[theta]-delt,delt,res, l, k,fx);
       fprintf(ficlog,"%d %d k1=%.12e k2=%.12e xk1=%.12e xk2=%.12e delt=%.12e res=%.12e l=%d k=%d,fx=%.12e\n",theta,theta,k1,k2,x[theta]+delt,x[theta]-delt,delt,res, l, k,fx);
 #endif
@@ -2841,48 +2897,122 @@ double hessii(double x[], double delta, int theta, double delti[], double (*func
       else if((k1 >khi/nkhi) || (k2 >khi/nkhi)){ 
        delts=delt;
       }
-    }
+    } /* End loop k */
   }
   delti[theta]=delts;
   return res; 
   
 }
 
-double hessij( double x[], double delti[], int thetai,int thetaj,double (*func)(double []),int npar)
+double hessij( double x[], double **hess, double delti[], int thetai,int thetaj,double (*func)(double []),int npar)
 {
   int i;
   int l=1, lmax=20;
   double k1,k2,k3,k4,res,fx;
   double p2[MAXPARM+1];
-  int k;
-
+  int k, kmax=1;
+  double v1, v2, cv12, lc1, lc2;
+  
   fx=func(x);
-  for (k=1; k<=2; k++) {
+  for (k=1; k<=kmax; k=k+10) {
     for (i=1;i<=npar;i++) p2[i]=x[i];
-    p2[thetai]=x[thetai]+delti[thetai]/k;
-    p2[thetaj]=x[thetaj]+delti[thetaj]/k;
+    p2[thetai]=x[thetai]+delti[thetai]*k;
+    p2[thetaj]=x[thetaj]+delti[thetaj]*k;
     k1=func(p2)-fx;
   
-    p2[thetai]=x[thetai]+delti[thetai]/k;
-    p2[thetaj]=x[thetaj]-delti[thetaj]/k;
+    p2[thetai]=x[thetai]+delti[thetai]*k;
+    p2[thetaj]=x[thetaj]-delti[thetaj]*k;
     k2=func(p2)-fx;
   
-    p2[thetai]=x[thetai]-delti[thetai]/k;
-    p2[thetaj]=x[thetaj]+delti[thetaj]/k;
+    p2[thetai]=x[thetai]-delti[thetai]*k;
+    p2[thetaj]=x[thetaj]+delti[thetaj]*k;
     k3=func(p2)-fx;
   
-    p2[thetai]=x[thetai]-delti[thetai]/k;
-    p2[thetaj]=x[thetaj]-delti[thetaj]/k;
+    p2[thetai]=x[thetai]-delti[thetai]*k;
+    p2[thetaj]=x[thetaj]-delti[thetaj]*k;
     k4=func(p2)-fx;
-    res=(k1-k2-k3+k4)/4.0/delti[thetai]*k/delti[thetaj]*k/2.; /* Because of L not 2*L */
-#ifdef DEBUG
-    printf("%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
-    fprintf(ficlog,"%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
+    res=(k1-k2-k3+k4)/4.0/delti[thetai]/k/delti[thetaj]/k/2.; /* Because of L not 2*L */
+    if(k1*k2*k3*k4 <0.){
+      kmax=kmax+10;
+      if(kmax >=10){
+      printf("Warning: directions %d-%d, you are not estimating the Hessian at the exact maximum likelihood; increase ftol=%.2e\n",thetai,thetaj, ftol);
+      fprintf(ficlog,"Warning: directions %d-%d, you are not estimating the Hessian at the exact maximum likelihood; increase ftol=%.2e\n",thetai,thetaj, ftol);
+      printf("%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti*k=%.12e deltj*k=%.12e, xi-de*k=%.12e xj-de*k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
+      fprintf(ficlog,"%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti*k=%.12e deltj*k=%.12e, xi-de*k=%.12e xj-de*k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
+      }
+    }
+#ifdef DEBUGHESSIJ
+    v1=hess[thetai][thetai];
+    v2=hess[thetaj][thetaj];
+    cv12=res;
+    /* Computing eigen value of Hessian matrix */
+    lc1=((v1+v2)+sqrt((v1+v2)*(v1+v2) - 4*(v1*v2-cv12*cv12)))/2.;
+    lc2=((v1+v2)-sqrt((v1+v2)*(v1+v2) - 4*(v1*v2-cv12*cv12)))/2.;
+    if ((lc2 <0) || (lc1 <0) ){
+      printf("Warning: sub Hessian matrix '%d%d' does not have positive eigen values \n",thetai,thetaj);
+      fprintf(ficlog, "Warning: sub Hessian matrix '%d%d' does not have positive eigen values \n",thetai,thetaj);
+      printf("%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
+      fprintf(ficlog,"%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4);
+    }
 #endif
   }
   return res;
 }
 
+    /* Not done yet: Was supposed to fix if not exactly at the maximum */
+/* double hessij( double x[], double delti[], int thetai,int thetaj,double (*func)(double []),int npar) */
+/* { */
+/*   int i; */
+/*   int l=1, lmax=20; */
+/*   double k1,k2,k3,k4,res,fx; */
+/*   double p2[MAXPARM+1]; */
+/*   double delt=0.0001, delts, nkhi=10.,nkhif=1., khi=1.e-4; */
+/*   int k=0,kmax=10; */
+/*   double l1; */
+  
+/*   fx=func(x); */
+/*   for(l=0 ; l <=lmax; l++){  /\* Enlarging the zone around the Maximum *\/ */
+/*     l1=pow(10,l); */
+/*     delts=delt; */
+/*     for(k=1 ; k <kmax; k=k+1){ */
+/*       delt = delti*(l1*k); */
+/*       for (i=1;i<=npar;i++) p2[i]=x[i]; */
+/*       p2[thetai]=x[thetai]+delti[thetai]/k; */
+/*       p2[thetaj]=x[thetaj]+delti[thetaj]/k; */
+/*       k1=func(p2)-fx; */
+      
+/*       p2[thetai]=x[thetai]+delti[thetai]/k; */
+/*       p2[thetaj]=x[thetaj]-delti[thetaj]/k; */
+/*       k2=func(p2)-fx; */
+      
+/*       p2[thetai]=x[thetai]-delti[thetai]/k; */
+/*       p2[thetaj]=x[thetaj]+delti[thetaj]/k; */
+/*       k3=func(p2)-fx; */
+      
+/*       p2[thetai]=x[thetai]-delti[thetai]/k; */
+/*       p2[thetaj]=x[thetaj]-delti[thetaj]/k; */
+/*       k4=func(p2)-fx; */
+/*       res=(k1-k2-k3+k4)/4.0/delti[thetai]*k/delti[thetaj]*k/2.; /\* Because of L not 2*L *\/ */
+/* #ifdef DEBUGHESSIJ */
+/*       printf("%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4); */
+/*       fprintf(ficlog,"%d %d k=%d, k1=%.12e k2=%.12e k3=%.12e k4=%.12e delti/k=%.12e deltj/k=%.12e, xi-de/k=%.12e xj-de/k=%.12e  res=%.12e k1234=%.12e,k1-2=%.12e,k3-4=%.12e\n",thetai,thetaj,k,k1,k2,k3,k4,delti[thetai]/k,delti[thetaj]/k,x[thetai]-delti[thetai]/k,x[thetaj]-delti[thetaj]/k, res,k1-k2-k3+k4,k1-k2,k3-k4); */
+/* #endif */
+/*       if((k1 <khi/nkhi/2.) || (k2 <khi/nkhi/2.)|| (k4 <khi/nkhi/2.)|| (k4 <khi/nkhi/2.)){ */
+/*     k=kmax; */
+/*       } */
+/*       else if((k1 >khi/nkhif) || (k2 >khi/nkhif) || (k4 >khi/nkhif) || (k4 >khi/nkhif)){ /\* Keeps lastvalue before 3.84/2 KHI2 5% 1d.f. *\/ */
+/*     k=kmax; l=lmax*10; */
+/*       } */
+/*       else if((k1 >khi/nkhi) || (k2 >khi/nkhi)){  */
+/*     delts=delt; */
+/*       } */
+/*     } /\* End loop k *\/ */
+/*   } */
+/*   delti[theta]=delts; */
+/*   return res;  */
+/* } */
+
+
 /************** Inverse of matrix **************/
 void ludcmp(double **a, int n, int *indx, double *d) 
 { 
@@ -3815,7 +3945,7 @@ void cvevsij(double ***eij, double x[], int nlstate, int stepm, int bage, int fa
 }
 
 /************ Variance ******************/
-void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double x[], double delti[], int nlstate, int stepm, double bage, double fage, double **oldm, double **savm, double **prlim, double ftolpl, int ij, int estepm, int cptcov, int cptcod, int popbased, int mobilav, char strstart[])
+ void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double x[], double delti[], int nlstate, int stepm, double bage, double fage, double **oldm, double **savm, double **prlim, double ftolpl, int *ncvyear, int ij, int estepm, int cptcov, int cptcod, int popbased, int mobilav, char strstart[])
 {
   /* Variance of health expectancies */
   /*  double **prevalim(double **prlim, int nlstate, double *xp, double age, double **oldm, double ** savm,double ftolpl);*/
@@ -3941,7 +4071,7 @@ void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double
        xp[i] = x[i] + (i==theta ?delti[theta]:0);
       }
       hpxij(p3mat,nhstepm,age,hstepm,xp,nlstate,stepm,oldm,savm, ij);  
-      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ij);
+      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ncvyear,ij);
 
       if (popbased==1) {
        if(mobilav ==0){
@@ -3972,7 +4102,7 @@ void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double
       for(i=1; i<=npar; i++) /* Computes gradient x - delta */
        xp[i] = x[i] - (i==theta ?delti[theta]:0);
       hpxij(p3mat,nhstepm,age,hstepm,xp,nlstate,stepm,oldm,savm, ij);  
-      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ij);
+      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ncvyear, ij);
  
       if (popbased==1) {
        if(mobilav ==0){
@@ -4047,7 +4177,7 @@ void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double
     /* end ppptj */
     /*  x centered again */
     hpxij(p3mat,nhstepm,age,hstepm,x,nlstate,stepm,oldm,savm, ij);  
-    prevalim(prlim,nlstate,x,age,oldm,savm,ftolpl,ij);
+    prevalim(prlim,nlstate,x,age,oldm,savm,ftolpl,ncvyear,ij);
  
     if (popbased==1) {
       if(mobilav ==0){
@@ -4125,7 +4255,7 @@ void varevsij(char optionfilefiname[], double ***vareij, double **matcov, double
 }  /* end varevsij */
 
 /************ Variance of prevlim ******************/
-void varprevlim(char fileres[], double **varpl, double **matcov, double x[], double delti[], int nlstate, int stepm, double bage, double fage, double **oldm, double **savm, double **prlim, double ftolpl, int ij, char strstart[])
+ void varprevlim(char fileres[], double **varpl, double **matcov, double x[], double delti[], int nlstate, int stepm, double bage, double fage, double **oldm, double **savm, double **prlim, double ftolpl, int *ncvyear, int ij, char strstart[])
 {
   /* Variance of prevalence limit */
   /*  double **prevalim(double **prlim, int nlstate, double *xp, double age, double **oldm, double **savm,double ftolpl);*/
@@ -4164,13 +4294,13 @@ void varprevlim(char fileres[], double **varpl, double **matcov, double x[], dou
       for(i=1; i<=npar; i++){ /* Computes gradient */
        xp[i] = x[i] + (i==theta ?delti[theta]:0);
       }
-      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ij);
+      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ncvyear,ij);
       for(i=1;i<=nlstate;i++)
        gp[i] = prlim[i][i];
     
       for(i=1; i<=npar; i++) /* Computes gradient */
        xp[i] = x[i] - (i==theta ?delti[theta]:0);
-      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ij);
+      prevalim(prlim,nlstate,xp,age,oldm,savm,ftolpl,ncvyear,ij);
       for(i=1;i<=nlstate;i++)
        gm[i] = prlim[i][i];
 
@@ -4628,7 +4758,7 @@ divided by h: hPij/h : <a href=\"%s_%d-3.svg\">%s_%d-3.svg</a><br> \
  fprintf(fichtm,"\
 \n<br><li><h4> <a name='secondorder'>Result files (second order: variances)</a></h4>\n\
  - Parameter file with estimated parameters and covariance matrix: <a href=\"%s\">%s</a> <br> \
- - 95%% confidence intervals and Wald tests of the estimated parameters are in the log file.<br> \
+ - 95%% confidence intervals and Wald tests of the estimated parameters are in the log file if optimization has been done (mle != 0).<br> \
 But because parameters are usually highly correlated (a higher incidence of disability \
 and a higher incidence of recovery can give very close observed transition) it might \
 be very useful to look not only at linear confidence intervals estimated from the \
@@ -4733,7 +4863,7 @@ void printinggnuplot(char fileresu[], char optionfilefiname[], double ageminpar,
     fprintf(ficgp,"\nset out \"%s.png\";",subdirf2(optionfilefiname,"ILK_"));
     fprintf(ficgp,"\nplot  \"%s\" u 2:(-$11):3 t \"All sample, all transitions\" with dots lc variable",subdirf(fileresilk));
     fprintf(ficgp,"\nreplot  \"%s\" u 2:($3 <= 3 ? -$11 : 1/0):3 t \"First 3 individuals\" with line lc variable", subdirf(fileresilk));
-    fprintf(ficgp,"\nset out\n");
+    fprintf(ficgp,"\nset out;unset log\n");
     /* fprintf(ficgp,"\nset out \"%s.svg\"; replot; set out; # bug gnuplot",subdirf2(optionfilefiname,"ILK_")); */
 
   strcpy(dirfileres,optionfilefiname);
@@ -6314,11 +6444,12 @@ void syscompilerinfo(int logged)
 
  }
 
- int prevalence_limit(double *p, double **prlim, double ageminpar, double agemaxpar, double ftolpl){
+ int prevalence_limit(double *p, double **prlim, double ageminpar, double agemaxpar, double ftolpl, int *ncvyear){
   /*--------------- Prevalence limit  (period or stable prevalence) --------------*/
   int i, j, k, i1 ;
   /* double ftolpl = 1.e-10; */
   double age, agebase, agelim;
+  double tot;
 
   strcpy(filerespl,"PL_");
   strcat(filerespl,fileresu);
@@ -6329,7 +6460,7 @@ void syscompilerinfo(int logged)
   printf("Computing period (stable) prevalence: result on file '%s' \n", filerespl);
   fprintf(ficlog,"Computing period (stable) prevalence: result on file '%s' \n", filerespl);
   pstamp(ficrespl);
-  fprintf(ficrespl,"# Period (stable) prevalence \n");
+  fprintf(ficrespl,"# Period (stable) prevalence. Precision given by ftolpl=%g \n", ftolpl);
   fprintf(ficrespl,"#Age ");
   for(i=1; i<=nlstate;i++) fprintf(ficrespl,"%d-%d ",i,i);
   fprintf(ficrespl,"\n");
@@ -6364,18 +6495,21 @@ void syscompilerinfo(int logged)
        for(j=1;j<=cptcoveff;j++) {
          fprintf(ficrespl,"V%d %d ",Tvaraff[j],nbcode[Tvaraff[j]][codtabm(k,j)]);
        }
-       for(i=1; i<=nlstate;i++) fprintf(ficrespl,"%d-%d ",i,i);
-       fprintf(ficrespl,"\n");
+       for(i=1; i<=nlstate;i++) fprintf(ficrespl,"  %d-%d   ",i,i);
+       fprintf(ficrespl,"Total Years_to_converge\n");
        
        for (age=agebase; age<=agelim; age++){
        /* for (age=agebase; age<=agebase; age++){ */
-         prevalim(prlim, nlstate, p, age, oldm, savm,ftolpl,k);
+         prevalim(prlim, nlstate, p, age, oldm, savm, ftolpl, ncvyear, k);
          fprintf(ficrespl,"%.0f ",age );
          for(j=1;j<=cptcoveff;j++)
            fprintf(ficrespl,"%d %d ",Tvaraff[j],nbcode[Tvaraff[j]][codtabm(k,j)]);
-         for(i=1; i<=nlstate;i++)
+         tot=0.;
+         for(i=1; i<=nlstate;i++){
+           tot +=  prlim[i][i];
            fprintf(ficrespl," %.5f", prlim[i][i]);
-         fprintf(ficrespl,"\n");
+         }
+         fprintf(ficrespl," %.3f %d\n", tot, *ncvyear);
        } /* Age */
        /* was end of cptcod */
     } /* cptcov */
@@ -6468,7 +6602,8 @@ int main(int argc, char *argv[])
 #endif
   int movingaverage(double ***probs, double bage,double fage, double ***mobaverage, int mobilav);
   int i,j, k, n=MAXN,iter=0,m,size=100, cptcod;
-
+  int ncvyearnp=0;
+  int *ncvyear=&ncvyearnp; /* Number of years needed for the period prevalence to converge */
   int jj, ll, li, lj, lk;
   int numlinepar=0; /* Current linenumber of parameter file */
   int num_filled;
@@ -6516,6 +6651,7 @@ int main(int argc, char *argv[])
   double ***param; /* Matrix of parameters */
   double  *p;
   double **matcov; /* Matrix of covariance */
+  double **hess; /* Hessian matrix */
   double ***delti3; /* Scale */
   double *delti; /* Scale */
   double ***eij, ***vareij;
@@ -6722,7 +6858,8 @@ int main(int argc, char *argv[])
     }
     printf("ftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\n",ftol, stepm, ncovcol, nlstate,ndeath, maxwav, mle, weightopt);
   }
-  ftolpl=6*ftol*1.e5; /* 6.e-3 make convergences in less than 80 loops for the prevalence limit */
+  /* ftolpl=6*ftol*1.e5; /\* 6.e-3 make convergences in less than 80 loops for the prevalence limit *\/ */
+  ftolpl=6.e-3; /* 6.e-3 make convergences in less than 80 loops for the prevalence limit */
   /* Third parameter line */
   while(fgets(line, MAXLINE, ficpar)) {
     /* If line starts with a # it is a comment */
@@ -6752,14 +6889,13 @@ int main(int argc, char *argv[])
       }
     }
     /* printf(" model=1+age%s modeltemp= %s, model=%s\n",model, modeltemp, model);fflush(stdout); */
+    printf("model=1+age+%s\n",model);fflush(stdout);
   }
   /* fscanf(ficpar,"title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%lf stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d model=1+age+%s\n",title, datafile, &lastobs, &firstpass,&lastpass,&ftol, &stepm, &ncovcol, &nlstate,&ndeath, &maxwav, &mle, &weightopt,model); */
   /* numlinepar=numlinepar+3; /\* In general *\/ */
   /* printf("title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\nmodel=1+age+%s\n", title, datafile, lastobs, firstpass,lastpass,ftol, stepm, ncovcol, nlstate,ndeath, maxwav, mle, weightopt,model); */
-  if(model[strlen(model)-1]=='.') /* Suppressing leading dot in the model */
-    model[strlen(model)-1]='\0';
-  fprintf(ficparo,"title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\nmodel=1+age%s.\n", title, datafile, lastobs, firstpass,lastpass,ftol,stepm,ncovcol,nlstate,ndeath,maxwav, mle, weightopt,model);
-  fprintf(ficlog,"title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\nmodel=1+age%s.\n", title, datafile, lastobs, firstpass,lastpass,ftol,stepm,ncovcol,nlstate,ndeath,maxwav, mle, weightopt,model);
+  fprintf(ficparo,"title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\nmodel=1+age+%s.\n", title, datafile, lastobs, firstpass,lastpass,ftol,stepm,ncovcol,nlstate,ndeath,maxwav, mle, weightopt,model);
+  fprintf(ficlog,"title=%s datafile=%s lastobs=%d firstpass=%d lastpass=%d\nftol=%e stepm=%d ncovcol=%d nlstate=%d ndeath=%d maxwav=%d mle=%d weight=%d\nmodel=1+age+%s.\n", title, datafile, lastobs, firstpass,lastpass,ftol,stepm,ncovcol,nlstate,ndeath,maxwav, mle, weightopt,model);
   fflush(ficlog);
   /* if(model[0]=='#'|| model[0]== '\0'){ */
   if(model[0]=='#'){
@@ -6824,6 +6960,7 @@ int main(int argc, char *argv[])
     fprintf(ficlog," You chose mle=-3, look at file %s for a template of covariance matrix \n",filereso);
     param= ma3x(1,nlstate,1,nlstate+ndeath-1,1,ncovmodel);
     matcov=matrix(1,npar,1,npar);
+    hess=matrix(1,npar,1,npar);
   }
   else{
     /* Read guessed parameters */
@@ -6932,6 +7069,7 @@ run imach with mle=-1 to get a correct template of the parameter file.\n",numlin
     ungetc(c,ficpar);
   
     matcov=matrix(1,npar,1,npar);
+    hess=matrix(1,npar,1,npar);
     for(i=1; i <=npar; i++)
       for(j=1; j <=npar; j++) matcov[i][j]=0.;
       
@@ -7399,18 +7537,20 @@ Interval (in months) between two waves: Min=%d Max=%d Mean=%.2lf<br>\n",\
 #endif  
     fclose(ficrespow);
     
-    hesscov(matcov, p, NDIM, delti, 1e-4, gompertz); 
+    hesscov(matcov, hess, p, NDIM, delti, 1e-4, gompertz); 
 
     for(i=1; i <=NDIM; i++)
       for(j=i+1;j<=NDIM;j++)
        matcov[i][j]=matcov[j][i];
     
     printf("\nCovariance matrix\n ");
+    fprintf(ficlog,"\nCovariance matrix\n ");
     for(i=1; i <=NDIM; i++) {
       for(j=1;j<=NDIM;j++){ 
        printf("%f ",matcov[i][j]);
+       fprintf(ficlog,"%f ",matcov[i][j]);
       }
-      printf("\n ");
+      printf("\n ");  fprintf(ficlog,"\n ");
     }
     
     printf("iter=%d MLE=%f Eq=%lf*exp(%lf*(age-%d))\n",iter,-gompertz(p),p[1],p[2],agegomp);
@@ -7473,7 +7613,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
 #endif
   } /* Endof if mle==-3 mortality only */
   /* Standard maximisation */
-  else{ /* For mle >=1 */
+  else{ /* For mle !=- 3 */
     globpr=0;/* debug */
     /* Computes likelihood for initial parameters */
     likelione(ficres, p, npar, nlstate, &globpr, &ipmx, &sw, &fretone, funcone); /* Prints the contributions to the likelihood */
@@ -7516,29 +7656,30 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
        }
       }
     }
-    if(mle!=0){
-      /* Computing hessian and covariance matrix */
+    if(mle != 0){
+      /* Computing hessian and covariance matrix only at a peak of the Likelihood, that is after optimization */
       ftolhess=ftol; /* Usually correct */
-      hesscov(matcov, p, npar, delti, ftolhess, func);
-    }
-    printf("Parameters and 95%% confidence intervals\n W is simply the result of the division of the parameter by the square root of covariance of the parameter.\n And Wald-based confidence intervals plus and minus 1.96 * W .\n But be careful that parameters are highly correlated because incidence of disability is highly correlated to incidence of recovery.\n It might be better to visualize the covariance matrix. See the page 'Matrix of variance-covariance of one-step probabilities' and its graphs.\n");
-    fprintf(ficlog, "Parameters, Wald tests and Wald-based confidence intervals\n W is simply the result of the division of the parameter by the square root of covariance of the parameter.\n And Wald-based confidence intervals plus and minus 1.96 * W \n  It might be better to visualize the covariance matrix. See the page 'Matrix of variance-covariance of one-step probabilities' and its graphs.\n");
-    for(i=1,jk=1; i <=nlstate; i++){
-      for(k=1; k <=(nlstate+ndeath); k++){
-       if (k != i) {
-         printf("%d%d ",i,k);
-         fprintf(ficlog,"%d%d ",i,k);
-         for(j=1; j <=ncovmodel; j++){
-           printf("%12.7f W=%8.3f CI=[%12.7f ; %12.7f] ",p[jk], p[jk]/sqrt(matcov[jk][jk]), p[jk]-1.96*sqrt(matcov[jk][jk]),p[jk]+1.96*sqrt(matcov[jk][jk]));
-           fprintf(ficlog,"%12.7f W=%8.3f CI=[%12.7f ; %12.7f] ",p[jk], p[jk]/sqrt(matcov[jk][jk]), p[jk]-1.96*sqrt(matcov[jk][jk]),p[jk]+1.96*sqrt(matcov[jk][jk]));
-           jk++; 
+      hesscov(matcov, hess, p, npar, delti, ftolhess, func);
+      printf("Parameters and 95%% confidence intervals\n W is simply the result of the division of the parameter by the square root of covariance of the parameter.\n And Wald-based confidence intervals plus and minus 1.96 * W .\n But be careful that parameters are highly correlated because incidence of disability is highly correlated to incidence of recovery.\n It might be better to visualize the covariance matrix. See the page 'Matrix of variance-covariance of one-step probabilities' and its graphs.\n");
+      fprintf(ficlog, "Parameters, Wald tests and Wald-based confidence intervals\n W is simply the result of the division of the parameter by the square root of covariance of the parameter.\n And Wald-based confidence intervals plus and minus 1.96 * W \n  It might be better to visualize the covariance matrix. See the page 'Matrix of variance-covariance of one-step probabilities' and its graphs.\n");
+      for(i=1,jk=1; i <=nlstate; i++){
+       for(k=1; k <=(nlstate+ndeath); k++){
+         if (k != i) {
+           printf("%d%d ",i,k);
+           fprintf(ficlog,"%d%d ",i,k);
+           for(j=1; j <=ncovmodel; j++){
+             printf("%12.7f W=%8.3f CI=[%12.7f ; %12.7f] ",p[jk], p[jk]/sqrt(matcov[jk][jk]), p[jk]-1.96*sqrt(matcov[jk][jk]),p[jk]+1.96*sqrt(matcov[jk][jk]));
+             fprintf(ficlog,"%12.7f W=%8.3f CI=[%12.7f ; %12.7f] ",p[jk], p[jk]/sqrt(matcov[jk][jk]), p[jk]-1.96*sqrt(matcov[jk][jk]),p[jk]+1.96*sqrt(matcov[jk][jk]));
+             jk++; 
+           }
+           printf("\n");
+           fprintf(ficlog,"\n");
          }
-         printf("\n");
-         fprintf(ficlog,"\n");
        }
       }
-    }
+    } /* end of hesscov and Wald tests */
 
+    /*  */
     fprintf(ficres,"# Scales (for hessian or gradient estimation)\n");
     printf("# Scales (for hessian or gradient estimation)\n");
     fprintf(ficlog,"# Scales (for hessian or gradient estimation)\n");
@@ -7562,7 +7703,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
     }
     
     fprintf(ficres,"# Covariance matrix \n# 121 Var(a12)\n# 122 Cov(b12,a12) Var(b12)\n#   ...\n# 232 Cov(b23,a12)  Cov(b23,b12) ... Var (b23)\n");
-    if(mle>=1)
+    if(mle >= 1) /* To big for the screen */
       printf("# Covariance matrix \n# 121 Var(a12)\n# 122 Cov(b12,a12) Var(b12)\n#   ...\n# 232 Cov(b23,a12)  Cov(b23,b12) ... Var (b23)\n");
     fprintf(ficlog,"# Covariance matrix \n# 121 Var(a12)\n# 122 Cov(b12,a12) Var(b12)\n#   ...\n# 232 Cov(b23,a12)  Cov(b23,b12) ... Var (b23)\n");
     /* # 121 Var(a12)\n\ */
@@ -7625,9 +7766,9 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
                        fprintf(ficres," Var(%s%1d%1d)",ca,i,j);
                      }else{
                        if(mle>=1)
-                         printf(" %.5e",matcov[jj][ll]); 
-                       fprintf(ficlog," %.5e",matcov[jj][ll]); 
-                       fprintf(ficres," %.5e",matcov[jj][ll]); 
+                         printf(" %.7e",matcov[jj][ll]); 
+                       fprintf(ficlog," %.7e",matcov[jj][ll]); 
+                       fprintf(ficres," %.7e",matcov[jj][ll]); 
                      }
                    }
                  }
@@ -7755,7 +7896,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
     /*--------------- Prevalence limit  (period or stable prevalence) --------------*/
     /*#include "prevlim.h"*/  /* Use ficrespl, ficlog */
     prlim=matrix(1,nlstate,1,nlstate);
-    prevalence_limit(p, prlim,  ageminpar, agemaxpar, ftolpl);
+    prevalence_limit(p, prlim,  ageminpar, agemaxpar, ftolpl, ncvyear);
     fclose(ficrespl);
 
 #ifdef FREEEXIT2
@@ -7917,7 +8058,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
        for(vpopbased=0; vpopbased <= popbased; vpopbased++){ /* Done for vpopbased=0 and vpopbased=1 if popbased==1*/
          oldm=oldms;savm=savms; /* ZZ Segmentation fault */
          cptcod= 0; /* To be deleted */
-         varevsij(optionfilefiname, vareij, matcov, p, delti, nlstate, stepm, (int) bage, (int) fage, oldm, savm, prlim, ftolpl,k, estepm, cptcov,cptcod,vpopbased,mobilav, strstart); /* cptcod not initialized Intel */
+         varevsij(optionfilefiname, vareij, matcov, p, delti, nlstate, stepm, (int) bage, (int) fage, oldm, savm, prlim, ftolpl, ncvyear, k, estepm, cptcov,cptcod,vpopbased,mobilav, strstart); /* cptcod not initialized Intel */
          fprintf(ficrest,"# Total life expectancy with std error and decomposition into time to be expected in each health state\n#  (weighted average of eij where weights are ");
          if(vpopbased==1)
            fprintf(ficrest,"the age specific prevalence observed (cross-sectionally) in the population i.e cross-sectionally\n in each health state (popbased=1) (mobilav=%d)\n",mobilav);
@@ -7929,7 +8070,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
          /* printf("Which p?\n"); for(i=1;i<=npar;i++)printf("p[i=%d]=%lf,",i,p[i]);printf("\n"); */
          epj=vector(1,nlstate+1);
          for(age=bage; age <=fage ;age++){
-           prevalim(prlim, nlstate, p, age, oldm, savm,ftolpl,k); /*ZZ Is it the correct prevalim */
+           prevalim(prlim, nlstate, p, age, oldm, savm, ftolpl, ncvyear, k); /*ZZ Is it the correct prevalim */
            if (vpopbased==1) {
              if(mobilav ==0){
                for(i=1; i<=nlstate;i++)
@@ -8001,7 +8142,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
       
        varpl=matrix(1,nlstate,(int) bage, (int) fage);
        oldm=oldms;savm=savms;
-       varprevlim(fileres, varpl, matcov, p, delti, nlstate, stepm, (int) bage, (int) fage, oldm, savm, prlim, ftolpl,k,strstart);
+       varprevlim(fileres, varpl, matcov, p, delti, nlstate, stepm, (int) bage, (int) fage, oldm, savm, prlim, ftolpl, ncvyear, k, strstart);
        free_matrix(varpl,1,nlstate,(int) bage, (int)fage);
       /*}*/
     }
@@ -8020,6 +8161,7 @@ Please run with mle=-1 to get a correct covariance matrix.\n",ageminpar,agemaxpa
     free_matrix(savms, 1,nlstate+ndeath,1,nlstate+ndeath);
     free_matrix(covar,0,NCOVMAX,1,n);
     free_matrix(matcov,1,npar,1,npar);
+    free_matrix(hess,1,npar,1,npar);
     /*free_vector(delti,1,npar);*/
     free_ma3x(delti3,1,nlstate,1, nlstate+ndeath-1,1,ncovmodel); 
     free_matrix(agev,1,maxwav,1,imx);