/* phc6.c , yama:1999/sm1-prog/phc6.c */ /* $OpenXM: OpenXM/src/phc/phc6.c,v 1.5 2002/05/02 11:54:33 takayama Exp $ */ /* This is a simple C interface to the black-box solver of phc. ** Requirements: ** 1) executable version of phc will be searched in the following order: ** OpenXM_HOME/bin/, /usr/local/bin/phc, /tmp/phc, your command search path. ** Here, PHC_LIBDIR is an environment variable. ** 2) user of this program has write permissions to create ** the files "tmp.input.xx" and "tmp.output.xx" in the directory where ** this program is executed. xx are numbers. */ #include #include #include #include /* Definition of class identifiers. */ #define Snull 0 #define SstringObject 5 #define Sarray 6 #define SlongdoubleComplex 601 /* Definition of Object */ union cell { int ival; char *str; struct phc_object *op; double longdouble; }; struct phc_object{ int tag; /* class identifier */ union cell lc; /* left cell */ union cell rc; /* right cell */ }; /* Memory allocation function. Use your favorite memory allocation function. I recommend not to use malloc and to use gc4.14 for large applications. */ #define sGC_malloc(n) malloc(n) /********** macros to use Sarray **************/ /* put to Object Array */ #define phc_putoa(ob,i,cc) {\ if ((ob).tag != Sarray) {fprintf(stderr,"Warning: PUTOA is for an array of objects\n");} else \ {if ((0 <= (i)) && ((i) < (ob).lc.ival)) {\ (ob.rc.op)[i] = cc;\ }else{\ fprintf(stderr,"Warning: PUTOA, the size is %d.\n",(ob).lc.ival);\ }}} #define phc_getoa(ob,i) ((ob.rc.op)[i]) #define phc_getoaSize(ob) ((ob).lc.ival) /* prototypes */ struct phc_object phc_newObjectArray(int size); void phc_printObject(FILE *fp,struct phc_object ob); char *phc_generateUniqueFileName(char *s); char *phc_which(char *s); /* search a path for the file s */ struct phc_object phc_complexTo(double r, double i); int phc_scan_for_string(FILE *fp, char str[]); struct phc_object phc_scan_solutions(FILE *fp, int npaths, int dim ); struct phc_object phc_scan_output_of_phc(char *fname); struct phc_object phc_call_phc(char *sys); int phc_verbose = 0; int phc_overwrite = 1; /* Always use tmp.input.0 and tmp.output.0 for work files. */ main(int argc, char *argv[]) { struct phc_object ob; int n,i,dim; #define INPUTSIZE 4096 char input[INPUTSIZE]; char fname[INPUTSIZE]; #define A_SIZE 1024 char a[A_SIZE]; int message = 0; for (i=1; i= INPUTSIZE) { fprintf(stderr,"Too big input for the input buffer input.\n"); exit(10); } sprintf(input+strlen(input),"%s\n",a); } ob = phc_call_phc(input); if (message) { printf("-----------------------------------------------------------\n"); } n = phc_getoaSize(ob); printf("[\n"); for (i=0; i BUF_SIZE-2) { fprintf(stderr,"Too long string for scan_for_string.\n"); exit(1); } for (i=0; i= BUF_SIZE-1) { fprintf(stderr,"Too long string in phc_scan_for_string\n"); exit(-1); } index = -1; found = 0; while (((ch = fgetc(fp))!=EOF) && found == 0) { if (index == -1 && ch == str[0]) { index = 0; buf[index] = ch; } else { if (index == lenstr) { compare = 0; for (i=0; str[i] != '\0'; i++) { if (buf[i]!=str[i]) { compare = compare+1; } } if (compare == 0) { found = 1; } index = -1; } else if (index > -1 && index < lenstr) { index = index+1; buf[index] = ch; } } if (found == 1) break; } return found; } struct phc_object phc_scan_solutions(FILE *fp, int npaths, int dim ) /* ** Scans the file for the solutions, from a list of length npaths, ** of complex vectors with dim entries. ** The tolerance for the residual to a solution is set to 1.0E-12. ** Returns solutions. */ #define BUFSIZE 1024 { struct phc_object rob,sob; char ch; int fnd,i,j,nsols; double res; double realpart; double imagpart; /* double realparts[npaths][dim]; double imagparts[npaths][dim]; */ double *realparts; double *imagparts; char buf[BUFSIZE]; nsols = 0; realparts = (double *)sGC_malloc(sizeof(double)*(npaths*dim+1)); imagparts = (double *)sGC_malloc(sizeof(double)*(npaths*dim+1)); while ((ch = fgetc(fp)) != EOF) { fnd = phc_scan_for_string(fp,"start residual :"); if (fnd==1) { fgets(buf,BUFSIZE-1,fp); sscanf(buf,"%le",&res); if (phc_verbose) { fprintf(stderr,"res in string: %s\n",buf); fprintf(stderr," residual = "); fprintf(stderr,"%le\n",res); } if (res < 1.0E-12) { nsols = nsols+1; if (nsols > npaths) { fprintf(stderr,"Something is wrong in phc_scan_solutions\n"); fprintf(stderr,"npaths=%d, nsols=%d \n",npaths,nsols); exit(-1); } } fnd = phc_scan_for_string(fp,"the solution for t :"); for (i=0;i 0) { op = (struct phc_object *)sGC_malloc(size*sizeof(struct phc_object)); if (op == (struct phc_object *)NULL) {fprintf(stderr,"No memory\n");exit(1);} }else{ op = (struct phc_object *)NULL; } rob.tag = Sarray; rob.lc.ival = size; rob.rc.op = op; return(rob); } void phc_printObject(FILE *fp,struct phc_object ob) { int n,i; if (ob.tag == Snull) { fprintf(fp,"null"); }else if (ob.tag == SstringObject) { fprintf(fp,"%s",ob.lc.str); }else if (ob.tag == Sarray) { n = phc_getoaSize(ob); fprintf(fp,"["); for (i=0; i