Annotation of OpenXM/src/hgm/mh/src/wmain.c, Revision 1.23
1.1 takayama 1: /*
1.23 ! takayama 2: $OpenXM: OpenXM/src/hgm/mh/src/wmain.c,v 1.22 2015/03/24 05:59:43 takayama Exp $
1.10 takayama 3: License: LGPL
4: */
1.1 takayama 5: #include <stdio.h>
6: #include <stdlib.h>
7: #include <math.h>
8: #include <string.h>
1.4 takayama 9: #include "sfile.h"
1.11 takayama 10: #include "mh.h"
1.1 takayama 11: #define SMAX 4096
1.22 takayama 12: #define inci(i) { i++; if (i >= argc) { oxprintfe("Option argument is not given.\n"); return(NULL); }}
1.3 takayama 13: int MH_deallocate=0;
14:
1.20 takayama 15: /*
16: changelog
17: 2014.03.15 --strategy 1 is default. A new parser in setParam()
18: */
1.1 takayama 19: extern char *MH_Gfname;
20: extern char *MH_Dfname;
21:
22: /* global variables. They are set in setParam() */
1.4 takayama 23: int MH_byFile=1;
1.1 takayama 24: int MH_RANK;
25: int MH_M;
26:
27: int MH_Mg; /* m */
28: double *MH_Beta; /* beta[0], ..., beta[m-1] */
1.2 takayama 29: double *MH_Ng; /* freedom n. c=(m+1)/2+n/2; Note that it is a pointer */
30: double MH_X0g; /* initial point */
31: static double *Iv; /* Initial values of mhg sorted by mhbase() in rd.rr at beta*x0 */
32: static double Ef; /* exponential factor at beta*x0 */
33: extern double MH_Hg; /* step size of rk defined in rk.c */
34: int MH_Dp; /* Data sampling period */
35: static double Xng=0.0; /* the last point */
36: int MH_RawName = 0;
37: static int Testrank=0;
1.20 takayama 38: /* If MH_success is set to 1, then strategy, MH_abserr, MH_relerr seem to
39: be properly set.
40: */
41: int MH_success=0;
42: /*
43: Estimation of the maximal coeff of A in y'=Ay.
44: This might be too rough estimate.
45: */
46: double MH_coeff_max;
47: /*
48: Estimation of h by MH_coeff_max;
49: */
50: double MH_estimated_start_step;
1.2 takayama 51: extern int MH_Verbose;
1.20 takayama 52: extern int MH_strategy;
53: extern double MH_abserr;
54: extern double MH_relerr;
1.16 takayama 55:
1.2 takayama 56: extern int MH_P95; /* 95 % points */
57: int mh_gopen_file(void);
58: static int setParamTest(void);
59: static int setParamDefault(void);
60: static int setParam(char *fname);
61: static int showParam(void);
1.6 takayama 62: static int next(struct SFILE *fp,char *s, char *msg);
1.20 takayama 63: static double estimateHg(int m, double beta[],double x0);
1.1 takayama 64:
65: /* #define DEBUG */
66: #ifdef DEBUG
1.2 takayama 67: char *MH_Dfname; char *MH_Gfname; double MH_Hg;
68: int mh_gopen_file(void) { }
1.4 takayama 69: struct MH_RESULT mh_rkmain(double x0,double y0[],double xn) { }
1.1 takayama 70: #endif
71:
1.3 takayama 72: void mh_freeWorkArea(void) {
73: extern int MH_deallocate;
74: MH_deallocate=1; /* switch to deallocation mode. */
75: mh_main(0,NULL);
76: setParam(NULL);
77: mh_rkmain(0.0, NULL, 0.0);
78: mh_rf(0.0, NULL, 0, NULL, 0);
79: MH_deallocate=0; /* switch to the normal mode. */
80: }
1.8 takayama 81: static int mypower(int x,int n) {
1.1 takayama 82: int a,i;
83: a = 1;
84: for (i=0; i<n; i++) a = a*x;
85: return(a);
86: }
1.9 takayama 87: #ifdef STANDALONE2
1.1 takayama 88: main(int argc,char *argv[]) {
1.12 takayama 89: int strategy=STRATEGY_DEFAULT;
90: double err[2]={-1.0,-1.0};
91: int i;
1.6 takayama 92: mh_exit(MH_RESET_EXIT); /* standalone mode */
1.10 takayama 93: /* mh_main(argc,argv);
94: mh_freeWorkArea(); */
1.3 takayama 95: mh_main(argc,argv);
1.12 takayama 96: /* showParam(); */
1.18 takayama 97: return(0);
1.2 takayama 98: }
99: #endif
1.4 takayama 100: struct MH_RESULT *mh_main(int argc,char *argv[]) {
1.13 takayama 101: static double *y0=NULL;
1.1 takayama 102: double x0,xn;
103: double ef;
104: int i,rank;
1.4 takayama 105: struct MH_RESULT *rp=NULL;
1.3 takayama 106: extern int MH_deallocate;
1.4 takayama 107: extern int MH_byFile;
108: MH_byFile=1;
109: if (MH_deallocate) { if (y0) mh_free(y0); return(rp); }
1.2 takayama 110: setParam(NULL); MH_Gfname = MH_Dfname = NULL; MH_Verbose=1;
1.1 takayama 111: for (i=1; i<argc; i++) {
1.10 takayama 112: if (strcmp(argv[i],"--idata")==0) {
1.1 takayama 113: inci(i);
1.10 takayama 114: setParam(argv[i]); MH_Verbose=0;
115: }else if (strcmp(argv[i],"--gnuplotf")==0) {
1.1 takayama 116: inci(i);
1.10 takayama 117: MH_Gfname = (char *)mh_malloc(SMAX);
118: strcpy(MH_Gfname,argv[i]);
119: }else if (strcmp(argv[i],"--dataf")==0) {
120: inci(i);
121: MH_Dfname = (char *)mh_malloc(SMAX);
122: strcpy(MH_Dfname,argv[i]);
123: }else if (strcmp(argv[i],"--xmax")==0) {
124: inci(i);
125: sscanf(argv[i],"%lf",&Xng);
126: }else if (strcmp(argv[i],"--step")==0) {
127: inci(i);
128: sscanf(argv[i],"%lg",&MH_Hg);
129: }else if (strcmp(argv[i],"--help")==0) {
130: mh_usage(); return(rp);
131: }else if (strcmp(argv[i],"--raw")==0) {
132: MH_RawName = 1;
133: }else if (strcmp(argv[i],"--test")==0) {
134: inci(i);
135: sscanf(argv[i],"%d",&Testrank);
136: setParamTest();
137: }else if (strcmp(argv[i],"--95")==0) {
138: MH_P95=1;
139: }else if (strcmp(argv[i],"--verbose")==0) {
140: MH_Verbose=1;
141: }else if (strcmp(argv[i],"--bystring")==0) {
142: MH_byFile = 0;
1.20 takayama 143: }else if (strcmp(argv[i],"--strategy")==0) {
144: i++; sscanf(argv[i],"%d",&MH_strategy);
145: }else if (strcmp(argv[i],"--abserr")==0) {
146: i++; sscanf(argv[i],"%lg",&MH_abserr);
147: }else if (strcmp(argv[i],"--relerr")==0) {
148: i++; sscanf(argv[i],"%lg",&MH_relerr);
1.10 takayama 149: }else {
1.22 takayama 150: oxprintfe("Unknown option %s\n",argv[i]);
1.10 takayama 151: mh_usage();
152: return(rp);
153: }
1.1 takayama 154: }
1.2 takayama 155: x0 = MH_X0g;
1.1 takayama 156: xn = Xng;
157: ef = Ef;
158: rank = mypower(2,MH_Mg);
1.2 takayama 159: y0 = (double *) mh_malloc(sizeof(double)*rank);
1.1 takayama 160: for (i=0; i<rank; i++) y0[i] = ef*Iv[i];
1.2 takayama 161: mh_gopen_file();
1.20 takayama 162: rp = (struct MH_RESULT*) mh_malloc(sizeof(struct MH_RESULT));
163:
164: if (MH_strategy) {
165: if (MH_abserr > SIGDIGIT_DEFAULT*myabs(y0[0])) {
166: MH_success = 0;
1.22 takayama 167: oxprintfe("%%%%Warning, abserr seems not to be small enough, abserr=%lg, y[0]=%lg\n",MH_abserr,y0[0]);
1.20 takayama 168: }else{
169: MH_success = 1;
170: }
171: }else{
172: MH_success = 0;
173: }
174: MH_estimated_start_step = estimateHg(MH_Mg,MH_Beta,MH_X0g);
175: if (MH_Verbose) showParam();
1.22 takayama 176: if (MH_Verbose) {for (i=0; i<rank; i++) oxprintf("%lf\n",y0[i]); }
1.19 takayama 177:
1.4 takayama 178: *rp=mh_rkmain(x0,y0,xn);
179: return(rp);
1.1 takayama 180: }
181:
1.8 takayama 182: int mh_usage() {
1.22 takayama 183: oxprintfe("Usages:\n");
184: oxprintfe("hgm_w-n [--idata input_data_file --gnuplotf gnuplot_file_name\n");
185: oxprintfe(" --dataf output_data_file --raw --xmax xmax --test m --step h]\n");
186: oxprintfe("[ --95 --verbose] \n");
187: oxprintfe("[ --strategy s --abserr ae --relerr re] \n");
188: oxprintfe("s:0 rk, s:1 adaptive, s:2 adaptive&multiply, see rk.c for the default value of ae and re.\n");
189: oxprintfe("strategy default = %d\n",MH_strategy);
190: oxprintfe("--raw does not add data parameters to the output_data_file.\n");
191: oxprintfe("\nThe command hgm_w-n [options] evaluates Pr({y | y<xmax}), which is the cumulative distribution function of the largest root of the m by m Wishart matrix with n degrees of freedom and the covariantce matrix sigma.\n");
192: oxprintfe("All the eigenvalues of sigma must be simple.\n");
193: oxprintfe("Parameters are specified by the input_data_file.\n");
194: oxprintfe("Parameters are redefined when they appear more than once in the idata file and the command line options.\n");
195: oxprintfe("The format of the input_data_file, which should be generated by the command hgm_jack-n.\n");
196: oxprintfe(" MH_Mg: m, MH_Beta: beta=sigma^(-1)/2 (diagonized), MH_Ng: n, MH_X0g: starting value of x,\n");
197: oxprintfe(" Iv: initial values at MH_X0g*MH_Beta (see our paper how to order them), \n");
198: oxprintfe(" Ef: a scalar factor to the initial value. It may set to 1.\n");
199: oxprintfe(" MH_Hg: h (step size),\n");
200: oxprintfe(" MH_Dp: output data is stored in every MH_Dp steps when output_data_file is specified.\n");
201: oxprintfe(" Xng: terminating value of x.\n\n");
202: oxprintfe("--95: output the 95%% point. --verbose: verbose mode.\n");
203: oxprintfe("The line started with %%%% or # is a comment line.\n");
204: oxprintfe("An example format of the input_data_file can be obtained by executing hgm_jack-n with no option.\n");
205: oxprintfe("When --idata option is used, this command is quiet. Use --verbose option if you want to see some messages.\n");
206: oxprintfe("\nExamples:\n");
207: oxprintfe("[1] ./hgm_w-n \n");
208: oxprintfe("[2] ./hgm_w-n --xmax 20\n");
209: oxprintfe("[3] ./hgm_w-n --test 6\n");
210: oxprintfe(" A test run in Mg=6.\n");
211: oxprintfe("[4] ./hgm_jack-n --idata Testdata/tmp-idata3.txt >t.txt\n");
212: oxprintfe(" ./hgm_w-n --idata t.txt --gnuplotf test-g --verbose\n");
213: oxprintfe(" gnuplot -persist <test-g-gp.txt\n");
214: oxprintfe(" tmp-idata3.txt is a sample input data distributed with this file.\n");
215: oxprintfe(" test-g-gp.txt is an input file of the gnuplot\n");
1.23 ! takayama 216: oxprintfe(" test-g is the table of x and the values of Pr({y | y<x}).\n"); return(0);
1.1 takayama 217: }
218:
1.8 takayama 219: static int setParamTest() {
1.1 takayama 220: int rank;
221: int i;
222: extern int Testrank;
1.2 takayama 223: extern int MH_Verbose;
224: MH_Verbose=1;
1.1 takayama 225: MH_M= MH_Mg = Testrank ;
226: MH_RANK = rank = mypower(2,MH_Mg);
1.2 takayama 227: MH_Beta = (double *)mh_malloc(sizeof(double)*MH_Mg);
1.1 takayama 228: for (i=0; i<MH_Mg; i++) MH_Beta[i] = 1.0+0.1*i;
1.2 takayama 229: MH_Ng = (double *)mh_malloc(sizeof(double)); *MH_Ng = 3.0;
230: Iv = (double *)mh_malloc(sizeof(double)*rank);
1.1 takayama 231: for (i=0; i<rank; i++) Iv[i] = 0;
232: Iv[0] = 0.001;
233: Ef = 1;
1.2 takayama 234: MH_X0g = 0.3;
235: MH_Hg = 0.001;
236: MH_Dp = 1;
1.23 ! takayama 237: Xng = 10.0; return(0);
1.1 takayama 238: }
1.8 takayama 239: static int setParamDefault() {
1.1 takayama 240: int rank;
241: MH_M=MH_Mg = 2 ;
242: MH_RANK=rank = mypower(2,MH_Mg);
1.2 takayama 243: MH_Beta = (double *)mh_malloc(sizeof(double)*MH_Mg);
1.1 takayama 244: MH_Beta[0] = 1.0; MH_Beta[1] = 2.0;
1.2 takayama 245: MH_Ng = (double *)mh_malloc(sizeof(double)); *MH_Ng = 3.0;
246: Iv = (double *)mh_malloc(sizeof(double)*rank);
1.1 takayama 247: Iv[0] = 1.58693;
248: Iv[1] = 0.811369;
249: Iv[2] = 0.846874;
250: Iv[3] = 0.413438;
251: Ef = 0.01034957388338225707;
1.2 takayama 252: MH_X0g = 0.3;
253: MH_Hg = 0.001;
254: MH_Dp = 1;
1.23 ! takayama 255: Xng = 10.0; return(0);
1.1 takayama 256: }
257:
1.8 takayama 258: static int next(struct SFILE *sfp,char *s,char *msg) {
1.1 takayama 259: s[0] = '%';
260: while (s[0] == '%') {
1.10 takayama 261: if (!mh_fgets(s,SMAX,sfp)) {
1.22 takayama 262: oxprintfe("Data format error at %s\n",msg);
1.10 takayama 263: mh_exit(-1);
264: }
265: if (s[0] != '%') return(0);
1.23 ! takayama 266: } return(0);
1.1 takayama 267: }
1.8 takayama 268: static int setParam(char *fname) {
1.1 takayama 269: int rank;
270: char s[SMAX];
1.4 takayama 271: struct SFILE *fp;
1.1 takayama 272: int i;
1.20 takayama 273: struct mh_token tk;
1.3 takayama 274: extern int MH_deallocate;
1.4 takayama 275: extern int MH_byFile;
1.3 takayama 276: if (MH_deallocate) {
1.10 takayama 277: if (MH_Beta) mh_free(MH_Beta);
278: if (MH_Ng) mh_free(MH_Ng);
279: if (Iv) mh_free(Iv);
280: return(0);
1.3 takayama 281: }
1.1 takayama 282: if (fname == NULL) return(setParamDefault());
283:
1.4 takayama 284: if ((fp=mh_fopen(fname,"r",MH_byFile)) == NULL) {
1.22 takayama 285: oxprintfe("File %s is not found.\n",fname);
1.10 takayama 286: mh_exit(-1);
1.1 takayama 287: }
288: next(fp,s,"MH_Mg(m)");
289: sscanf(s,"%d",&MH_Mg); MH_M=MH_Mg;
290: MH_RANK=rank = mypower(2,MH_Mg);
291:
1.2 takayama 292: MH_Beta = (double *)mh_malloc(sizeof(double)*MH_Mg);
1.1 takayama 293: for (i=0; i<MH_Mg; i++) {
294: next(fp,s,"MH_Beta");
1.10 takayama 295: sscanf(s,"%lf",&(MH_Beta[i]));
1.1 takayama 296: }
297:
1.2 takayama 298: MH_Ng = (double *)mh_malloc(sizeof(double));
299: next(fp,s,"MH_Ng(freedom parameter n)");
300: sscanf(s,"%lf",MH_Ng);
1.1 takayama 301:
1.2 takayama 302: next(fp,s,"MH_X0g(initial point)");
303: sscanf(s,"%lf",&MH_X0g);
1.1 takayama 304:
1.2 takayama 305: Iv = (double *)mh_malloc(sizeof(double)*rank);
1.1 takayama 306: for (i=0; i<rank; i++) {
1.10 takayama 307: next(fp,s,"Iv(initial values)");
308: sscanf(s,"%lg",&(Iv[i]));
1.1 takayama 309: }
310:
311: next(fp,s,"Ef(exponential factor)");
312: sscanf(s,"%lg",&Ef);
313:
1.2 takayama 314: next(fp,s,"MH_Hg (step size of rk)");
315: sscanf(s,"%lg",&MH_Hg);
1.1 takayama 316:
1.2 takayama 317: next(fp,s,"MH_Dp (data sampling period)");
318: sscanf(s,"%d",&MH_Dp);
1.1 takayama 319:
320: next(fp,s,"Xng (the last point, cf. --xmax)");
321: sscanf(s,"%lf",&Xng);
1.20 takayama 322:
323: /* Reading the optional parameters */
324: while ((tk = mh_getoken(s,SMAX-1,fp)).type != MH_TOKEN_EOF) {
325: /* expect ID */
326: if (tk.type != MH_TOKEN_ID) {
1.22 takayama 327: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 328: }
329: if ((strcmp(s,"abserr")==0) || (strcmp(s,"abserror")==0)) {
330: if (mh_getoken(s,SMAX-1,fp).type != MH_TOKEN_EQ) {
1.22 takayama 331: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 332: }
333: if ((tk=mh_getoken(s,SMAX-1,fp)).type != MH_TOKEN_DOUBLE) {
1.22 takayama 334: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 335: }
336: MH_abserr = tk.dval;
337: continue;
338: }
339: if ((strcmp(s,"relerr")==0) || (strcmp(s,"relerror")==0)) {
340: if (mh_getoken(s,SMAX-1,fp).type != MH_TOKEN_EQ) {
1.22 takayama 341: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 342: }
343: if ((tk=mh_getoken(s,SMAX-1,fp)).type != MH_TOKEN_DOUBLE) {
1.22 takayama 344: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 345: }
346: MH_relerr = tk.dval;
347: continue;
348: }
349: if (strcmp(s,"strategy")==0) {
350: if (mh_getoken(s,SMAX-1,fp).type != MH_TOKEN_EQ) {
1.22 takayama 351: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 352: }
353: if ((tk=mh_getoken(s,SMAX-1,fp)).type != MH_TOKEN_INT) {
1.22 takayama 354: oxprintfe("Syntax error at %s\n",s); mh_exit(-1);
1.20 takayama 355: }
356: MH_strategy = tk.ival;
357: continue;
358: }
1.22 takayama 359: oxprintfe("Unknown ID at %s\n",s); mh_exit(-1);
1.20 takayama 360: }
361:
1.23 ! takayama 362: mh_fclose(fp); return(0);
1.1 takayama 363: }
364:
1.20 takayama 365: static int showParam() {
1.1 takayama 366: int rank,i;
1.12 takayama 367: extern int MH_strategy;
368: extern double MH_abserr;
369: extern double MH_relerr;
1.1 takayama 370: rank = mypower(2,MH_Mg);
1.22 takayama 371: oxprintf("%%MH_Mg=\n%d\n",MH_Mg);
1.1 takayama 372: for (i=0; i<MH_Mg; i++) {
1.22 takayama 373: oxprintf("%%MH_Beta[%d]=\n%lf\n",i,MH_Beta[i]);
1.1 takayama 374: }
1.22 takayama 375: oxprintf("%%MH_Ng=\n%lf\n",*MH_Ng);
376: oxprintf("%%MH_X0g=\n%lf\n",MH_X0g);
1.1 takayama 377: for (i=0; i<rank; i++) {
1.22 takayama 378: oxprintf("%%Iv[%d]=\n%lg\n",i,Iv[i]);
1.1 takayama 379: }
1.22 takayama 380: oxprintf("%%Ef=\n%lf\n",Ef);
381: oxprintf("%%MH_Hg=\n%lf\n",MH_Hg);
382: oxprintf("%%MH_Dp=\n%d\n",MH_Dp);
383: oxprintf("%%Xng=\n%lf\n",Xng);
384: oxprintf("%%strategy=%d\n",MH_strategy);
385: oxprintf("%%abserr=%lg, %%relerr=%lg\n",MH_abserr,MH_relerr);
386: oxprintf("#MH_success=%d\n",MH_success);
387: oxprintf("#MH_coeff_max=%lg\n",MH_coeff_max);
1.23 ! takayama 388: oxprintf("#MH_estimated_start_step=%lg\n",MH_estimated_start_step); return(0);
1.1 takayama 389: }
390:
1.20 takayama 391: static double estimateHg(int m, double beta[],double x0) {
392: int i,j;
393: double dmin;
394: double cmax;
395: double h;
396: /* mynote on 2014.03.15 */
397: if (m>1) dmin = myabs(beta[1]-beta[0]);
398: else dmin=myabs(beta[0]);
399: for (i=0; i<m; i++) {
400: for (j=i+1; j<m; j++) {
401: if (myabs(beta[i]-beta[j]) < dmin) dmin = myabs(beta[i]-beta[j]);
402: }
403: }
404: dmin = dmin*x0*2;
405: cmax = 1.0;
406: for (i=0; i<m; i++) cmax = cmax*dmin;
407: cmax = 1.0/cmax;
408: MH_coeff_max=cmax;
409: h = exp(log(MH_abserr/cmax)/5.0);
410: MH_estimated_start_step = h;
411: return h;
412: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>