[BACK]Return to call_phc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / C

Annotation of OpenXM_contrib/PHC/C/call_phc.c, Revision 1.1.1.1

1.1       maekawa     1: /* This is a simple C interface to the black-box solver of phc,
                      2: ** written by Nobuki Takayama.
                      3: ** Requirements:
                      4: **  1) executable version of phc must be on /tmp;
                      5: **  2) user of this program has write permissions to create
                      6: **     the files "input" and "output" in the directory where
                      7: **     this program is executed.
                      8: */
                      9:
                     10: #include <stdio.h>
                     11: #include <sys/stat.h>
                     12: #include <unistd.h>
                     13:
                     14: /* Definition of class identifiers. */
                     15: #define SstringObject     5
                     16: #define Sarray            6
                     17:
                     18: /* Definition of Object */
                     19: union cell {
                     20:   int ival;
                     21:   char *str;
                     22:   struct object *op;
                     23: };
                     24: struct object{
                     25:   int tag;                /* class identifier */
                     26:   union cell lc;          /* left cell */
                     27:   union cell rc;          /* right cell */
                     28: };
                     29:
                     30: /* Memory allocation function.
                     31:    I recommend not to use malloc and to use gc4.14 for large applications. */
                     32: #define sGC_malloc(n)   malloc(n)
                     33:
                     34: /********** macros to use Sarray **************/
                     35: /* put to Object Array */
                     36: #define phc_putoa(ob,i,cc) {\
                     37: if ((ob).tag != Sarray) {fprintf(stderr,"Warning: PUTOA is for an array of objects\n");} else \
                     38: {if ((0 <= (i)) && ((i) < (ob).lc.ival)) {\
                     39:   (ob.rc.op)[i] = cc;\
                     40: }else{\
                     41:   fprintf(stderr,"Warning: PUTOA, the size is %d.\n",(ob).lc.ival);\
                     42: }}}
                     43: #define phc_getoa(ob,i) ((ob.rc.op)[i])
                     44: #define phc_getoaSize(ob) ((ob).lc.ival)
                     45:
                     46:
                     47: /* prototypes */
                     48: struct object phc_newObjectArray(int size);
                     49: void phc_printObject(FILE *fp,struct object ob);
                     50: char *phc_generateUniqueFileName(char *s);
                     51: struct object phc_complexTo(long double r, long double i);
                     52: struct object phc_longdoubleToStringObject(long double r);
                     53:
                     54: int phc_scan_for_string(FILE *fp, char str[], int lenstr);
                     55: struct object phc_scan_solutions(FILE *fp, int npaths, int dim );
                     56: struct object phc_scan_output_of_phc(char *fname);
                     57: struct object phc_call_phc(char *sys);
                     58:
                     59: main() {
                     60:   struct object ob;
                     61:   ob = phc_call_phc("2\n x**2 + y**2 - 1;\n x**2 + y**2 - 8*x - 3;\n");
                     62:   printf("-----------------------------------------------------------\n");
                     63:   phc_printObject(stdout,ob);
                     64:   printf("\n");
                     65: }
                     66:
                     67: int phc_scan_for_string(FILE *fp, char str[], int lenstr)
                     68:      /*
                     69:   **  Scans the file fp for a certain string str of length lenstr+1.
                     70:   **  Reading stops when the string has been found, then the variable
                     71:   **  on return equals 1, otherwise 0 is returned.
                     72:   */
                     73: {
                     74:   char buf[lenstr+1];
                     75:   char ch;
                     76:   int index,i,compare,npaths,dim,found;
                     77:   index = -1;
                     78:   found = 0;
                     79:   while ((fscanf(fp,"%c",&ch)!=EOF) && found == 0)
                     80:     {
                     81:       if (index == -1 && ch == str[0])
                     82:        {
                     83:          index = 0;
                     84:          buf[index] = ch;
                     85:        }
                     86:       else
                     87:        {
                     88:          if (index == lenstr)
                     89:            {
                     90:              compare = 0;
                     91:              for (i=0; i<lenstr+1; i++)
                     92:                {
                     93:                  if (buf[i]!=str[i])
                     94:                    {
                     95:                      compare = compare+1;
                     96:                    }
                     97:                }
                     98:              if (compare == 0)
                     99:                {
                    100:                  found = 1;
                    101:                }
                    102:              index = -1;
                    103:            }
                    104:          else
                    105:            if (index > -1 && index < lenstr)
                    106:              {
                    107:                index = index+1;
                    108:                buf[index] = ch;
                    109:              }
                    110:        }
                    111:       if (found == 1) break;
                    112:     }
                    113:   return found;
                    114: }
                    115: struct object phc_scan_solutions(FILE *fp, int npaths, int dim )
                    116:      /*
                    117:   **  Scans the file for the solutions, from a list of length npaths,
                    118:   **  of complex vectors with dim entries.
                    119:   **  The tolerance for the residual to a solution is set to 1.0E-12.
                    120:   **  Returns the number of solutions.
                    121:   */
                    122: {
                    123:   struct object rob,sob;
                    124:   char ch;
                    125:   int fnd,i,j,nsols;
                    126:   float res;
                    127:   long double realpart;
                    128:   long double imagpart;
                    129:   long double realparts[npaths][dim];
                    130:   long double imagparts[npaths][dim];
                    131:   nsols = 0;
                    132:   while (fscanf(fp,"%c",&ch)!=EOF)
                    133:     {
                    134:       fnd = phc_scan_for_string(fp,"start residual :",15);
                    135:       if (fnd==1)
                    136:        {
                    137:          fscanf(fp,"%E",&res);
                    138:          /* printf(" residual = "); printf("%E\n",res); */
                    139:          if (res < 1.0E-12) nsols = nsols+1;
                    140:          fnd = phc_scan_for_string(fp,"the solution for t :",19);
                    141:          for (i=0;i<dim;i++)
                    142:            {
                    143:              fnd = phc_scan_for_string(fp,":",0);
                    144:              fscanf(fp,"%LE",&realpart);
                    145:              fscanf(fp,"%LE",&imagpart);
                    146:              if (res < 1.0E-12)
                    147:                {
                    148:                  realparts[nsols-1][i] = realpart;
                    149:                  imagparts[nsols-1][i] = imagpart;
                    150:                }
                    151:            }
                    152:        }
                    153:     }
                    154:   /* fprintf(stderr,"  number of solutions = %i\n",nsols); */
                    155:   rob = phc_newObjectArray(nsols);
                    156:   for (i=0;i<nsols;i++)
                    157:     {
                    158:       /* fprintf(stderr,"Solution %i :\n",i+1); */
                    159:       sob = phc_newObjectArray(dim);
                    160:       for (j=0;j<dim;j++)
                    161:        {
                    162:          /*
                    163:          printf("%20.14LE",realparts[i][j]); printf("  ");
                    164:          printf("%20.14LE",imagparts[i][j]); printf("\n");
                    165:          */
                    166:          phc_putoa(sob,j,phc_complexTo(realparts[i][j],imagparts[i][j]));
                    167:        }
                    168:       phc_putoa(rob,i,sob);
                    169:     }
                    170:   return(rob);
                    171: }
                    172: struct object phc_scan_output_of_phc(char *fname)
                    173:      /*
                    174:   **  Scans the file "output" of phc in two stages to get
                    175:   **   1) the number of paths and the dimension;
                    176:   **   2) the solutions, vectors with residuals < 1.0E-12.
                    177:   */
                    178: {
                    179:   FILE *otp;
                    180:   char ch;
                    181:   int fnd,npaths,dim,i,nsols;
                    182:   otp = fopen(fname,"r");
                    183:   fprintf(stderr,"Scanning the %s of phc.\n",fname);
                    184:   fnd = phc_scan_for_string(otp,"THE SOLUTIONS :",14);
                    185:   fscanf(otp,"%i",&npaths);
                    186:   fprintf(stderr,"  number of paths traced = %i\n",npaths);
                    187:   fscanf(otp,"%i",&dim);
                    188:   fprintf(stderr,"  dimension of solutions = %i\n",dim);
                    189:   return(phc_scan_solutions(otp,npaths,dim));
                    190: }
                    191: struct object phc_call_phc(char *sys)  /* call phc, system as string */
                    192: {
                    193:   FILE *inp;
                    194:   char *f,*outf;
                    195:   char cmd[1024];
                    196:   f = phc_generateUniqueFileName("tmp.input");
                    197:   outf = phc_generateUniqueFileName("tmp.output");
                    198:   fprintf(stderr,"Creating file with name %s.\n",f);
                    199:   inp = fopen(f,"w");
                    200:   fprintf(inp,sys);
                    201:   fclose(inp);
                    202:   sprintf(cmd,"/tmp/phc -b %s %s",f,outf);
                    203:   fprintf(stderr,"Calling %s, black-box solver of phc.\n",cmd);
                    204:   system(cmd);
                    205:   fprintf(stderr,"See the file %s for results.\n",outf);
                    206:   return(phc_scan_output_of_phc(outf));
                    207: }
                    208:
                    209:
                    210: struct object phc_newObjectArray(size)
                    211: int size;
                    212: {
                    213:   struct object rob;
                    214:   struct object *op;
                    215:   if (size > 0) {
                    216:     op = (struct object *)sGC_malloc(size*sizeof(struct object));
                    217:     if (op == (struct object *)NULL) {fprintf(stderr,"No memory\n");exit(1);}
                    218:   }else{
                    219:     op = (struct object *)NULL;
                    220:   }
                    221:   rob.tag = Sarray;
                    222:   rob.lc.ival = size;
                    223:   rob.rc.op = op;
                    224:   return(rob);
                    225: }
                    226:
                    227: void phc_printObject(FILE *fp,struct object ob)
                    228: {
                    229:   int n,i;
                    230:   if (ob.tag == SstringObject) {
                    231:     fprintf(fp,"%s",ob.lc.str);
                    232:   }else if (ob.tag == Sarray) {
                    233:     n = phc_getoaSize(ob);
                    234:     fprintf(fp,"[");
                    235:     for (i=0; i<n; i++) {
                    236:       phc_printObject(fp,phc_getoa(ob,i));
                    237:       if (i <n-1) fprintf(fp,", ");
                    238:     }
                    239:     fprintf(fp,"]");
                    240:   }else{
                    241:     fprintf(stderr,"Unknown object tag %d",ob.tag);
                    242:   }
                    243: }
                    244:
                    245:
                    246: char *phc_generateUniqueFileName(char *s)
                    247: {
                    248:   char *t;
                    249:   int i;
                    250:   struct stat statbuf;
                    251:   t = (char *)sGC_malloc(sizeof(char)*strlen(s)+4+2);
                    252:   for (i=0; i<1000; i++) {
                    253:     /* Give up if we failed for 1000 names. */
                    254:     sprintf(t,"%s.%d",s,i);
                    255:     if (stat(t,&statbuf) < 0) {
                    256:       return(t);
                    257:     }
                    258:   }
                    259:   fprintf(stderr,"Could not generate a unique file name.");
                    260:   return(NULL);
                    261: }
                    262:
                    263: struct object phc_longdoubleToStringObject(long double r)
                    264: {
                    265:   struct object rob;
                    266:   rob.tag = SstringObject;
                    267:   rob.lc.str = (char *) sGC_malloc(sizeof(char)*50); /*??*/
                    268:   sprintf(rob.lc.str,"%20.14LE",r);
                    269:   return(rob);
                    270: }
                    271:
                    272: struct object phc_complexTo(long double r, long double i)
                    273: {
                    274:   struct object rob;
                    275:   rob = phc_newObjectArray(2);
                    276:   phc_putoa(rob,0,phc_longdoubleToStringObject(r));
                    277:   phc_putoa(rob,1,phc_longdoubleToStringObject(i));
                    278:   return(rob);
                    279: }
                    280:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>