⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semip_gcc.c

📁 计量工具箱
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <malloc.h>
#include <mex.h>
#include "randomlib.h"
#include "matrixjpl.h"

// *****************************************************
// mex semip_gcc file (semip_gcc.c)

// *****************************************************

// routine to draw rho from the conditional posterior distribution
double draw_rho(double *rvec,
				double *ldet,
				double epe0,
				double eped,
				double epe0d,
				double sige,
				int nrho,
				int n,
				int k,
     			double rho)
{

	int i;
	double adj, nmk, nmk2, rnd;
	double *s, *den, *num;
	double dsum, rsum, z;
	

// compute denominator (integrating constant)
	      s    = dvector(0,nrho-1);
	      den  = dvector(0,nrho-1);
	      num  = dvector(0,nrho-1);

		  nmk = (double)(n-k);
		  nmk2 = nmk/2;	  

	  for(i=0; i<nrho; i++){
		      z = epe0 - 2.0*rvec[i]*eped + rvec[i]*rvec[i]*epe0d;
              s[i] = ldet[i] - (z/2*sige);
	  }

// adjustment for scaling that subtracts the maximum value
	adj = s[0];
	for(i=1; i<nrho; i++){
		if (s[i] > adj)
			adj = s[i];
	}
	
	for(i=0; i<nrho; i++){
		den[i] = (s[i] - adj);
		den[i] = exp(den[i]);
		}

	dsum = 0.0; // trapezoid rule
    for(i=0; i<nrho-1; i++){
		dsum = dsum + (rvec[i+1]+rvec[i])*(den[i+1]-den[i])/2;
	}

	    rsum = 0.0;
		for(i=0; i<nrho; i++){
		s[i] = dabs(den[i]/dsum); // normalize rho post
        rsum = rsum + s[i];
		if (i == 0){
		den[i] = s[i];
		} else {
		den[i] = den[i-1] + s[i]; // cumulative sum
		}
	}
	
    rnd = rsum*ranf();

	// create rho draw via inversion
	for(i=0; i<nrho; i++){
	  if (rnd <= den[i]){
	  rho = rvec[i];
	  break;
	  }
	  }
	  	  
	free_dvector(s,0);
	free_dvector(den,0);
	free_dvector(num,0);

	return (rho);

}




// *****************************************************
// MAIN SAMPLER
// *****************************************************

// Estimates robust spatial probit model using MCMC

// semip_gc(bdraw,adraw,pdraw,sdraw,rdraw,vmean,amean,zmean,yhat,cntr,
// y,x,W,ndraw,nomit,nsave,n,k,m,mobs,a,nu,d0,rval,mm,kk,detval,ngrid,TI,TIc)
     

void semip_gc(

		//Output Arguments

        double *bdraw, // draws for beta (ndraw - nomit,k) matrix
		double *adraw, // draws for regional effects, a, (m,1) vector
        double *pdraw, // draws for rho (ndraw - nomit,1) vector
		double *sdraw, // draws for sige (ndraw - nomit,1) vector
		double *rdraw, // draws for rval (ndraw - nomit,1) vector (if mm != 0)
		double *vmean, // mean of vi draws (n,1) vector			
        double *amean, // mean of a-draws (m,1) vector
        double *zmean, // mean of latent z-draws (n,1) vector
        double *yhat,  // mean of posterior predicted y (n,1) vector
            
		//Input Arguments

		double *y,		// (n,1) lhs vector with 0,1 values
 		double *x,		// (n,k) matrix of explanatory variables   
 		double *W,		// (m,m) weight matrix
        int ndraw,		// # of draws
        int nomit,		// # of burn-in draws to omit
		int nsave,		// # of draws saved (= ndraw - nomit)
        int n,			// # of observations
		int k,			// # of explanatory variables
        int m,			// # of regions
        int *mobs,		// (m,1) vector of obs numbers in each region
		double *a,		// (m,1) vector of regional effects
		double nu,		// prior parameter for sige	 
        double d0,		// prior parameter for sige
        double rval,	// hyperparameter r            
        double mm,		// prior parameter for rval
        double kk,		// prior parameter for rval
        double *detval, // (ngrid,2) matrix with [rho , log det values]            
        int ngrid,		// # of values in detval (rows)
        double *TI,		// prior var-cov for beta (inverted in matlab)
		double *TIc)	// prior var-cov * prior mean	

