/* ------------------------------------------------------------ */ /* */ /* REM Memory Version january 12 1996 */ /* */ /* Mark Steyvers */ /* msteyver@falstaff.ucs.indiana.edu */ /* http://EZinfo.ucs.indiana.edu/~msteyver/home.html */ /* */ /* PAIRS - LIST LENGTH + STRENGTH + */ /* LIST STRENGTH + FREQUENCY + ROC */ /* */ /* Note: this is NOT the program used for the simulations */ /* reported in the technical report; this version is */ /* a stripped down version of the original program */ /* ------------------------------------------------------------ */ #include #include #include /* the random generator (from numerical recipes) */ #include "ran1.c" /* file handling */ #define FILENM "results.txt" /* append to existing file ? */ #define APPEND 0 /* random seed */ long IDUM = -3; /* number of data points */ #define NPOINTS 20000 /* the parameters for the model */ #define W 20 #define SystemG 0.4 #define LowG 0.325 #define HighG 0.45 float G[ 3 ] = { LowG , SystemG , HighG }; #define CO 0.7 /* probability storing correct */ #define US 0.04 /* probability storage attempt per time unit */ #define TINCR 0.0 /* criterion for recognition in incremental storage */ #define T1 10 /* use T1 when strong, T2 when weak */ #define T2 7 /* in normal op. t1=10 t2=7; for incremental storage, set t1=2 and t2=1 !!!!!!!! */ #define REPnew 7 /* storage attempts in incremental storage */ #define REPold 3 #define NLEN 4 #define NSTR 4 #define NCRI 11 #define NFRE 4 int LEN[ NLEN ] = { 4 , 10 , 20 , 40 }; /* criteria used in log scale for ZROC plots */ float CRI[ NCRI ] = { -1.0 , -0.8 , -0.7 , -0.2 , 0.0 , 0.2 , 0.7 , 1.0 , 1.25 , 1.75 , 2.5 }; /* what kind of simulations are we running? */ #define DOLENGTH 1 #define DOSTRENGTH 1 #define DOFREQ 1 #define DOROC 1 /* calculate ZROC curves ? */ #define DOPAIRS 0 /* do we do pairs ? */ #define DOINCREMENT 0 /* incremental storage ? */ #define SHOWZSCORES 0 /* these are the default settings for length, strength and frequency when one of these are held constant */ #define FIXED_LEN 2 /* look up length in length array */ #define FIXED_STR 0 /* 0 : strength= t1; 1 : strength= t1&t2 (mixed) ; 2 : strength= t2 */ #define FIXED_CRI 4 /* look up criterion in criterion array */ #define FIXED_FRE 2 /* 0 = lowg ; 1= mixed 2=high */ /* some constants */ #define MAXK 50 #define NMAX 40 #define IMAX 100 #define LMAX 100 #define MAXPOS 40 float MINV = -5.0; float MAXV = +5.0; #define STEPSV 5000 float PI = 3.1415927; /* strings used by the program */ #define NPARAM 12 struct PARAM { char *word; } SPARAM[ NPARAM ] = { "Length ", "Strength ", "Frequency ", "Criterion Used ", "Criterion ROC ", "W ", "CO ", "US ", "G ", "REPnew ", "REPold ", "TINCR ", }; #define ENDWHAT 13 #define NWHAT ENDWHAT struct WHAT { char *word; int SWI; } SWHAT[ NWHAT ] = { "Hits " , 1 , "False Alarms " , 1 , "Dprime " , 1 , "Slope " , 1 , "List average Ln(O) " , 1 , "Max Odds " , 1 , "P( F crit for list ) " , 1 , "#traces " , 1 , "P( both in 1 trace ) " , 1 , "P( second in new ) " , 1 , "P( second with other ) " , 1 , "max images in 1 trace " , 1 }; struct TAG { char *word; } TAGS[ 4 ] = { " targets ", " distractors ", " matching ", " mismatching ", }; /* declarations of the global arrays */ float GF[ MAXK ][ 4 ]; float INF[ NMAX*2 ][ NWHAT ]; float INFCRI[ NMAX*2 ][ NCRI ]; float SLOPE[ NLEN + NSTR + NFRE ]; /* declarations for the structured arrays */ struct VEC { int W1[ W ]; int W2[ W ]; int PO[ MAXPOS ]; int DR; int TI; }; struct VEC LEX[ LMAX ]; /* lexical array */ struct VEC LEXCOP; struct VEC IMA[ IMAX + NMAX ]; /* images array or memory traces */ struct VEC TEST; /* probe array */ /* structure for statistics bookkeeping */ struct STA { float SUM; float SUS; float AVE; float STD; long N; }; struct STA STATS[ NWHAT ][ NLEN + NSTR + NFRE ][ 2 ]; struct STA STATSCRI[ NCRI ][ NLEN + NSTR + NFRE ][ 4 ]; /* declarations of the global variables */ FILE *OUTD,*OUTFREQ; int o,ULEN,UFRE,USTR,whv,iv; long n,NRUN,ntraces,testpos; long cycle,tcycle; long SAVEIDUM,storewhere; char *comment; float dprime,INTERCEPT,PMCC; /* declarations of the function used */ void checkparams(); void initstats(); void initf(); int getf(); void openfile(); void myclosefile(); void makelexicon(); void dorecognition(); void dorecognitionstorage(); void doincrementstats(); void writecycle(); void calcstats(); float powm( float w1, int w2 ); float conv( float Pagg ); void makeincrementlexicon(); void regression(); void calcslopes(); void procstats( int whv, int iv, int nstart, int nend, int td ); int wh( int whv, int iv ); int convert( int ustr ); void statslength(); void statsstrength(); void statsfreq(); void showparams(); void showstats( int whv , int nv ); void dorun(); main() { SAVEIDUM = IDUM; checkparams(); initf(); openfile(); initstats(); cycle = 0; tcycle = 0; if (DOLENGTH) for (o=0; o0) && (ni2>0)) { std1 = sqrt( (1.0*ni1*sumsqr1 - sum1*sum1) / (1.0*ni1*ni1) ); av1 = sum1 / (1.0*ni1); std2 = sqrt( (1.0*ni2*sumsqr2 - sum2*sum2) / (1.0*ni2*ni2) ); av2 = sum2 / (1.0*ni2); if (std1*std2 != 0) { PMCC = 0.0; for (ir=0; ir< NCRI; ir++) PMCC += ( STATSCRI[ ir ][ i ][ 3 ].AVE - av1 ) * ( STATSCRI[ ir ][ i ][ 2 ].AVE - av2 ) / ( std1 * std2 ); PMCC = PMCC / (1.0*NCRI); SLOPE[ i ] = PMCC * ( std2 / std1 ); INTERCEPT = av2 - SLOPE[ i ] * av1; } else SLOPE[ i ] = 0.0; } else SLOPE[ i ] = 0.0; } } /* show the parameters of the simulation */ void showparams() { char *stars = "***************************"; int i,j; fprintf( OUTD , "\n" ); fprintf( OUTD , stars ); fprintf( OUTD , " " ); fprintf( OUTD , comment ); fprintf( OUTD , " " ); fprintf( OUTD , stars , "\n" ); fprintf( OUTD , "\n\n" ); fprintf( OUTD , "# points " ); fprintf( OUTD , "%d\n" , NPOINTS ); fprintf( OUTD , "seed " ); fprintf( OUTD , "%ld\n" , SAVEIDUM ); fprintf( OUTD , "LowG SystemG HighG: %1.3f %1.3f %1.3f\n" , LowG , SystemG , HighG ); if (DOPAIRS) fprintf( OUTD , "PAIRS\n" ); else fprintf( OUTD , "SINGLES\n" ); if (!DOINCREMENT) fprintf( OUTD , "NO INCREMENTAL STORAGE\n" ); else fprintf( OUTD , "INCREMENTAL STORAGE\n" ); for (i=0; i 0) { fprintf( OUTD , "AVERAGES\n" ); for (i=0; i< NWHAT; i++) if ((SWHAT[i].SWI) || (i>=ENDWHAT)) { if (i=ENDWHAT) || ((i>=9) && (i<=12)) || ((i>=18) && (i<=ENDWHAT)) ) { for (iv=0; iv=ENDWHAT) fprintf( OUTD , "%1.3f\t" , STATS[ i ][ wh( whv , iv ) ][ 1 ].AVE ); if ((i>=9) && (i<=12)) fprintf( OUTD , "%1.3f\t" , STATS[ i ][ wh( whv , iv ) ][ 1 ].AVE ); if ((i>=18) && (i12) && (i<18)) offset = 2; else offset = 0; for (j=0; j<2; j++) { fprintf( OUTD , TAGS[ j+offset ].word ); for (iv=0; iv NLEN+NSTR+NFRE-1 )) { printf( "something is wrong with iv\n" ); exit(0); } return (offs); } void statslength() { comment = " LENGTH "; whv = 0; for (iv=0; iv 0) { if (tcycle >= 10) { if ((cycle % (tcycle / 10)) == 0) { percen = 100.0 * cycle / (tcycle * 1.0); printf( "Percentage done : " ); printf( "%3.0f\n" , percen ); fflush( stdout ); } } } } int convert( int ust ) { int vout; vout = ust; if (ust==2) vout = 3; return (vout); } void procstats( int whv, int iv, int nstart, int nend, int td ) { float sumin,susin; long nin; int f,i,cri_now; float value; for (f=0; f= MAXK ); return kindex; } /* file handling */ void openfile() { int error = 0; if (APPEND) { if (( OUTD = fopen( FILENM , "at" )) == NULL) { error = 1; OUTD = fopen( FILENM , "wt" ); } } else { OUTD = fopen( FILENM , "wt" ); } if (error==1) { printf( "WARNING: attempt to append to non-existing file\n" ); } } void myclosefile() { fclose( OUTD ); } void checkparams() { int i; for (i=0;i NMAX) { printf( "error in initializing length array\n" ); exit(0); } } /* make a lexicon of LIST-LENGTH*2 items. Later, we will store the first half, so the first half of the lexicon are old items and the seconf half new items */ void makelexicon() { long i,ulmax,uimax,lexpos; int j,dr,fr,time,t,value,useg; uimax = ULEN; ulmax = ULEN * 2; for (i=0;i CO) value = getf( 1 ); IMA[ i ].W1[ j ] = value; } } /* second word */ if (DOPAIRS) for (j=0; j CO) value = getf( 1 ); IMA[ i ].W2[ j ] = value; } } } } /* this is only used in the incremental storage version */ void makeincrementlexicon() { long i,ulmax,uimax,lexpos,totaldraws,q; int j,dr,fr,time,t,value,useg; /* note: ulmax-1 is upper boundary of lexicon array */ ulmax = ULEN * 2; uimax = ULEN * 2; totaldraws = 0; for (i=0;i=ULEN) dr = 0; else { if (USTR==0) dr=T1; if ((USTR==1) && (i< ULEN / 2)) dr=T1; if ((USTR==1) && (i>= ULEN / 2)) dr=T2; if (USTR==2) dr=T2; } totaldraws += dr; LEX[ i ].DR = dr; } /* clean storage array */ for (i=0; i 0) { testpos = lexpos; dorecognitionstorage(); time = REPold; if (storewhere==ntraces) { ++ntraces; time = REPnew; } } else { time = REPnew; storewhere = 0; ++ntraces; } i = storewhere; /* do the storage */ ++IMA[ i ].PO[ 0 ]; if (IMA[ i ].PO[ 0 ] == MAXPOS) { printf( "\n\n\n\ warning !!!! storing too many images in one trace\n" ); exit(0); } IMA[ i ].PO[ IMA[ i ].PO[ 0 ] ] = lexpos; IMA[ i ].TI = time; /* first word */ for (j=0; j CO) value = getf( 1 ); IMA[ i ].W1[ j ] = value; } } /* second word */ if (DOPAIRS) for (j=0; j CO) value = getf( 1 ); IMA[ i ].W2[ j ] = value; } } } } /* this is only used in the incremental storage version */ void dorecognitionstorage() { float gamma,F1,F2; long uimax,k,q; long kl,bestpos; int j,mis1,mis2,misc,mat1,mat2,matc,f,mis,mat; int check,bestmis,bestnf; float odds,odds1,odds2,firstt1,firstt2,secondt1,secondt2; float lnodds,best,b,gterm,sumodds,ni; uimax = ntraces; b = 0.0; for (j=0; j < W; j++) { TEST.W1[ j ] = LEX[ testpos ].W1[ j ]; if (DOPAIRS) TEST.W2[ j ] = LEX[ testpos ].W2[ j ]; else TEST.W2[ j ] = 0; } /* go through all the test items */ best = -100.0; bestpos = -1; bestmis = 100; sumodds = 0.0; ni = 0.0; for (k=0; k0.0) { lnodds = log( odds ); if ( 1.0 > 0.0 ) { sumodds += odds; ni += 1.0; } if (lnodds > best) { best = lnodds; bestpos = k; bestmis = mis; bestnf = mat+mis; } } } storewhere = ntraces; if ((ni>0.0) && (log(sumodds/ni) > TINCR)) storewhere = bestpos; } /* main routine for calculating the odds */ void dorecognition() { float gamma,F1,F2,listodds; long i,uimax,ni,nilist,k,q,ulist; int j,mis1,mis2,misc,mat1,mat2,matc,f,mis,mat,nfeatp,targetp,order; int check,myc; float sumodds,odds,odds1,odds2,firstt1,firstt2,secondt1,secondt2; float lnodds,best,floatodds,floatlog,matchln,mismatchln; float matchodds,mismatchodds,Pd,Ps,gterm,odds3,odds4,term1; int intlog,intodds,fp,fv; float b,codds,odds1b,odds2b; int ch; uimax = ULEN; if (DOINCREMENT) uimax = ntraces; if (DOINCREMENT) ulist = ntraces; else ulist = ULEN; b = 0.0; for (i=0; i < ULEN*2; i++) { /* construct the probe in array TEST. In all simulations (in this program), we will probe with a single item, so word-1 is put in TEST.W1 and since there is no word-2, TEST.W1 is empty */ for (j=0; j < W; j++) { TEST.W1[ j ] = LEX[ i ].W1[ j ]; TEST.W2[ j ] = 0; } /* go through all the test items */ sumodds = 0.0; listodds = 0.0; ni = 0; nilist = 0; nfeatp = 0; best = -100.0; targetp = 0; for (k=0; k best) && (k < ulist)) best = lnodds; if ((i CRI[ FIXED_CRI ]) && ( i < ULEN )) INF[ i ][ 0 ] = 1.0; if (( lnodds > CRI[ FIXED_CRI ]) && ( i >= ULEN )) INF[ i ][ 1 ] = 1.0; if (nilist>0) INF[ i ][ 4 ] = log( listodds / (1.0*nilist)); INF[ i ][ 5 ] = best; if (i>=ULEN) INF[ i ][ 6 ] = nilist / ( 1.0 * ulist ); if (i CRI[ f ]) INFCRI[ i ][ f ] = 1.0; } } } float powm( float w1, int w2 ) { float poww; int wc; poww = 1.0; wc = w2; while (wc != 0) { --wc; poww = poww * w1; } return poww; } /* calculate some statistics for the incremental storage version */ void doincrementstats() { long i,j,k; int indiffnew,indiffother,inone,prevj,firstother; int tracesin[ 5 ]; int maxtraces,numbert; for (i=0; i maxtraces) maxtraces = numbert; for (k=1; k<=numbert; k++) { if (IMA[ j ].PO[ k ]==i) { if (prevj == -1) { prevj = j; if (k>1) firstother=1; } else if (prevj == j ) { inone = 1; } else if (prevj != j) { if (k==1) indiffnew = 1; else indiffother = 1; } } } } if (inone==1) ++tracesin[ 1 ]; if (indiffnew==1) ++tracesin[ 2 ]; if (indiffother==1) ++tracesin[ 3 ]; if (firstother==1) ++tracesin[ 4 ]; } INF[ i ][ 19 ] = tracesin[ 1 ] / (1.0*ULEN); /* both in one */ INF[ i ][ 20 ] = tracesin[ 2 ] / (1.0*ULEN); /* second in new */ INF[ i ][ 21 ] = tracesin[ 3 ] / (1.0*ULEN); /* second in other */ INF[ i ][ 22 ] = firstother; } /* main running routine */ void dorun() { int f,i; if (DOINCREMENT) makeincrementlexicon(); else makelexicon(); dorecognition(); if (DOINCREMENT) doincrementstats(); }