
 
/* SAS Program to optiimize the log likelihood function */

proc iml  worksize=1000 symbolsize=1000;

use DataDionne;

read all var{nb_atot} into y;
print "Dependent Variable: y=number of annual truck accidents per truck";

read all var{an_trans sect_14 sect_05 sect_07 sect_08 
             n_vh1 n_vh3 n_vh45 n_vh69 n_vh20 n_vh50 n_vh51 duree_at 
             nb_inf1 nb_inf2 nb_inf3 nb_inf6 nb_inf7 nb_inf89
             compr tbrgn
             essence carb_aut
             cyl1_5 cyl6_7
             ess_02 ess_02p ess_03 ess_04 ess_05
             vit sanct rouge arret ceinture
             an_91 an_92 an_93 an_94 an_95 an_96 an_97} into x;

 
parm3={'delta' 'bc' 'delta_et' 'b_et' 
       'intercept' 'an_trans' 'sect_14' 'sect_05' 'sect_07' 'sect_08'
       'n_vh1' 'n_vh3' 'n_vh45' 'n_vh69' 'n_vh20' 'n_vh50'  'n_vh51' 'duree_at' 
       'nb_inf1' 'nb_inf2' 'nb_inf3'  'nb_inf6' 'nb_inf7' 'nb_inf89'
       'compr' 'tbrgn'
       'essence' 'carb_aut' 'cyl1_5' 'cyl6_7'
       'ess_02' 'ess_02p' 'ess_03' 'ess_04' 'ess_05'
       'vit' 'sanct' 'rouge' 'arret' 'ceinture' 
       'an_91' 'an_92' 'an_93' 'an_94' 'an_95' 'an_96' 'an_97'};


p=ncol(x)+1;
n=nrow(x);
x=j(n,1)||x;

print n p;

read all var{taille_t} into tt where(flotte=1);
read all var{taille_c} into ttc where(flotte=1);
read all var{n_period} into n_period where(camion=1);

nflotte=nrow(tt);  
print nflotte;
print p;
n_parm=p+4; 
r_beta=j(1,n_parm);

