home *** CD-ROM | disk | FTP | other *** search
- /*
- * Report file generation utility code.
- * See report.doc for more info.
- *
- * (C)1998-1999 Peter Bengtsson
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <GAP.h>
-
- #include "report.h"
-
- static const char * const exts[REPFILES] = {
- "avg",
- "med",
- "typ",
- "max",
- "min",
- "dev"
- };
-
- static const char * const descs[REPFILES] = {
- "Average",
- "Median",
- "TypeCount",
- "Max",
- "Min",
- "StdDev"
- };
-
- struct Report *MakeReport(char *,struct TagItem *);
- void DoReport(struct Report *,struct Population *,unsigned int);
- void EndReport(struct Report *rs);
-
- struct Report *MakeReport(char *basename,struct TagItem *TagList)
- {
- struct Report *rs;
- char *buf=NULL;
- int i;
- Tag tag=TAG_DONE;
-
- rs = malloc(sizeof(struct Report));
-
- rs->flags=0;
- rs->gencount=0;
-
- for(i=0;i!=REPFILES;i++) {
- rs->vbuffer[i]=NULL;
- rs->cbuffer[i] = 0;
- }
-
- i=0;
-
- if(rs!=0) {
-
- if(TagList!=NULL) {
- tag = TagList[0].ti_Tag;
- }
-
- while(tag!=TAG_DONE) {
-
- switch(tag) {
-
- case REP_Generations:
- rs->gencount = TagList[i].ti_Data;
- break;
-
- case REP_Multipass:
- rs->flags &= ~RFLG_MPASS;
- if(TagList[i].ti_Data!=FALSE) {
- rs->flags |= RFLG_MPASS;
- }
- break;
-
- default:
- fprintf(stderr,"MakeReport: Unrecognized tag 0x%08lx.\n",tag);
- }
-
- tag = TagList[++i].ti_Tag;
- }
-
- if((rs->flags&RFLG_MPASS) && rs->gencount==0) {
- fprintf(stderr,"MakeReport: Multipass mode selected but number of generations undeclared.\nDisabling multipass mode.\n");
- rs->flags &= ~RFLG_MPASS;
- }
-
- if(basename!=NULL) {
- buf = malloc((strlen(basename)+8)*sizeof(char));
- rs->basename = malloc((strlen(basename)+1)*sizeof(char));
- strcpy(rs->basename,basename);
-
- if(rs!=NULL && rs->basename!=NULL && buf!=NULL) {
- for(i=0;i!=REPFILES;i++) {
- sprintf(buf,"%s.%s",basename,exts[i]);
- if((rs->files[i]=fopen(buf,"wb"))==NULL) {
- while(--i>=0) {
- fclose(rs->files[i]);
- }
- free(rs->basename);
- free(rs);
- rs = NULL;
- fprintf(stderr,"MakeReport: Error opening files for writing.\n");
- }
- rs->used[i]=0;
- fprintf(rs->files[i],"# Generation, %s\n",descs[i]);
- }
- } else {
- if(rs!=NULL) {
- if(rs->basename!=NULL) {
- free(rs->basename);
- }
- free(rs);
- rs = NULL;
- }
- fprintf(stderr,"MakeReport: No free store (malloc() failed).\n");
- }
- } else {
- fprintf(stderr,"MakeReport: NULL basename.\n");
- }
-
- if(buf!=NULL) {
- free(buf);
- }
-
- }
-
- return(rs);
- }
-
- void EndReport(struct Report *rs)
- {
- int i,n;
- char *buf=NULL;
-
- if(rs!=NULL) {
- if(rs->flags&RFLG_MPASS) {
- for(i=0;i!=REPFILES;i++) {
- if(rs->used[i]!=0) {
- for(n=0;n!=rs->gencount;n++) {
- fprintf(rs->files[i],"%d %f\n",n+1,rs->vbuffer[i][n]/((double)rs->cbuffer[i]));
- }
- }
- }
- }
- buf=malloc((strlen(rs->basename)+8)*sizeof(char));
- for(i=0;i!=REPFILES;i++) {
- fclose(rs->files[i]); /* fclose does an fflush. */
- if(rs->used[i]==0 && buf!=NULL) {
- sprintf(buf,"%s.%s",rs->basename,exts[i]);
- remove(buf);
- }
- }
-
- if(rs->flags&RFLG_VBUF) {
- for(i=0;i!=REPFILES;i++) {
- if(rs->vbuffer[i]!=NULL) {
- free(rs->vbuffer[i]);
- }
- }
- }
-
- free(rs->basename);
- free(rs);
- }
-
- if(buf!=NULL) {
- free(buf);
- } else {
- fprintf(stderr,"EndReport: No free store, continuing.\n");
- }
-
- }
-
- void DoReport(struct Report *rs,struct Population *Pop,unsigned int flags)
- {
- int i,n,t;
- struct Popstat *stat;
-
- if(rs!=NULL && Pop!=NULL && flags!=0) {
- stat = &Pop->Stat;
- for(i=0;i!=REPFILES;i++) {
- n = flags&(1<<i);
- if(n!=0) {
- rs->used[i]=1;
- if(rs->flags&RFLG_MPASS) {
- if(stat->Generation==1) {
- rs->cbuffer[i]++;
- }
- if(stat->Generation>rs->gencount) {
- fprintf(stderr,"DoReport: Generation overflow.\n");
- } else {
- if(rs->vbuffer[i]==NULL) {
- if(rs->flags&RFLG_NOMEM) {
- break;
- }
- rs->flags |= RFLG_VBUF;
- rs->vbuffer[i] = malloc(rs->gencount*sizeof(double));
- if(rs->vbuffer[i]==NULL) {
- rs->flags |= RFLG_NOMEM;
- fprintf(stderr,"DoReport: No free store for multipass buffer.\n(Failed to allocate %ld bytes.)\n",rs->gencount*sizeof(double));
- break;
- } else {
- for(t=0;t!=rs->gencount;t++) {
- rs->vbuffer[i][t] = 0.0;
- }
- }
- }
- switch(n) {
- case AVERAGE:
- rs->vbuffer[i][stat->Generation-1] += stat->AverageFitness;
- break;
- case MEDIAN:
- rs->vbuffer[i][stat->Generation-1] += stat->MedianFitness;
- break;
- case TYPECOUNT:
- rs->vbuffer[i][stat->Generation-1] += (double) stat->TypeCount;
- break;
- case MAX:
- rs->vbuffer[i][stat->Generation-1] += stat->MaxFitness;
- break;
- case MIN:
- rs->vbuffer[i][stat->Generation-1] += stat->MinFitness;
- break;
- case STDDEV:
- rs->vbuffer[i][stat->Generation-1] += stat->StdDeviation;
- break;
- }
- }
- } else {
- switch(n) {
- case AVERAGE:
- fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->AverageFitness);
- break;
- case MEDIAN:
- fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MedianFitness);
- break;
- case TYPECOUNT:
- fprintf(rs->files[i],"%ld %ld\n",stat->Generation,stat->TypeCount);
- break;
- case MAX:
- fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MaxFitness);
- break;
- case MIN:
- fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MinFitness);
- break;
- case STDDEV:
- fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->StdDeviation);
- break;
- }
- }
- }
- }
- }
-
- }
-
- struct Report *MakeReportT(char *basename,...)
- {
- va_list ap;
- int i=0;
- struct TagItem TagList[64]; /* Assumed big enough */
-
- va_start(ap,basename);
-
- while((TagList[i].ti_Tag = va_arg(ap,Tag)),TagList[i].ti_Tag != TAG_DONE && TagList[i].ti_Tag != TAG_MORE) {
- TagList[i].ti_Data = va_arg(ap,IPTR);
- i++;
- }
-
- if(TagList[i].ti_Tag == TAG_MORE) {
- TagList[i].ti_Data = va_arg(ap,IPTR);
- if(TagList[i].ti_Data == 0) {
- fprintf(stderr,"MakeReportT: Illegal NULL value for TAG_MORE.\n");
- TagList[i].ti_Tag = TAG_DONE;
- }
- }
-
- va_end(ap);
-
- return (MakeReport(basename,TagList));
- }
-
-