program threelevel c for three level cumulative generalized linear model c mgmc algorithm c ming-hui chen c discussion paper joint with chuanhai liu c may 9, 1998 c implicit real*8 (a-h,o-z) parameter( n=8 ) parameter (iprint=3,maxlag=20,nobs=50000) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 seqgam(50000),seqbeta(2,50000) real*8 tau real*8 sbeta(2),s2beta(2),ebeta(2),sebeta(2) real*8 egam,segam,sgam,s2gam real*8 ac(maxlag+1),acv(maxlag+1),seac(maxlag+1), 1 xac(nobs+1), xacmean integer iseed,nrep integer imean,iseopt common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external dacf tau=0.001d0 c.......data set y(1)=3.0d0 x(1)=1.0d0 y(2)=2.0d0 x(2)=0.0d0 y(3)=3.0d0 x(3)=1.0d0 y(4)=1.0d0 x(4)=0.0d0 y(5)=3.0d0 x(5)=1.0d0 y(6)=1.0d0 x(6)=0.0d0 y(7)=3.0d0 x(7)=1.0d0 y(8)=3.0d0 x(8)=0.0d0 print*,'enter number of interations nrep=' read(*,*) nrep imean=1 iseopt=1 c........set initial value iseed=9999999 gam(1)=0.0d0 gam(2)=1.0d0 beta(1)=0.0d0 beta(2)=1.0d0 call rnset( iseed ) c.......warm up gibbs icount=0 sbeta(1)=0.0d0 sbeta(2)=0.0d0 s2beta(1)=0.0d0 s2beta(2)=0.0d0 do 100 i=1,5000 call gibbs( iseed ) if ( (i .eq. 1) .or. (i .eq. icount)) then write(*,*) 'warm up: i=',i write(*,800) beta(1),beta(2) 800 format('beta=',2f16.6) write(*,801) gam(2) 801 format('gam(2)=',f16.6) icount=icount+100 endif 100 continue icount=0 do 110 i=1,nrep call gibbs( iseed ) if ( (i .eq. 1) .or. (i .eq. icount)) then write(*,*) 'Gibbs: i=',i write(*,800) beta(1),beta(2) write(*,801) gam(2) icount=icount+100 endif do 120 j=1,2 seqbeta(j,i)=beta(j) sbeta(j)=sbeta(j)+beta(j) s2beta(j)=s2beta(j)+beta(j)**2 120 continue seqgam(i)=gam(2) sgam=sgam+gam(2) s2gam=s2gam+gam(2)**2 110 continue c........to obtain posterior estimates do 140 j=1,2 ebeta(j)=sbeta(j)/real(nrep) sebeta(j)=dsqrt( (s2beta(j)-real(nrep)*ebeta(j)**2) 1 /real(nrep-1) ) 140 continue egam=sgam/real(nrep) segam=dsqrt( (s2gam-real(nrep)*egam**2) 1 /real(nrep-1) ) open(unit=14,file='ca_mg.dat',access='sequential', 1 status='unknown') do 500 i=1,nrep write(14,990) i,seqbeta(1,i),seqbeta(2,i),seqgam(i) 990 format(1x,I6,3f16.6) 500 continue close(14) c........compute autocorrelation c c........for beta(1) write(*,*) 'for beta(1)' do 300 i=1,nrep xac(i)=seqbeta(1,i) 300 continue imean=1 iseopt=1 call dacf(nrep,xac,iprint,iseopt,imean,xacmean,maxlag, 1 acv,ac,seac) c........for beta(2) write(*,*) 'for beta(2)' do 310 i=1,nrep xac(i)=seqbeta(2,i) 310 continue call dacf(nrep,xac,iprint,iseopt,imean,xacmean,maxlag, 1 acv,ac,seac) c........for beta(1)+beta(2) write(*,*) 'for beta(1)+beta(2)' do 320 i=1,nrep xac(i)=seqbeta(2,i)+seqbeta(1,i) 320 continue call dacf(nrep,xac,iprint,iseopt,imean,xacmean,maxlag, 1 acv,ac,seac) c........for gam write(*,*) 'for gam' do 330 i=1,nrep xac(i)=seqgam(i) 330 continue call dacf(nrep,xac,iprint,iseopt,imean,xacmean,maxlag, 1 acv,ac,seac) open(unit=12,file='ca_mg.out',access='sequential', 1 status='unknown') write(12,*) 'nrep=',nrep write(12,*) 'ebeta(1)=',ebeta(1),' se=',sebeta(1) write(12,*) 'ebeta(2)=', ebeta(2),' se=',sebeta(2) write(12,*) 'egam=',egam,' se=',segam close(12) stop end subroutine gibbs( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau integer iseed common /vbeta/beta common /vgam/gam common /vx/x common /vz/z common /vy/y common /vtau/tau c.......generate z call Gz( iseed ) c.......generate gam call Ggam( iseed ) c.......generate b(i) call Gbeta( iseed ) c.......adjusted step call Gmg( iseed ) c.......ca-adjusted step call Gca_mg( iseed ) return end subroutine Gz( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau real*8 aleft,aright,amean,tn,sig integer iseed logical la,lb common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external YTUVN la=.false. lb=.false. call rnset( iseed ) do 300 i=1,n amean=beta(1)+beta(2)*x(i) sig=1.0d0 if (y(i) .eq. 1.0d0) then la=.true. aright=-amean/sig tn=YTUVN(aleft,aright,la,lb,iseed) z(i)=amean+tn*sig la=.false. endif if (y(i) .eq. 2.0d0) then aleft=-amean/sig aright=(gam(2)-amean)/sig tn=YTUVN(aleft,aright,la,lb,iseed) z(i)=amean+tn*sig endif if (y(i) .eq. 3.0d0) then lb=.true. aleft=(gam(2)-amean)/sig tn=YTUVN(aleft,aright,la,lb,iseed) lb=.false. z(i)=amean+tn*sig endif 300 continue call rnget( iseed ) return end subroutine Ggam( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau real*8 scale,shape,r(1) real*8 sum real*8 alow,aupp real*8 amaxz(1:3),aminz(1:3),u integer iseed common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external DRNUNF index1=0 index2=0 do 400 i=1,n if (y(i) .eq. 3.0d0) then index1=index1+1 if (index1 .eq. 1) then aupp=z(i) else if (aupp .gt. z(i)) aupp=z(i) endif endif if (y(i) .eq. 2.0d0) then index2=index2+1 if (index2 .eq. 1) then alow=z(i) else if (alow .lt. z(i)) alow=z(i) endif endif 400 continue call rnset( iseed ) u=DRNUNF() call rnget( iseed ) gam(2)=alow+u*(aupp-alow) return end subroutine Gbeta( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau real*8 scale,shape,r(1) real*8 sum real*8 xvec(2) real*8 xx(1:2,1:2),Bm(1:2,1:2) real*8 Binv(1:2,1:2) real*8 Binv1(1:2,1:2) real*8 Siginv(1:2,1:2) real*8 bhat(2),bhat1(2) real*8 tol,Rsig(1:2,1:2),RV(1,2) integer iseed,irank,lda,ldr,nr common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external DMACH,DRNMVN c.......initialize do 180 i=1,2 do 185 j=1,2 Bm(i,j)=0.0d0 185 continue 180 continue do 190 i=1,2 bhat(i)=0.0d0 Bm(i,i)=tau 190 continue do 200 i=1,n c........calculate xx(2,2) xvec(1)=1.0d0 xvec(2)=x(i) do 209 i1=1,2 do 210 j1=1,2 xx(i1,j1)=xvec(i1)*xvec(j1) 210 continue 209 continue do 250 j=1,2 do 255 j1=1,2 Bm(j,j1)=Bm(j,j1)+xx(j,j1) 255 continue 250 continue do 220 j=1,2 bhat(j)=bhat(j)+xvec(j)*z(i) 220 continue 200 continue c.......calculate Binv call DLINDS(2,Bm,2,Binv,2) c.......calculate bhat1 do 270 i=1,2 bhat1(i)=0.0d0 do 275 j=1,2 bhat1(i)=bhat1(i)+Binv(i,j)*bhat(j) Binv1(i,j)=Binv(i,j) 275 continue 270 continue c.......do Cholesky factorization lda=2 ldr=2 tol=100.0d0*DMACH(4) call DCHFAC(2,Binv1,lda,tol,irank,Rsig,ldr) c.......generate multivariate normal nr=1 call rnset( iseed ) call DRNMVN(nr,2,Rsig,2,RV,1) call rnget( iseed ) do 300 j=1,2 beta(j)=RV(1,j)+bhat1(j) 300 continue return end subroutine Gmg( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau real*8 scale,shape,r(1) integer iseed common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external DRNGAM shape=real(n+1+2)/2.0d0 sum=0.0d0 do 400 i=1,n sum=sum+(z(i)-beta(1)-beta(2)*x(i))**2 400 continue scale=sum/2.0d0+tau*(beta(1)**2/2.0d0 1 +beta(2)**2/2.0d0) c call rnset( iseed ) c call DRNGAM(1,shape,r) c call rnget( iseed ) c g=dsqrt(r(1)/scale) c.......adjusted step beta(1)=g*beta(1) beta(2)=g*beta(2) gam(2)=g*gam(2) do 410 i=1,n z(i)=g*z(i) 410 continue return end subroutine Gca_mg( iseed ) implicit real*8 (a-h,o-z) parameter( n=8 ) real*8 z(n),x(n),beta(2),gam(2) real*8 y(n) real*8 tau real*8 scale,shape,r(1) real*8 zstar(4) integer iseed logical la,lb common /vbeta/beta common /vgam/gam common /vx/x common /vy/y common /vz/z common /vtau/tau external DRNNOF,YTUVN la=.false. lb=.false. sum=0.0d0 num=0 sig2o=1.0d0/tau c alpha=dsqrt(2.0d0) alpha=1.0d0 do 100 i=1,n if (x(i) .eq. 1.0d0) then sum=sum+z(i) num=num+1 endif 100 continue tstar=sum/real(num) ind=0 do 110 i=1,n if (x(i) .eq. 1.0d0) then ind=ind+1 zstar(ind)=z(i)-tstar endif 110 continue do 120 j=1,4 if (j .eq. 1) then alow=gam(2)-zstar(j) else if (alow .lt. gam(2)-zstar(j)) then alow=gam(2)-zstar(j) endif endif 120 continue c.......generate T amean=alpha*beta(1) std=dsqrt(0.25d0+sig2o) lb=.true. aleft=(alow-amean)/std tn=YTUVN(aleft,aright,la,lb,iseed) lb=.false. T=amean+std*tn c.......generate amu=beta(1)+beta(2) amean=alpha*beta(1)+ 1 sig2o*(T-alpha*beta(1))/(sig2o+0.25d0) std=sig2o-sig2o**2/(sig2o+0.25) std=dsqrt(std) call rnset( iseed ) tn=DRNNOF() call rnget( iseed ) amu=amean+tn*std c.......adjusting stage beta(2)=amu-beta(1) ind=0 do 210 i=1,n if (x(i) .eq. 1.0d0) then ind=ind+1 z(i)=zstar(ind)+T endif 210 continue return end include 'tnorm.f'