/* Log likelihood function */
start r_llf_v(r_beta) global(nflotte,kz, km, n_parm,y,x,tt, ttc, n_period); 

  delta=r_beta[1,1];    bc_0_1=r_beta[1,2]; 
  delta_et=r_beta[1,3]; b_et=r_beta[1,4];
  par=r_beta[,5:n_parm];
  
   bc=bc_0_1/(1+bc_0_1);
   c_et=(1/(delta_et + (delta*b_et*(bc/(1-bc)))));
 
 nxijt=0;
 r_ll_f=0;
 nij_j=0;
 vec_r_ll_f=j(nflotte,1,0);

  do i=1 to nflotte;
 
  rl=0;

  nijt=tt[i]; /* number of truck-year of the fleet i */
  ijt=(nxijt+1):(nxijt+nijt);
  nxijt=nxijt+nijt; 
  yijt=y[ijt];
  xijt=x[ijt,];
  wijt=xijt*par`;
  lambdaijt=exp(wijt);
  
  term_poisijt=yijt#log(lambdaijt) - lgamma(yijt+1);
  s_term_poisi=term_poisijt[+];
  
  nij=ttc[i]; /* number of truck of fleet i */ 
  nxt=0;
  kmp=km+1;
  Mi=j(kmp,1,0);
  do m = 0 to km;
    log_sMij=j(nij,1,0);
	mp=m+1;
    nxt=0; 
    do j=1 to nij;
     jj=j+nij_j;
	 nt=n_period[jj]; /* number of periods of truck j of fleet i */ 
     jt=(nxt+1):(nxt+nt); 
     nxt=nxt+nt;
     yjt=yijt[jt];
     lambdajt=lambdaijt[jt];
      kzp=kz+1;
      Mij=j(kzp,1,0);
	  do z = 0 to kz;
	    zp=z+1;
	    term1 = lgamma(delta + m + z) - lgamma(delta + m) - lgamma(z+1);
		term2 = z#log(bc) - (delta + m + z)#log(1 + bc);
		term3 = lgamma(delta_et + b_et#z + yjt) - lgamma(delta_et + b_et#z);
		s_term3 = term3[+];
		term4 = yjt#log(c_et) - (delta_et + b_et#z + yjt)#log(1+(c_et#lambdajt));
		s_term4 = term4[+];
		term5 = term1 + term2 + s_term3 + s_term4;
		Mij[zp] = exp(term5);
          end; /* do z = 0 to k; */
    sMij=Mij[+];
    if sMij=0 then log_sMij[j]=log(10##(-300));  else log_sMij[j]=log(sMij); 
    
   end; /*do j = 1 to nij; */  

   term7 = lgamma(delta + m) - lgamma(delta) - lgamma(m+1);
   term8 = m#log(bc) + delta#log(1-bc);
   term10 = term7 + term8 + log_sMij[+];
   Mi[mp] =  exp(term10); 
 end; /* do m = 0 to k; */
   nij_j=nij_j+nij;
   s_Mi=Mi[+];
   if s_Mi=0 then vec_r_ll_f[i]=log(10##(-300)) + s_term_poisi; else vec_r_ll_f[i]=log(s_Mi) + s_term_poisi;
end; /* do i = 1 to nflotte */

r_ll_f=vec_r_ll_f[+];
return(r_ll_f);
  free  nxijt nijt yijt xijt wijt lambdaij nij Mij nt yjt lambdajt term1 term2 term3 term4
        term3 s_term3 term4 s_term4 term5 term7 term8 term10 Mi sMij log_sMij;
finish r_llf_v;


/* Calcul du gradient */;

start r_llg(r_beta) global(nflotte, n_parm,kz,km,y,x,tt, ttc, n_period);

  ll_g=j(n_parm,1,0); 
  delta=r_beta[1,1];    bc_0_1=r_beta[1,2]; 
  delta_et=r_beta[1,3]; b_et=r_beta[1,4];
  par=r_beta[,5:n_parm];
  
   bc=bc_0_1/(1+bc_0_1);
   c_et=1/(delta_et + (delta#b_et#bc_0_1));

   p=ncol(x);
 
   lldelta=j(nflotte,1,0);
   llbc=j(nflotte,1,0);
   lldelta_et=j(nflotte,1,0);
   llb_et=j(nflotte,1,0);
   llp=j(nflotte,p,0);

   nxijt=0;
   r_ll_f=0;
   nij_j=0;

do i=1 to nflotte;

  rl=0; rla=0; rlb=0; rlc=0; rld=0; rlp=j(1,p,0);

  nijt=tt[i]; /* number of truck-year of the fleet i */
  ijt=(nxijt+1):(nxijt+nijt);
  nxijt=nxijt+nijt; 
  yijt=y[ijt];
  xijt=x[ijt,];
  wijt=xijt*par`;
  lambdaijt=exp(wijt);

  kmp=km+1;
  Mi=j(kmp,1,0);
  Mia=j(kmp,1,0); Mib=j(kmp,1,0); Mic=j(kmp,1,0); Mid=j(kmp,1,0); 
  Mip=j(kmp,p,0.);
  nij=ttc[i]; /* number of truck of fleet i */ 
  nxt=0;
  
  do m = 0 to km;
    mp=m+1;
    Mij=j(nij,1,0); Mija=j(nij,1,0); Mijb=j(nij,1,0); Mijc=j(nij,1,0); Mijd=j(nij,1,0); Mijp=j(nij,p,0);
    nxt=0; 
    do j=1 to nij;
     jj=j+nij_j;
     nt=n_period[jj]; /* number of periods of truck j of fleet i */ 
     jt=(nxt+1):(nxt+nt); 
     nxt=nxt+nt;
     yjt=yijt[jt];
     xjt=xijt[jt,];
     lambdajt=lambdaijt[jt];
      
      kzp=kz+1;
      Mijz=j(kzp,1,0);
      Mijza=j(kzp,1,0); Mijzb=j(kzp,1,0); Mijzc=j(kzp,1,0); Mijzd=j(kzp,1,0);
      Mijzp=j(kzp,p,0);
	  do z = 0 to kz;
	    zp = z+1;
	    term1 = lgamma(delta + m + z) - lgamma(delta + m) - lgamma(z+1);
	    term2 = z#log(bc) - (delta + m + z)#log(1 + bc);
	    term3 = lgamma(delta_et + b_et#z + yjt) - lgamma(delta_et + b_et#z);
	    s_term3 = term3[+];
	    term4 = yjt#log(c_et) - (delta_et + b_et#z + yjt)#log(1+(c_et#lambdajt));
	    s_term4 = term4[+];
	    term5 = term1 + term2 + s_term3 + s_term4 ;
	    Mijz[zp] = exp(term5);

        term5a1 = digamma(delta + m + z) - digamma(delta + m) - log(1+bc);
        term5a2 = -yjt#c_et#b_et#bc_0_1;
		s_term5a2=term5a2[+];
		term5a3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#b_et#bc_0_1;
        s_term5a3=term5a3[+];
        term5a=term5a1 + s_term5a2 + s_term5a3;
        Mijza[zp] = exp(term5)#term5a;

        term5b1 = (z/(bc_0_1#(1+bc_0_1))) - (delta+m+z)/((1+2#bc_0_1)#(1+bc_0_1));
        term5b2 = -yjt#(c_et)#b_et#delta;
		s_term5b2=term5b2[+];
		term5b3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#b_et#delta;
        s_term5b3=term5b3[+];
        term5b=term5b1 + s_term5b2 + s_term5b3;
        Mijzb[zp] = exp(term5)#term5b;

        term5c1 = digamma(delta_et + b_et*z + yjt) - digamma(delta_et + b_et*z) - log(1+c_et#lambdajt);
		s_term5c1= term5c1[+];
        term5c2 = -yjt#(c_et);
		s_term5c2=term5c2[+];
		term5c3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2);
        s_term5c3=term5c3[+];
        term5c=s_term5c1 + s_term5c2 + s_term5c3;
        Mijzc[zp] = exp(term5)#term5c;

        term5d1 = z#digamma(delta_et + b_et*z + yjt) - z#digamma(delta_et + b_et*z) - z#log(1+c_et#lambdajt);
		s_term5d1= term5d1[+];
        term5d2 = -yjt#(c_et)#bc_0_1#delta;
		s_term5d2=term5d2[+];
		term5d3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#bc_0_1#delta;
        s_term5d3=term5d3[+];
        term5d=s_term5d1 + s_term5d2 + s_term5d3;
        Mijzd[zp] = exp(term5)#term5d;

        ter_p1 = (c_et#lambdajt)#(delta_et + b_et#z + yjt)/(1+c_et#lambdajt);
		ter_p = -xjt#ter_p1;
        s_ter_p =ter_p[+,];
        Mijzp[zp,] = exp(term5)#s_ter_p;

      end; /* do z = 0 to k; */
	s_Mijz=Mijz[+];
    	s_Mijza=Mijza[+];
    	s_Mijzb=Mijzb[+];
   	s_Mijzc=Mijzc[+];
    	s_Mijzd=Mijzd[+];
    	s_Mijzp=Mijzp[+,];
    	Mij[j]=log(s_Mijz);
    	Mija[j]=s_Mijza/s_Mijz; 
    	Mijb[j]=s_Mijzb/s_Mijz;
   	Mijc[j]=s_Mijzc/s_Mijz; 
   	Mijd[j]=s_Mijzd/s_Mijz;
   	Mijp[j,]=s_Mijzp/s_Mijz;
   end; /*do j = 1 to nij; */  

   term7 = lgamma(delta + m) - lgamma(delta) - lgamma(m+1);
   term8 = m#log(bc) + delta#log(1-bc);
   s_term9 = Mij[+];
   term10 = term7 + term8 + s_term9;
   Mi[mp] = exp(term10); 
    
   term10a = digamma(delta + m) - digamma(delta) + log(1-bc) + Mija[+];
   Mia[mp] = exp(term10)#term10a;

   term10b =  m/((bc_0_1)#(1+bc_0_1)) - delta/(1+bc_0_1) + Mijb[+];
   Mib[mp] = exp(term10)#term10b;

   term10c =  Mijc[+];
   Mic[mp] = exp(term10)#term10c;

   term10d =  Mijd[+];
   Mid[mp] = exp(term10)#term10d;

    term10p = Mijp[+,];
    Mip[mp,] = exp(term10)#term10p;
 end; /* do m = 0 to k; */
   nij_j=nij_j+nij;
   s_Mi =Mi[+];
   s_Mia =Mia[+];  s_Mib =Mib[+];  s_Mic =Mic[+];  s_Mid =Mid[+];
   s_Mip =Mip[+,];

   if s_Mi=0 then rla = s_Mia/(10##(-300)); else rla = s_Mia/s_Mi;
   lldelta[i]= rla;

   if s_Mi=0 then rlb = s_Mib/(10##(-300)); else rlb = s_Mib/s_Mi;
   llbc[i]= rlb;

   if s_Mi=0 then rlc = s_Mic/(10##(-300)); else rlc = s_Mic/s_Mi;
   lldelta_et[i]= rlc;

   if s_Mi=0 then rld = s_Mid/(10##(-300)); else rld = s_Mid/s_Mi;
   llb_et[i]=rld;

   if s_Mi=0 then rlp = s_Mip/(10##(-300)); else rlp = s_Mip/s_Mi;
   det_poisi = xijt#yijt;
   s_det_poisi=det_poisi[+,];
   
   llp[i,]=rlp + s_det_poisi;

 end; /* do i = 1 to nflotte */

  s_lldelta = lldelta[+];
  s_llbc = llbc[+];
  s_lldelta_et = lldelta_et[+];
  s_llb_et = llb_et[+];
  s_llp = llp[+,];
  
   ll_g[1]=s_lldelta;
   ll_g[2]=s_llbc;
   ll_g[3]=s_lldelta_et;
   ll_g[4]=s_llb_et;
   do jjj=5 to n_parm;
     iii=jjj-4;
     ll_g[jjj]=s_llp[iii];
   end;
 
   r_ll_g = t(ll_g);
   
  return(r_ll_g);
  free  nxijt nijt yijt xijt wijt lambdaij nij Mij nt yjt lambdajt term1 term2 term3 term4
        term3 s_term3 term4 s_term4 term5  term7 term8 s_term9 term10 Mi;
finish r_llg;

*Calcul du hessian;

start r_llh(r_beta) global(nflotte, n_parm,kz,km,y,x,tt, ttc, n_period);

  delta=r_beta[1,1];    bc_0_1=r_beta[1,2]; 
  delta_et=r_beta[1,3]; b_et=r_beta[1,4];
  par=r_beta[,5:n_parm];
  
   bc=bc_0_1/(1+bc_0_1);
   c_et=1/(delta_et + (delta#b_et#bc_0_1));
  
   p=ncol(x);
   
   nxijt=0;
   r_ll_f=0;
   nij_j=0;

   ll_h=j(n_parm,n_parm,0); 

   lldelta=j(nflotte,1,0);
   lldeltabc=j(nflotte,1,0);
   lldeltadelta_et=j(nflotte,1,0);
   lldeltab_et=j(nflotte,1,0);

   llbc=j(nflotte,1,0);
   llbcdelta_et=j(nflotte,1,0);
   llbcb_et=j(nflotte,1,0);

   lldelta_et=j(nflotte,1,0);
   lldelta_etb_et=j(nflotte,1,0);

   llb_et=j(nflotte,1,0);

   llpdelta=j(nflotte,p,0);
   llpbc=j(nflotte,p,0);
   llpdelta_et=j(nflotte,p,0);
   llpb_et=j(nflotte,p,0);

  s_rlpp=j(p,p,0);

do i=1 to nflotte;

  rl=0; rla=0; rlb=0; rlc=0; rld=0; rlp=j(1,p,0);

  nijt=tt[i]; /* number of truck-year of the fleet i */
  ijt=(nxijt+1):(nxijt+nijt);
  nxijt=nxijt+nijt; 
  yijt=y[ijt];
  xijt=x[ijt,];
  wijt=xijt*par`;
  lambdaijt=exp(wijt);

  kmp=km+1;
  Mi=j(kmp,1,0);
  Mia=j(kmp,1,0); Mib=j(kmp,1,0); Mic=j(kmp,1,0); Mid=j(kmp,1,0);  Mip=j(kmp,p,0.);

  Miaa=j(kmp,1,0); Miab=j(kmp,1,0); Miac=j(kmp,1,0); Miad=j(kmp,1,0); Miap=j(kmp,p,0.);
                   Mibb=j(kmp,1,0); Mibc=j(kmp,1,0); Mibd=j(kmp,1,0); Mibp=j(kmp,p,0.);
                                    Micc=j(kmp,1,0); Micd=j(kmp,1,0); Micp=j(kmp,p,0.);
						     Midd=j(kmp,1,0); Midp=j(kmp,p,0.);
                                                                      s_Mipp=j(p,p,0);
  nij=ttc[i]; /* number of truck of fleet i */ 

  nxt=0;
  do m = 0 to km; 
    mp=m+1;
    Mij=j(nij,1,0); Mija=j(nij,1,0); Mijb=j(nij,1,0); Mijc=j(nij,1,0); Mijd=j(nij,1,0); Mijp=j(nij,p,0);

	Mijaa=j(nij,1,0); Mijab=j(nij,1,0); Mijac=j(nij,1,0); Mijad=j(nij,1,0);  Mijap=j(nij,p,0);
                    	  Mijbb=j(nij,1,0); Mijbc=j(nij,1,0); Mijbd=j(nij,1,0);  Mijbp=j(nij,p,0);
					    Mijcc=j(nij,1,0); Mijcd=j(nij,1,0);  Mijcp=j(nij,p,0);
							      Mijdd=j(nij,1,0);  Mijdp=j(nij,p,0);
	                                                                         s_Mijpp=j(p,p,0);

    nxt=0; 
    do j=1 to nij;
     jj=j+nij_j;
     nt=n_period[jj]; /* number of periods of truck j of fleet i */ 
     jt=(nxt+1):(nxt+nt); 
     nxt=nxt+nt;
     yjt=yijt[jt];
     xjt=xijt[jt,];
     lambdajt=lambdaijt[jt];
      
      kzp=kz+1;
      Mijz=j(kzp,1,0);
      Mijza=j(kzp,1,0); Mijzb=j(kzp,1,0); Mijzc=j(kzp,1,0); Mijzd=j(kzp,1,0); Mijzp=j(kzp,p,0); 

      Mijzaa=j(kzp,1,0); Mijzab=j(kzp,1,0); Mijzac=j(kzp,1,0); Mijzad=j(kzp,1,0); Mijzap=j(kzp,p,0);  
                         Mijzbb=j(kzp,1,0); Mijzbc=j(kzp,1,0); Mijzbd=j(kzp,1,0); Mijzbp=j(kzp,p,0); 
					    Mijzcc=j(kzp,1,0); Mijzcd=j(kzp,1,0); Mijzcp=j(kzp,p,0); 
								Mijzdd=j(kzp,1,0); Mijzdp=j(kzp,p,0); 
                                                                                  s_Mijzpp=j(p,p,0);

	  do z = 0 to kz;
	    zp = z+1;
	    term1 = lgamma(delta + m + z) - lgamma(delta + m) - lgamma(z+1);
		term2 = z#log(bc) - (delta + m + z)#log(1 + bc);
		term3 = lgamma(delta_et + b_et#z + yjt) - lgamma(delta_et + b_et#z);
		s_term3 = term3[+];
		term4 = yjt#log(c_et) - (delta_et + b_et#z + yjt)#log(1+(c_et#lambdajt));
		s_term4 = term4[+];
		term5 = term1 + term2 + s_term3 + s_term4 ;
		Mijz[zp] = exp(term5);

        term5a1 = digamma(delta + m + z) - digamma(delta + m) - log(1+bc);
        term5a2 = -yjt#c_et#b_et#bc_0_1;
		s_term5a2=term5a2[+];
		term5a3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#b_et#bc_0_1;
        s_term5a3=term5a3[+];
        term5a=term5a1 + s_term5a2 + s_term5a3;
        Mijza[zp] = exp(term5)#term5a;

        term5b1 = (z/(bc_0_1#(1+bc_0_1))) - (delta+m+z)/((1+2#bc_0_1)#(1+bc_0_1));
        term5b2 = -yjt#(c_et)#b_et#delta;
		s_term5b2=term5b2[+];
		term5b3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#b_et#delta;
        s_term5b3=term5b3[+];
        term5b=term5b1 + s_term5b2 + s_term5b3;
        Mijzb[zp] = exp(term5)#term5b;

        term5c1 = digamma(delta_et + b_et*z + yjt) - digamma(delta_et + b_et*z) - log(1+c_et#lambdajt);
		s_term5c1= term5c1[+];
        term5c2 = -yjt#(c_et);
		s_term5c2=term5c2[+];
		term5c3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2);
        s_term5c3=term5c3[+];
        term5c=s_term5c1 + s_term5c2 + s_term5c3;
        Mijzc[zp] = exp(term5)#term5c;

        term5d1 = z#digamma(delta_et + b_et*z + yjt) - z#digamma(delta_et + b_et*z) - z#log(1+c_et#lambdajt);
		s_term5d1= term5d1[+];
        term5d2 = -yjt#(c_et)#bc_0_1#delta;
		s_term5d2=term5d2[+];
		term5d3=(delta_et + b_et#z + yjt)#(lambdajt/(1+(c_et#lambdajt)))#(c_et##2)#bc_0_1#delta;
        s_term5d3=term5d3[+];
        term5d=s_term5d1 + s_term5d2 + s_term5d3;
        Mijzd[zp] = exp(term5)#term5d;

        ter_p1 = (c_et#lambdajt)#(delta_et + b_et#z + yjt)/(1+c_et#lambdajt);
		ter_p = -xjt#ter_p1;
        s_ter_p =ter_p[+,];
        Mijzp[zp,] = exp(term5)#s_ter_p;
        
        term5aa1 = trigamma(delta + m + z) - trigamma(delta + m);
		s_term5aa2=((c_et#b_et#bc_0_1)##2)#yjt[+];
		term5aa3=(delta_et + b_et#z + yjt)#lambdajt#
                 (-2 - c_et#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
        s_term5aa3=((c_et#b_et#bc_0_1)##2)#c_et#term5aa3[+];
        term5aa=term5aa1 + s_term5aa2 + s_term5aa3;
        Mijzaa[zp] = exp(term5)#term5aa + term5a#Mijza[zp];

        term5ab1=-((1+bc_0_1)##-2)/(1+bc);
		s_term5ab2=-((c_et##2)#delta_et#b_et)#yjt[+];
		term5ab3=(delta_et + b_et#z + yjt)#b_et#lambdajt#(c_et##4)#
                 ((1+c_et#lambdajt)#(delta_et+delta#b_et#bc_0_1)#(delta_et-delta#b_et#bc_0_1) + 
                      (lambdajt#delta#b_et#bc_0_1))#
                 ((1+(c_et#lambdajt))##-2);
        s_term5ab3=term5ab3[+];
        term5ab= term5ab1 + s_term5ab2+ s_term5ab3;
        Mijzab[zp] = exp(term5)#term5ab + term5b#Mijza[zp];

		s_term5ac2=((c_et##2)#b_et#bc_0_1)#yjt[+];
		term5ac3=b_et#bc_0_1#lambdajt#
                 ( (-2#(c_et##3)#(delta_et+b_et#z+yjt)+(c_et##2))#(1+(c_et#lambdajt)) +
                 lambdajt#(c_et##4)#(delta_et+b_et#z+yjt))#
                 ((1+(c_et#lambdajt))##-2);
        s_term5ac3=term5ac3[+];
        term5ac= s_term5ac2+ s_term5ac3;
        Mijzac[zp] = exp(term5)#term5ac + term5c#Mijza[zp];

	s_term5ad2=-delta_et#(c_et##2)#bc_0_1#yjt[+];
	term5ad3=lambdajt#bc_0_1#( ((c_et##2)#(delta_et+2#b_et#z+yjt) - 
                                   2#(c_et##3)#delta#b_et#bc_0_1#(delta_et+b_et#z+yjt))#(1+(c_et#lambdajt)) +
				   lambdajt#(c_et##4)#b_et#delta#bc_0_1#(delta_et+b_et#z+yjt) )#
                 ((1+(c_et#lambdajt))##-2);
        s_term5ad3=term5ad3[+];
        term5ad=  s_term5ad2+ s_term5ad3;
        Mijzad[zp] = exp(term5)#term5ad + term5d#Mijza[zp];

	ter_ap1 = ( (c_et##2)#b_et#bc_0_1#(delta_et+b_et#z+yjt)#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
	ter_ap=xjt#ter_ap1;
        s_ter_ap =ter_ap[+,];
        Mijzap[zp,] = exp(term5)#s_ter_ap + Mijza[zp]#s_ter_p;

        term5bb1=-z#(1+2#bc_0_1)#(bc_0_1##-2)#((1+bc_0_1)##-2) + 
                  (delta+m+z)#(3+4#bc_0_1)#((1+2#bc_0_1)##-2)#((1+bc_0_1)##-2);
	s_term5bb2=((c_et#delta#b_et)##2)#yjt[+];
	term5bb3=lambdajt#delta#b_et#(delta_et+b_et#z+yjt)#
		        ( -(1+(c_et#lambdajt))#(2#delta#b_et#(c_et##3)) + 
                   lambdajt#delta#b_et#(c_et##4))#
              ((1+(c_et#lambdajt))##-2);
        s_term5bb3=term5bb3[+];
        term5bb= term5bb1 + s_term5bb2+ s_term5bb3;
        Mijzbb[zp] = exp(term5)#term5bb + term5b#Mijzb[zp];

	s_term5bc2=(c_et##2)#delta#b_et#yjt[+];
	term5bc3=lambdajt#delta#b_et#
		         (((c_et##2) - 2#(c_et##3)#(delta_et+b_et#z+yjt))#(1+(c_et#lambdajt))  +
                   lambdajt#(c_et##4)#(delta_et+b_et#z+yjt))#
                 ((1+(c_et#lambdajt))##-2);
        s_term5bc3=term5bc3[+];
        term5bc= s_term5bc2+ s_term5bc3;
        Mijzbc[zp] = exp(term5)#term5bc + term5c#Mijzb[zp];

	s_term5bd2=-delta#(c_et - (c_et##2)#delta#b_et#bc_0_1)#yjt[+];
	term5bd3=lambdajt#delta#
                 ((b_et#(z#(c_et##2)-2#(c_et##3)#delta#bc_0_1#(delta_et+b_et#z+yjt)) +
				  ((delta_et+b_et#z+yjt)#(c_et##2)))#(1+(c_et#lambdajt)) +
				  (b_et#(delta_et+b_et#z+yjt)#(c_et##2))#(lambdajt#delta#bc_0_1#(c_et##2)))#
                 ((1+(c_et#lambdajt))##-2);
        s_term5bd3=term5bd3[+];
        term5bd=  s_term5bd2+ s_term5bd3;
        Mijzbd[zp] = exp(term5)#term5bd + term5d#Mijzb[zp];

	ter_bp1 = ( (c_et##2)#b_et#delta#(delta_et+b_et#z+yjt)#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
	ter_bp=xjt#ter_bp1;
        s_ter_bp =ter_bp[+,];
        Mijzbp[zp,] = exp(term5)#s_ter_bp + Mijzb[zp]#s_ter_p;

        term5cc1=trigamma(delta_et+b_et#z+yjt) - trigamma(delta_et+b_et#z) +
		         lambdajt#(c_et##2)/(1+(c_et#lambdajt));
        s_term5cc1=term5cc1[+];
        s_term5cc2=(c_et##2)#yjt[+];
	term5cc3=lambdajt#
                 ((-2#(c_et##3)#(delta_et+b_et#z+yjt) + (c_et##2))#(1+(c_et#lambdajt)) +
				 (delta_et+b_et#z+yjt)#(c_et##4)#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
        s_term5cc3=term5cc3[+];
        term5cc= s_term5cc1+s_term5cc2+ s_term5cc3;
        Mijzcc[zp] = exp(term5)#term5cc + term5c#Mijzc[zp];

        term5cd1=z#trigamma(delta_et+b_et#z+yjt) -z#trigamma(delta_et+b_et#z) +
		         lambdajt#delta#bc_0_1#(c_et##2)/(1+(c_et#lambdajt));
        s_term5cd1=term5cd1[+];
		s_term5cd2=delta#bc_0_1#(c_et##2)#yjt[+];
		term5cd3=lambdajt#
                 ((z#(c_et##2)-2#(c_et##3)#delta#bc_0_1#(delta_et+b_et#z+yjt))#(1+(c_et#lambdajt)) +
                  (delta_et+b_et#z+yjt)#(c_et##4)#lambdajt#delta#bc_0_1)#
                 ((1+(c_et#lambdajt))##-2);
        s_term5cd3=term5cd3[+];
        term5cd=  s_term5cd1+s_term5cd2+ s_term5cd3;
        Mijzcd[zp] = exp(term5)#term5cd + term5d#Mijzc[zp];
        
		ter_cp1 =-c_et#lambdajt/(1+(c_et#lambdajt))  + ((c_et##2)#(delta_et+b_et#z+yjt)#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
		ter_cp=xjt#ter_cp1;
        s_ter_cp =ter_cp[+,];
        Mijzcp[zp,] = exp(term5)#s_ter_cp + Mijzc[zp]#s_ter_p;

       term5dd1=(z##2)#trigamma(delta_et+b_et#z+yjt) -(z##2)#trigamma(delta_et+b_et#z) +
		         z#lambdajt#delta#bc_0_1#(c_et##2)/(1+(c_et#lambdajt));
       s_term5dd1=term5dd1[+];
       s_term5dd2=((c_et#delta#bc_0_1)##2)#yjt[+];
       term5dd3=lambdajt#delta#bc_0_1#
                 ((z#(c_et##2)-2#(c_et##3)#delta#bc_0_1#(delta_et+b_et#z+yjt))#(1+(c_et#lambdajt)) +
				  (delta_et+b_et#z+yjt)#(c_et##4)#lambdajt#delta#bc_0_1)#
                 ((1+(c_et#lambdajt))##-2);
        s_term5dd3=term5dd3[+];
        term5dd= s_term5dd1 + s_term5dd2 + s_term5dd3;
        Mijzdd[zp] = exp(term5)#term5dd + term5d#Mijzd[zp];

	ter_dp1 = -z#c_et#lambdajt/(1+(c_et#lambdajt))  + ((c_et##2)#bc_0_1#delta#(delta_et+b_et#z+yjt)#lambdajt)#
                 ((1+(c_et#lambdajt))##-2);
	ter_dp=xjt#ter_dp1;
        s_ter_dp =ter_dp[+,];
        Mijzdp[zp,] = exp(term5)#s_ter_dp + Mijzd[zp]#s_ter_p;

        Mijzpp=j(p,p,0);
	do indxp = 1 to p;
         ter_pp1 = -c_et#lambdajt#(delta_et + b_et#z + yjt)#
                   ((1+c_et#lambdajt)##-2);
         ter_pp = (xjt#xjt[,indxp])#ter_pp1;
         s_ter_pp=ter_pp[+,];

         ter_p2 = -xjt[,indxp]#ter_p1;
         s_ter_p2=ter_p2[+,];
		
         Mijzpp[indxp,]= exp(term5)#s_ter_p#s_ter_p2 + exp(term5)#s_ter_pp;
	end;

      s_Mijzpp = s_Mijzpp + Mijzpp;
      end; /* do z = 0 to k; */


    s_Mijz=Mijz[+];

    s_Mijza=Mijza[+];  s_Mijzb=Mijzb[+]; s_Mijzc=Mijzc[+];  s_Mijzd=Mijzd[+]; s_Mijzp=Mijzp[+,];

    s_Mijzaa=Mijzaa[+]; s_Mijzab=Mijzab[+]; s_Mijzac=Mijzac[+]; s_Mijzad=Mijzad[+]; s_Mijzap=Mijzap[+,];
                        s_Mijzbb=Mijzbb[+]; s_Mijzbc=Mijzbc[+]; s_Mijzbd=Mijzbd[+]; s_Mijzbp=Mijzbp[+,];
                                            s_Mijzcc=Mijzcc[+]; s_Mijzcd=Mijzcd[+]; s_Mijzcp=Mijzcp[+,];
								s_Mijzdd=Mijzdd[+]; s_Mijzdp=Mijzdp[+,];
    
    Mij[j]=log(s_Mijz);

    Mija[j]=s_Mijza/s_Mijz; 
    Mijb[j]=s_Mijzb/s_Mijz;
    Mijc[j]=s_Mijzc/s_Mijz; 
    Mijd[j]=s_Mijzd/s_Mijz;
    Mijp[j,]=s_Mijzp/s_Mijz;

    Mijaa[j]=-(Mija[j])#(Mija[j]) + s_Mijzaa /s_Mijz; 
    Mijab[j]=-(Mija[j])#(Mijb[j]) + s_Mijzab /s_Mijz; 
    Mijac[j]=-(Mija[j])#(Mijc[j]) + s_Mijzac /s_Mijz; 
    Mijad[j]=-(Mija[j])#(Mijd[j]) + s_Mijzad /s_Mijz; 
    Mijap[j,]=-(Mija[j])#(Mijp[j,]) + s_Mijzap /s_Mijz; 

    Mijbb[j]=-(Mijb[j])#(Mijb[j]) + s_Mijzbb /s_Mijz; 
    Mijbc[j]=-(Mijb[j])#(Mijc[j]) + s_Mijzbc /s_Mijz; 
    Mijbd[j]=-(Mijb[j])#(Mijd[j]) + s_Mijzbd /s_Mijz; 
    Mijbp[j,]=-(Mijb[j])#(Mijp[j,]) + s_Mijzbp /s_Mijz; 

    Mijcc[j]=-(Mijc[j])#(Mijc[j]) + s_Mijzcc /s_Mijz; 
    Mijcd[j]=-(Mijc[j])#(Mijd[j]) + s_Mijzcd /s_Mijz; 
    Mijcp[j,]=-(Mijc[j])#(Mijp[j,]) + s_Mijzcp /s_Mijz; 

    Mijdd[j]=-(Mijd[j])#(Mijd[j]) + s_Mijzdd /s_Mijz; 
    Mijdp[j,]=-(Mijd[j])#(Mijp[j,]) + s_Mijzdp /s_Mijz; 


   Mijpp=j(p,p,0);
    do indxp1 = 1 to p;
      Mijpp[indxp1,]= -(s_Mijzp/s_Mijz)#((s_Mijzp[indxp1])/s_Mijz) + s_Mijzpp[indxp1,]/(s_Mijz);
    end;

      s_Mijpp = s_Mijpp + Mijpp;

   end; /*do j = 1 to nij; */  

   term7 = lgamma(delta + m) - lgamma(delta) - lgamma(m+1);
   term8 = m#log(bc) + delta#log(1-bc);
   s_term9 = Mij[+];
   term10 = term7 + term8 + s_term9;

   Mi[mp] = exp(term10); 

   term10a = digamma(delta + m) - digamma(delta) + log(1-bc) + Mija[+];
   Mia[mp] = exp(term10)#term10a;

   term10b =  m/((bc_0_1)#(1+bc_0_1)) - delta/(1+bc_0_1) + Mijb[+];
   Mib[mp] = exp(term10)#term10b;

   term10c =  Mijc[+];
   Mic[mp] = exp(term10)#term10c;

   term10d =  Mijd[+];
   Mid[mp] = exp(term10)#term10d;

   term10p = Mijp[+,];
    Mip[mp,] = exp(term10)#term10p;

   term10aa = trigamma(delta + m) - trigamma(delta) + Mijaa[+];
   Miaa[mp] = exp(term10)#term10aa + exp(term10)#term10a#term10a;
   term10ab = -((1+bc_0_1)##-2)/(1-bc) + Mijab[+];
   Miab[mp] = exp(term10)#term10ab + exp(term10)#term10a#term10b;
   term10ac =  Mijac[+];
   Miac[mp] = exp(term10)#term10ac + exp(term10)#term10a#term10c;
   term10ad =  Mijad[+];
   Miad[mp] = exp(term10)#term10ad + exp(term10)#term10a#term10d;
   term10ap =  Mijap[+,];
   Miap[mp,] = exp(term10)#term10ap + exp(term10)#term10a#term10p;


   term10bb = -m#(1+2#bc_0_1)#(bc_0_1##-2)#((1+bc_0_1)##-2) + delta#((1+bc_0_1)##-2)
              + Mijbb[+];
   Mibb[mp] = exp(term10)#term10bb + exp(term10)#term10b#term10b;
   term10bc =  Mijbc[+];
   Mibc[mp] = exp(term10)#term10bc + exp(term10)#term10b#term10c;
   term10bd =  Mijbd[+];
   Mibd[mp] = exp(term10)#term10bd + exp(term10)#term10b#term10d;
   term10bp =  Mijbp[+,];
   Mibp[mp,] = exp(term10)#term10bp + exp(term10)#term10b#term10p;

   term10cc =  Mijcc[+];
   Micc[mp] = exp(term10)#term10cc + exp(term10)#term10c#term10c;

   term10cd =  Mijcd[+];
   Micd[mp] = exp(term10)#term10cd + exp(term10)#term10c#term10d;

   term10cp =  Mijcp[+,];
   Micp[mp,] = exp(term10)#term10cp + exp(term10)#term10c#term10p;

   term10dd =  Mijdd[+];
   Midd[mp] = exp(term10)#term10dd + exp(term10)#term10d#term10d;

   term10dp =  Mijdp[+,];
   Midp[mp,] = exp(term10)#term10dp + exp(term10)#term10d#term10p;


   Mipp=j(p,p,0);
    do indxp2 = 1 to p;
      Mipp[indxp2,]=exp(term10)#term10p#term10p[indxp2] +
                   exp(term10)#s_Mijpp[indxp2,];
    end;
   
  s_Mipp = s_Mipp + Mipp;

 end; /* do m = 0 to k; */

   nij_j=nij_j+nij;

   s_Mi =Mi[+]; if s_Mi=0 then s_Mi=(10##(-300));

   s_Mia =Mia[+]; s_Mib =Mib[+];  s_Mic =Mic[+];  s_Mid =Mid[+]; s_Mip =Mip[+,];

   s_Miaa = Miaa[+]; s_Miab = Miab[+]; s_Miac = Miac[+]; s_Miad = Miad[+]; s_Miap = Miap[+,];
                     s_Mibb = Mibb[+]; s_Mibc = Mibc[+]; s_Mibd = Mibd[+]; s_Mibp = Mibp[+,];
                                       s_Micc = Micc[+]; s_Micd = Micd[+]; s_Micp = Micp[+,];
					                 s_Midd = Midd[+]; s_Midp = Midp[+,];

   if s_Mi=0 then rlp = s_Mip/(10##(-300)); else rlp = s_Mip/s_Mi;
   
   rlpp=j(p,p,0);
    do indxp3 = 1 to p;
      rlpp[indxp3,]= ((-s_Mip/s_mi)#(s_Mip[indxp3]/s_Mi)) +
	                 (s_Mipp[indxp3,])/s_Mi;               
    end;

     rlaa = -(s_Mia/s_Mi)#(s_Mia/s_Mi) +  s_Miaa/s_Mi;
     lldelta[i]= rlaa;
     rlab = -(s_Mia/s_Mi)#(s_Mib/s_Mi) +  s_Miab/s_Mi;
     lldeltabc[i]= rlab;
     rlac = -(s_Mia/s_Mi)#(s_Mic/s_Mi) +  s_Miac/s_Mi;
     lldeltadelta_et[i]= rlac;
     rlad = -(s_Mia/s_Mi)#(s_Mid/s_Mi) +  s_Miad/s_Mi;
     lldeltab_et[i]= rlad;
     rlap = -(s_Mia/s_Mi)#(s_Mip/s_Mi) +  s_Miap/s_Mi;
     llpdelta[i,]= rlap;

     rlbb = -(s_Mib/s_Mi)#(s_Mib/s_Mi) +  s_Mibb/s_Mi;
     llbc[i]= rlbb;
     rlbc = -(s_Mib/s_Mi)#(s_Mic/s_Mi) +  s_Mibc/s_Mi;
     llbcdelta_et[i]= rlbc;
     rlbd = -(s_Mib/s_Mi)#(s_Mid/s_Mi) +  s_Mibd/s_Mi;
     llbcb_et[i]= rlbd;
     rlbp = -(s_Mib/s_Mi)#(s_Mip/s_Mi) +  s_Mibp/s_Mi;
     llpbc[i,]= rlbp;

     rlcc = -(s_Mic/s_Mi)#(s_Mic/s_Mi) +  s_Micc/s_Mi;
     lldelta_et[i]= rlcc;

     rlcd = -(s_Mic/s_Mi)#(s_Mid/s_Mi) +  s_Micd/s_Mi;
     lldelta_etb_et[i]= rlcd;

     rlcp = -(s_Mic/s_Mi)#(s_Mip/s_Mi) +  s_Micp/s_Mi;
     llpdelta_et[i,]= rlcp;

     rldd = -(s_Mid/s_Mi)#(s_Mid/s_Mi) +  s_Midd/s_Mi;
     llb_et[i]= rldd;

     rldp = -(s_Mid/s_Mi)#(s_Mip/s_Mi) +  s_Midp/s_Mi;
     llpb_et[i,]= rldp;


     s_rlpp = s_rlpp + rlpp;
	  

 end; /* do i = 1 to nflotte */

s_lldelta=lldelta[+];
s_lldeltabc=lldeltabc[+];
s_lldeltadelta_et=lldeltadelta_et[+];
s_lldeltab_et=lldeltab_et[+];
s_llpdelta=llpdelta[+,];  

s_llbc=llbc[+];  
s_llbcdelta_et=llbcdelta_et[+]; 
s_llbcb_et=llbcb_et[+]; 
s_llpbc=llpbc[+,]; 

s_lldelta_et=lldelta_et[+]; 
s_lldelta_etb_et=lldelta_etb_et[+]; 
s_llpdelta_et=llpdelta_et[+,];

s_llb_et=llb_et[+];
s_llpb_et=llpb_et[+,];  

   ll_h[1,1]=s_lldelta;
   ll_h[1,2]=s_lldeltabc;
   ll_h[1,3]=s_lldeltadelta_et;
   ll_h[1,4]=s_lldeltab_et;
   ll_h[1,5:n_parm]=s_llpdelta;
   ll_h[5:n_parm,1]=t(s_llpdelta);

   ll_h[2,1]=s_lldeltabc;
   ll_h[2,2]=s_llbc;
   ll_h[2,3]=s_llbcdelta_et;
   ll_h[2,4]=s_llbcb_et;
   ll_h[2,5:n_parm]=s_llpbc;
   ll_h[5:n_parm,2]=t(s_llpbc);

   ll_h[3,1]=s_lldeltadelta_et;
   ll_h[3,2]=s_llbcdelta_et;
   ll_h[3,3]=s_lldelta_et;
   ll_h[3,4]=s_lldelta_etb_et;
   ll_h[3,5:n_parm]=s_llpdelta_et;
   ll_h[5:n_parm,3]=t(s_llpdelta_et);

   ll_h[4,1]=s_lldeltab_et;
   ll_h[4,2]=s_llbcb_et;
   ll_h[4,3]=s_lldelta_etb_et;
   ll_h[4,4]=s_llb_et;
   ll_h[4,5:n_parm]=s_llpb_et;
   ll_h[5:n_parm,4]=t(s_llpb_et);
   
   ll_h[5:n_parm,5:n_parm]=s_rlpp;
   
   
  return(ll_h);
  free  nxijt nijt yijt xijt wijt lambdaij nij Mij nt yjt lambdajt term1 term2 term3 term4
        term3 s_term3 term4 s_term4 term5  term7 term8 s_term9 term10 Mi;
finish r_llh;


/*starting values */
r_beta[,1]=0.6725;
r_beta[,2]=2.1295;
r_beta[,3]=2.7240;
r_beta[,4]=2.6551;
r_beta[,5]=-3.1796;
r_beta[,6]=-0.0501;
r_beta[,7]=-0.2004;
r_beta[,8]=0.0966;
r_beta[,9]=0.0482;
r_beta[,10]=0.4637;
r_beta[,11]=-0.0526;
r_beta[,12]=0.1203;
r_beta[,13]=0.1761;
r_beta[,14]=0.2371;
r_beta[,15]=0.2805;
r_beta[,16]=0.2424;
r_beta[,17]=0.2735;
r_beta[,18]=1.6489;
r_beta[,19]=0.0990;
r_beta[,20]=0.1587;
r_beta[,21]=0.2442;
r_beta[,22]=0.1999;
r_beta[,23]=0.2174;
r_beta[,24]=0.2177;
r_beta[,25]=-0.1915;
r_beta[,26]=-0.0799;
r_beta[,27]=-0.4325;
r_beta[,28]=-0.3283;
r_beta[,29]=0.2268;
r_beta[,30]=0.3299;
r_beta[,31]=-0.3447;
r_beta[,32]=-0.3823;
r_beta[,33]=-0.3014;
r_beta[,34]=-0.2084;
r_beta[,35]=-0.2524;
r_beta[,36]=0.2203;
r_beta[,37]=0.3956;
r_beta[,38]=0.3835;
r_beta[,39]=0.4178;
r_beta[,40]=0.2140;
r_beta[,41]=0.0003;
r_beta[,42]=-0.0302;
r_beta[,43]=-0.0913;
r_beta[,44]=-0.0220;
r_beta[,45]=0.0002;
r_beta[,46]=-0.0483;
r_beta[,47]=-0.1566;


kz=19;
km=19;
optn=j(1,11,.);
optn[1]=1;
optn[2]=5;
optn[8]=01;

con=j(2,n_parm,.);
con[1,1:4]=0.0000000000000001;
ter=repeat(.,1,10);
ter[1]=5000;
ter[2]=30000;

call nlpnra(rc,xr,"r_llf_v",r_beta,optn,con) tc=ter grd="r_llg" hes="r_llh";
r_xopt=xr; r_fopt=r_llf_v(r_xopt); r_gopt=r_llg(r_xopt); r_hopt=r_llh(r_xopt);

*Calcul Standard error of the parameters;
r_hin=-inv(r_hopt);
r_stder=sqrt(abs(vecdiag(r_hin)));
r_pr=r_xopt`;
t_ratio=r_pr/r_stder;
p_value=2#(1-probt(abs(t_ratio),n-n_parm));

iii=r_pr||r_stder||t_ratio||P_value;

b2_label={"coefficents" "S.E." "t_ratio" "P_value"};

print "Hierarchical random effect models for fleet insurance pricing adding one truck fleet",
       iii[colname=b2_label rowname=parm3 format=10.7],;

AIC = -2*r_fopt + 2*n_parm;
BIC = -2*r_fopt + n_parm*log(n);
print AIC BIC;
quit;