/* ========================================================================== scam.c -- a program to run the Haario et al. "SCAM" algorithm Copyright (c) 2007 by Jeffrey S. Rosenthal (jeff@math.toronto.edu). Licensed for general copying, distribution and modification according to the GNU General Public License (http://www.gnu.org/copyleft/gpl.html). ---------------------------------------------------- Compile with "cc scam.c -lm", then run with "a.out". ========================================================================== */ #include #include #include #include #include /* #define NUMITER 500000 */ #define NUMITER 500000 /* #define EMPBAYES true */ /* #define VERBOSE true */ /* #define HYPERVERBOSE true */ /* #define SPEEDUP true */ #define SPEEDUP true #define K 500 /* #define a1 -1 #define a2 -1 */ #define a1 1.0 #define a2 1.0 #define b1 1.0 #define b2 1.0 #define mu0 0.0 #define s0 1.0 #define PRINTLENGTH 100 #define TARGACCEPT 0.44 /* #define TARGACCEPT 0.234 */ #define PI 3.14159265 #define X0FILE "scamx0" #define X1FILE "scamx1" #define X2FILE "scamx2" #define MUFILE "scammu" #define AFILE "scamA" #define VFILE "scamV" #define SG0FILE "scamsg0" #define SG1FILE "scamsg1" #define SG2FILE "scamsg2" #define SGMUFILE "scamsgmu" #define SGAFILE "scamsgA" #define SGVFILE "scamsgV" #define EFILE "scame" #define MASTERFILE "scamm" double drand48(); int r[K]; double mm[K], sd[K]; #define JMAX 1000 double Y[K][JMAX]; main() { int i,j,k,ii, jj, kk, xspacing; int itnum, accepted, acount[K+3]; double t[K+3]; double newt[K+3]; double sigma[K+3], xbar[K+3], g[K+3], newxbar, newg; double sqdiff, logalpha, tmp; double pilogest, pilogsum, logval; double sqnorm(), normal(), targlogdens(), targlogdenscomp(), adaptamount(); double square(); FILE *fpx0, *fpx1, *fpx2, *fpmu, *fpA, *fpV, *fpe, *fpm; FILE *fpsg0, *fpsg1, *fpsg2, *fpsgmu, *fpsgA, *fpsgV; double begintime, endtime, currtime; struct timeval tmptv; /* DATA VALUES */ seedrand(); for (jj=0; jj 0.01) { fprintf(stderr, "\nERROR: t and newt not synchronised.\n\n"); exit(1); } } logval = log(1.0+sqnorm(t)); #ifdef EMPBAYES for (kk=0; kkK-1) ) { fprintf(stderr, "\nERROR: component number out of range!\n\n"); exit(1); } mu = t[K]; A = exp(t[K+1]); V = exp(t[K+2]); #ifdef CAUCHYLEVEL result = - log(A) - square( (t[kk]-mu) / A ); #else /* Usual normal case. */ result = - 0.5 * log(A) - square(t[kk]-mu) / 2.0 / A; #endif for (jj=0; jjn2) return(n1); else return(n2); } /* ADAPTAMOUNT */ double adaptamount( int iteration ) { /* return( 1.0 / imax(100, sqrt(iteration)) ); */ return( min( 0.01, 1.0 / sqrt((double)iteration) ) ); /* return(0.01); */ } /* SEEDRAND: SEED RANDOM NUMBER GENERATOR. */ seedrand() { int i, seed; struct timeval tmptv; gettimeofday (&tmptv, (struct timezone *)NULL); /* seed = (int) (tmptv.tv_usec - 1000000 * (int) ( ((double)tmptv.tv_usec) / 1000000.0 ) ); */ seed = (int) tmptv.tv_usec; srand48(seed); (void)drand48(); /* Spin it once. */ return(0); } /* NORMAL: return a standard normal random number. */ double normal() { double R, theta, drand48(); R = - log(drand48()); theta = 2 * PI * drand48(); return( sqrt(2*R) * cos(theta)); } int divisible (int n1, int n2) { return (n1 == n2 * (n1/n2)); } double square(double xx) { return(xx*xx); }