{
    
// Local Variables

	int i,j,l,iter,invt,accept,rcount,cobs,obsi,zflag;
    double rmin,rmax,sige,chi,ee,ratio,p,rho,rho_new;
	double junk,aBBa,vsqrt,ru,rhox,rhoy,phi,awi,aw2i,bi,di;
    double *z,*tvec,*e,*e0,*xb,*mn,*ys,*limit1,*limit2,*zmt;
	double *bhat,*b0,*b0tmp,*v,*vv,*b1,*b1tmp,*Bpa,*rdet,*ldet,*w1;
	double **xs,**xst,**xsxs,**A0,**A1,**Bpt,**Bp,**xmat,**W2; 	
	double *Wa, **Wmat;
	double c0, c1,c2;

		   
// Allocate Matrices and Vectors


	  xs     = dmatrix(0,n-1,0,k-1);	  
	  xst    = dmatrix(0,k-1,0,n-1);      
	  xsxs   = dmatrix(0,k-1,0,k-1);
	  A0     = dmatrix(0,k-1,0,k-1);	  
	  A1     = dmatrix(0,m-1,0,m-1);
	  Bp     = dmatrix(0,m-1,0,m-1);
	  Bpt    = dmatrix(0,m-1,0,m-1);
	  xmat	 = dmatrix(0,n-1,0,k-1);
	  W2     = dmatrix(0,m-1,0,m-1);
	  Wmat   = dmatrix(0,m-1,0,m-1);

	   z     = dvector(0,n-1);
	   tvec  = dvector(0,n-1);
	   e     = dvector(0,n-1);
	   e0    = dvector(0,n-1);
	   xb    = dvector(0,n-1);
	   mn    = dvector(0,n-1);
	   ys    = dvector(0,n-1);      
      limit1 = dvector(0,n-1);			
	  limit2 = dvector(0,n-1);
	  zmt	 = dvector(0,n-1);
	  vv	 = dvector(0,n-1);
	  bhat   = dvector(0,k-1);
	  b0     = dvector(0,k-1);
	  b0tmp  = dvector(0,k-1);
	  v      = dvector(0,m-1);
	  b1     = dvector(0,m-1);
	  b1tmp  = dvector(0,m-1);
	  Bpa    = dvector(0,m-1);
	  w1     = dvector(0,m-1);
	  rdet   = dvector(0,ngrid-1);
	  ldet   = dvector(0,ngrid-1);	 
	  Wa     = dvector(0,m-1);
   
// Initializations


    junk = 0.0;  // Placeholder for mean in meanvar()
  	rho = 0.5;  
	sige = 1.0;
	zflag = 0;  // a flag for 0,1 y-values

// Initialize (z,vv,limits,tvec) 

	for(i=0; i<n; i++){
        z[i] = y[i];
		vv[i] = 1.0;
		tvec[i] = 1.0;
	    if (y[i] == 0.0){
			limit1[i] = -10000;
			limit2[i] = 0.0;
			zflag = 1; // we have 0,1 y-values so sample z
	    }else{
			limit1[i] = 0.0;
			limit2[i] = 10000;
		}
	}
        
	
	// Initialize v, b1tmp, Bp


	for(i=0; i<m; i++){
		v[i] = 1.0;
	    b1tmp[i] = 1.0;		                 
        for(j=0; j<m; j++){
              if (j == i){
                 Bp[i][j] = 1 - rho*W[i + j*m];
			  }else{
                 Bp[i][j] = - rho*W[i + j*m];
              }
              Wmat[i][j] = W[i + j*m];
		}
	}


	
	// Parse detval into rdet and ldet vectors 
	//       and define (rmin,rmax)
	
	for(i=0; i<ngrid; i++){
	    j=0;
		rdet[i] = detval[i + j*ngrid];
	    j=1;
		ldet[i] = detval[i + j*ngrid];
	}
	
	rmin = rdet[0];
    rmax = rdet[ngrid-1];  

	
	// Put x into xmat

	for(i=0; i<n; i++){
		for(j=0; j<k; j++)
            xmat[i][j] = x[i + j*n];
	}


	// Compute matrices to be used for updating a-vector

	if(m > 100){  // Used only for large m

		for(i=0; i<m; i++){

			w1[i] = 0.0;							// Form w1[i]
			for(j=0;j<m;j++){
				w1[i] = w1[i] + (W[j + i*m]*W[j + i*m]);
			}

			for(j=0;j<m;j++){						// Form W2[i][*]
				W2[i][j] = 0.0;
				if(j != i){					
					for(l=0;l<m;l++){
						W2[i][j] = W2[i][j] + W[l + i*m]*W[l + j*m];
					}
				}		// Note that W2[i][i] = 0.0 by construction
			}			
		}
	} // End if(m > 10)



// ======================================
// Start the Sampler
// ======================================

	for(iter=0; iter<ndraw; iter++){


// UPDATE: beta

// (1) Apply stnd devs (vsqrt) to x, z, z - tvec
	
	for(i=0; i<n; i++){
		vsqrt = sqrt(vv[i]);
	    zmt[i] = (z[i] - tvec[i])/vsqrt;
		for(j=0; j<k; j++)
			xs[i][j] = x[i + j*n]/vsqrt;
	}
	      

//  (2) Construct A0 matrix


	transpose(xs,n,k,xst);				// form xs'
	  matmat(xst,k,n,xs,k,xsxs);		// form xs'*xs
      for(i=0; i<k; i++){				// form xs'*xs + TI
            for(j=0; j<k; j++)
                 A0[i][j] = xsxs[i][j] + TI[i + j*k];
          }      

      invt = inverse(A0, k);			// replace A0 = inv(A0)
	  if (invt != 1)
		 mexPrintf("semip_gc: Inversion error in beta conditional \n");

// (3) Construct b0 vector

	matvec(xst,k,n,zmt,b0tmp);			//form xs'*zmt
      for(i=0; i<k; i++){
		b0tmp[i] = b0tmp[i] + TIc[i];		//form b0tmp = xs'*zmt + TIc
      }
	matvec(A0,k,k,b0tmp,b0);				//form b0 = A0*b0tmp

// (4) Do multivariate normal draw from N(b0,A0)

	normal_rndc(A0, k, bhat);			// generate N(0,A0) vector
	for(i=0; i<k; i++){
		bhat[i] = bhat[i] + b0[i];		// add mean vector, b0
	}

// (5) Now update related values:


	matvec(xmat,n,k,bhat,xb);			// form xb = xmat*bhat


	for(i=0; i<n; i++){					// form e0 = z - x*bhat
		e0[i] = z[i] - xb[i];	
	}

	cobs = 0;
	for(i=0; i<m; i++){					// form b1tmp = e0i/v[i]
		obsi = mobs[i];
		b1tmp[i] = 0.0;
		for(j=cobs; j<cobs + obsi; j++){
			b1tmp[i] = b1tmp[i] + (e0[j]/v[i]);	
		}
		cobs = cobs + obsi;
	}
	
        

// UPDATE: a 
	
	if(m <= 100){  // For small m use straight inverse

		// (1) Define A1 and b1

		transpose(Bp,m,m,Bpt);			    // form Bp'
		matmat(Bpt,m,m,Bp,m,A1);			// form Bp'*Bp
	
		for(i=0; i<m; i++){					// form A1 = (1/sige)*Bp'Bp + diag(mobs/v)
			for(j=0; j<m; j++){
				if (j == i){
					A1[i][j] = (1/sige)*A1[i][j] + ((double)mobs[i])/v[i];
				}else{
					A1[i][j] = (1/sige)*A1[i][j];
				}
			}
		}
	

		inverse(A1,m);						// set A1 = inv(A1)
	
		matvec(A1,m,m,b1tmp,b1);			// form b1

	
		// (2) Do multivariate normal draw from N(b1,A1)

		normal_rndc(A1,m,a);				// generate N(0,A1) vector
		for(i=0; i<m; i++){
			a[i] = a[i] + b1[i];			// add mean vector, b1
		}

	}else{   // For large m use marginal distributions

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -