put results into separate result dir
[libfirm] / ir / be / test / scanner.c
1 /*$Header$*/
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include <fcntl.h>
6
7 #ifdef PLATFORM_NT
8 #include <io.h>
9 #endif
10 #ifdef PLATFORM_LINUX
11 #endif
12
13 #define TRUE 1
14 #define FALSE 0
15
16 #define MODE_RECOGNIZE 0
17 #define MODE_TRAIN1 1
18 #define MODE_TRAIN2 2
19
20 void alloc_td_bu();
21
22
23 unsigned char **cimage;
24 double **tds;
25 double **bus;
26 int lwidth,lheight;
27 int width, height,numinputs;
28 long i,j;
29
30 int pass_flag;
31 int highx[2], highy[2];
32 double highest_confidence[2];
33 int set_high[2];
34
35 #define DB1 1
36 #define DB2 0
37 #define DB3 1
38
39 FILE *fp;
40
41 int winner,numf1s,numf2s, resonant,cp,numpatterns;
42
43 double a, b, c, d, theta, delta_t;
44 double rho;
45
46 typedef struct {
47         double *I;
48         double W;
49         double X;
50         double V;
51         double U;
52         double P;
53         double Q;
54         double R;
55                 } f1_neuron;
56
57 f1_neuron *f1_layer;
58
59 typedef struct {
60       double y;
61       int   reset;
62       } xyz;
63
64 xyz *Y;
65
66
67 double g(i)
68 int i;
69 {  double result;
70     if (i != winner)
71         result =0;
72     else
73        if ( Y[i].y > 0)
74            result = d;
75        else
76            result =0;
77     return(result);
78 }
79
80 void find_match()
81 { int i;
82    winner = 0;
83    for (i=0;i<numf2s;i++)
84        if (Y[i].y > Y[winner].y)
85               winner =i;
86 }
87
88 double simtest()
89 {   int j;
90    double sum,norm;
91    double temp_sum;
92
93    sum = norm =0;
94    for (j=0;j<numf1s;j++)
95    {
96       norm += f1_layer[j].P * f1_layer[j].P;
97    }
98    norm = sqrt((double) norm);
99    norm *= c;
100    sum += norm;
101    norm =0;
102    for (j=0;j<numf1s;j++)
103    {
104       temp_sum = f1_layer[j].U * f1_layer[j].U;
105       norm += temp_sum;
106    }
107    norm = sqrt((double) norm);
108    sum += norm;
109    for (j=0;j<numf1s;j++)
110       f1_layer[j].R =  (f1_layer[j].U+ c * f1_layer[j].P)/sum;
111    norm = 0;
112    for (j=0;j<numf1s;j++)
113       norm += f1_layer[j].R * f1_layer[j].R;
114    norm = sqrt((double) norm);
115 #ifdef DEBUG
116    if (DB2 && (winner==0)) printf("%5.3f",norm);
117 #endif
118 return(norm);
119 }
120
121
122 double simtest2()
123 {   int j;
124    double Su,Sp,numerator,denom;
125    double su,sp;
126    double su2,sp2;
127    double sup;
128    double r;
129    double e = 0.0000000001; /* 10e-10 */
130
131    su = sp = sup = su2 = sp2=numerator= 0.0;
132    for (j=0;j<numf1s;j++)
133    {
134       su += f1_layer[j].U;
135       sp += f1_layer[j].P;
136       su2 += f1_layer[j].U * f1_layer[j].U;
137       sp2 += f1_layer[j].P * f1_layer[j].P;
138       sup += f1_layer[j].U * f1_layer[j].P;
139    }
140    Su = ((double)numf1s*su2-su*su)/((double)numf1s*((double)numf1s-1.0));
141    Su = sqrt(Su);
142    Sp = ((double)numf1s*sp2-sp*sp)/((double)numf1s*((double)numf1s-1.0));
143    Sp = sqrt(Sp);
144    numerator = (double) numf1s * sup - su * sp;
145    denom = sqrt((double) numf1s*su2 - su*su) * sqrt((double) numf1s*sp2 - sp*sp);
146    r = (numerator+e)/(denom+e);
147
148    if ((numerator == 0) || (denom==0))
149    {
150        fprintf(stderr,"potential div by zero");
151        r=1;
152    }
153    if ((numerator != 0) && (denom==0))
154    {
155        fprintf(stderr,"div by zero");
156        r=1;
157    }
158    r *= r;     /*  trying to match inverse images */
159 #ifdef DEBUG
160    if (DB1) printf( "  simtest2(r) = %8.6f\n",r);
161    if (DB2 && (winner==0)) printf("%8.4f",r);
162 #endif
163    return (r);
164 }
165
166 void weightadj()
167 { int i,j,k;
168   double temp;
169   double er = 0.000000001;
170 #ifdef DEBUG
171   int bad_count;
172   int good_count;
173 #endif
174
175     i = winner;
176 #ifdef DEBUG
177     fprintf(stdout,"winner %d\n",i);
178 #endif
179     for (k=0;k<1;k++)
180     {   resonant=0;
181         for (j=0;j<numf1s;j++)
182         {    temp = tds[j][i];
183              tds[j][i] += g(i)*(f1_layer[j].P - tds[j][i])*delta_t;
184              if (fabs(temp - tds[j][i]) <= er)
185                 resonant = 1;
186         }
187 #ifdef DEBUG
188         bad_count=0;
189         good_count = 0;
190 #endif
191         for (j=0;j<numf1s;j++)
192         {   temp = bus[j][i];
193             bus[j][i] += g(i) * (f1_layer[j].P - bus[j][i]) * delta_t;
194             if ((fabs(temp - bus[j][i]) <= er) && resonant)
195             {
196 #ifdef DEBUG
197                  good_count++;
198 #endif
199                  resonant =1;
200             }
201             else
202             {
203 #ifdef DEBUG
204                  bad_count++;
205 #endif
206                  resonant =0;
207             }
208         }
209     }
210 #ifdef DEBUG
211     printf("bad %d good %d\n",bad_count,good_count);
212 #endif
213 }
214
215 /* init_globs - initialize ART 2 parameters based
216  *   on whether we are training a network or loading
217  *   the weights of a pretrained network.
218  */
219 void init_globs(int mode)
220 {
221   if (mode==MODE_RECOGNIZE)
222   {
223      a       = 255;
224      b       = 0.0;
225      c       = 0.11;
226      d       = 0.9;
227      theta   = 1/sqrt((double) numf1s);
228      delta_t = 0.1;
229      rho     = 0.70;
230   }
231   else
232   {
233      a       = 255;
234      b       = 10.0;
235      c       = 0.11;
236      d       = 0.9;
237      theta   = 1/sqrt((double) numf1s);
238      delta_t = 0.7;
239      rho     = 0.95;
240   }
241 } /* end of init_globs */
242
243 void init_net()
244 {
245    int i;
246
247    f1_layer = (f1_neuron *)malloc(numf1s * sizeof (f1_neuron));
248    if (f1_layer==NULL)
249    {
250      fprintf(stderr,"malloc error in init_net\n");
251      exit(1);
252    }
253    for (i=0;i<numf1s;i++)
254    {
255
256      f1_layer[i].I = (double *)malloc(2*sizeof(double));
257      if (f1_layer[i].I==NULL)
258      {
259        fprintf(stderr,"malloc error in init_net\n");
260        exit(1);
261      }
262      f1_layer[i].W = 0;
263      f1_layer[i].X = 0;
264      f1_layer[i].V = 0;
265      f1_layer[i].U = 0;
266      f1_layer[i].P = 0;
267      f1_layer[i].Q = 0;
268      f1_layer[i].R = 0;
269    }
270
271    Y = (xyz *)malloc(numf2s*sizeof(xyz));
272    if (Y==NULL)
273    {
274      fprintf(stdout,"Malloc error for Y\n");
275      exit(1);
276    }
277
278 }
279
280 void analog_conv()
281 { int j,lines,k;
282   int x1,x2;
283   double y1,y2;
284
285    fscanf(fp,"%i",&lines);
286    for (j=0;j<lines;j++)
287    {   fscanf(fp,"%i %f %i %f",&x1,&y1,&x2,&y2);
288        for (k=x1;k<=x2;k++)
289           f1_layer[k].I[cp] = ((y2-y1)/(x2-x1) * (k-x2)) + y2;
290           /*I[cp][k] = ((y2-y1)/(x2-x1) * (k-x2)) + y2;*/
291    }
292
293 }
294
295 void get_pat()
296 { int i;
297
298   for(i=0;i<numf1s;i++)
299      fscanf(fp,"%f",&f1_layer[i].I[cp]);
300 }
301
302 void show_pat()
303 { int i;
304
305    for(i=0;i<numf1s;i++)
306    {  if ( (i%5) == 0)
307           printf("\n");
308       printf(" %8.5f ",f1_layer[i].I[cp]);
309    }
310    printf("\n\n");
311 /*   getchar();*/
312 }
313
314 void reset_nodes()
315 { int i;
316
317    for (i=0;i<numf1s;i++)
318    {
319      f1_layer[i].W = 0.0;
320      f1_layer[i].X = 0.0;
321      f1_layer[i].V = 0.0;
322      f1_layer[i].U = 0.0;
323      f1_layer[i].P = 0.0;
324      f1_layer[i].Q = 0.0;
325      f1_layer[i].R = 0.0;
326    }
327    for (i=0;i<numf2s;i++)
328     {   Y[i].y = 0.0;
329         Y[i].reset =0;
330     }
331     winner = 0;
332     resonant = 0;
333 }
334
335
336 void reset_nodes2()
337 { int i;
338
339    for (i=0;i<numf1s;i++)
340    {
341      f1_layer[i].W = 0.0;
342      f1_layer[i].X = 0.0;
343      f1_layer[i].V = 0.0;
344      f1_layer[i].U = 0.0;
345      f1_layer[i].P = 0.0;
346      f1_layer[i].Q = 0.0;
347      f1_layer[i].R = 0.0;
348    }
349    for (i=0;i<numf2s;i++)
350        Y[i].y = 0.0;
351     winner = 0;
352     resonant = 0;
353 }
354
355
356
357 void print_weights()
358 { int i,j;
359
360   /* print td's */
361   printf("============  TOP down WEIGHTS ==============\n");
362   for (i=0;i<numf1s;i++)
363       for (j=0;j<numf2s;j++)
364          if (j==(numf2s-1))
365             printf(" %8.16f\n",tds[i][j]);
366          else
367             printf(" %8.16f ",tds[i][j]);
368   /* print bu's */
369   printf("============  BOTTOM up WEIGHTS ==============\n");
370   for (i=0;i<numf1s;i++)
371       for (j=0;j<numf2s;j++)
372          if (j==(numf2s-1))
373             printf(" %8.16f\n",bus[i][j]);
374          else
375             printf(" %8.16f ",bus[i][j]);
376 }
377
378
379 void print_f12()
380 { int j;
381      printf("\n\n");
382      for(j=0;j<numf2s;j++)
383          printf(" j = %i  Y= %9.7f\n",j,Y[j].y);
384 }
385
386 void train_match(int spot)
387 { int j,matched,f1res,mt;
388   int ti,tj,tresult;
389   double tnorm;
390   double xr,qr,tsum,ttemp;
391   char matchtest;
392   double match_confidence;
393   f1res=0;
394   reset_nodes();
395   cp =spot;
396   matched = 0;
397   while (!matched)
398   {
399     f1res = 0;
400     for (j=0;j<9 && !f1res ;j++)
401     {
402
403       /* Compute F1 layer - W values */
404       tnorm = 0;
405       for (ti=0;ti<numf1s;ti++)
406       {
407           f1_layer[ti].W = f1_layer[ti].I[cp] + a*(f1_layer[ti].U);
408           tnorm += f1_layer[ti].W * f1_layer[ti].W;
409       }
410       tnorm =  sqrt((double)tnorm);
411       /* Compute F1 layer - X values */
412
413       for (tj=0;tj<numf1s;tj++)
414             f1_layer[tj].X = f1_layer[tj].W/tnorm;
415
416       /* Compute F1 layer - V values */
417
418       tnorm =0;
419       for (ti=0;ti<numf1s;ti++)
420       {
421            if (f1_layer[ti].X < theta)
422                   xr = 0;
423            else
424                   xr = f1_layer[ti].X;
425            if (f1_layer[ti].Q < theta)
426                   qr = 0;
427            else
428                   qr = f1_layer[ti].Q;
429            f1_layer[ti].V = xr + b*qr;
430            tnorm += f1_layer[ti].V * f1_layer[ti].V;
431       }
432
433       /* Compute F1 layer - U values */
434       tnorm = sqrt((double) tnorm);
435       for (tj=0;tj<numf1s;tj++)
436             f1_layer[tj].U = f1_layer[tj].V/tnorm;
437
438
439
440       /* Compute F1 layer - P values */
441       tnorm =0;
442       tsum=0;
443       tresult = 1;
444       for (ti=0;ti<numf1s;ti++)
445       {
446         tsum = 0;
447         ttemp = f1_layer[ti].P;
448
449         for (tj=spot;tj<numf2s;tj++)
450         {
451            if ((tj == winner)&&(Y[tj].y > 0))
452                  tsum += tds[ti][tj] * d;
453         }
454
455         f1_layer[ti].P = f1_layer[ti].U + tsum;
456
457         tnorm += f1_layer[ti].P * f1_layer[ti].P;
458
459         if (ttemp != f1_layer[ti].P)
460            tresult=0;
461       }
462       f1res = tresult;
463
464       /* Compute F1 - Q values */
465
466       tnorm = sqrt((double) tnorm);
467       for (tj=0;tj<numf1s;tj++)
468             f1_layer[tj].Q = f1_layer[tj].P;
469
470       /* Compute F2 - y values */
471       for (tj=spot;tj<numf2s;tj++)
472       {
473         Y[tj].y = 0;
474         if ( !Y[tj].reset )
475         for (ti=0;ti<numf1s;ti++)
476            Y[tj].y += f1_layer[ti].P * bus[ti][tj];
477       }
478
479       /* Find match */
480       winner = 0;
481       for (ti=spot;ti<numf2s;ti++)
482       {
483        if (Y[ti].y > Y[winner].y)
484           winner =ti;
485       }
486
487
488     }
489 #ifdef DEBUG
490     if (DB1) print_f12();
491     if (DB1) printf("\n num iterations for p to stabalize = %i \n",j);
492 #endif
493     match_confidence=simtest();
494 #ifdef DEBUG
495 fprintf(stdout,"rho %e\n",match_confidence);
496 #endif
497     if ((match_confidence) > rho)
498     {
499 #ifdef DEBUG
500        if (DB2 && (winner==0)) printf("#%i",winner);
501 #endif
502        weightadj();
503        matched = 1;
504     }
505     else
506     {    Y[winner].y = 0;
507          Y[winner].reset = 1;
508 #ifdef DEBUG
509          if (DB1) printf("#%iN",winner);
510 #endif
511          matchtest=0;
512          for (mt=spot;mt<numf2s;mt++)
513               if (Y[mt].reset==0)
514                    matchtest =1;
515          if (matchtest)
516             find_match();
517          else
518             matched = 1;
519     }
520   } /* end while */
521 } /* end of train_match() */
522
523 void match()
524 { int j,matched,f1res,mt;
525   int ti,tj,tresult;
526   double tnorm;
527   double xr,qr,tsum,ttemp;
528   char matchtest;
529   double match_confidence;
530   f1res=0;
531
532   cp =0;
533   reset_nodes();
534
535   matched = 0;
536   while (!matched)
537   {
538     reset_nodes2();
539     f1res = 0;
540     for (j=0;j<9 && !f1res ;j++)
541     {
542
543       /* Compute F1 layer - W values */
544       tnorm = 0;
545       for (ti=0;ti<numf1s;ti++)
546       {
547           f1_layer[ti].W = f1_layer[ti].I[cp] + a*(f1_layer[ti].U);
548           tnorm += f1_layer[ti].W * f1_layer[ti].W;
549       }
550       tnorm =  sqrt((double)tnorm);
551       /* Compute F1 layer - X values */
552
553       for (tj=0;tj<numf1s;tj++)
554             f1_layer[tj].X = f1_layer[tj].W/tnorm;
555
556       /* Compute F1 layer - V values */
557
558       tnorm =0;
559       for (ti=0;ti<numf1s;ti++)
560       {
561            if (f1_layer[ti].X < theta)
562                   xr = 0;
563            else
564                   xr = f1_layer[ti].X;
565            if (f1_layer[ti].Q < theta)
566                   qr = 0;
567            else
568                   qr = f1_layer[ti].Q;
569            f1_layer[ti].V = xr + b*qr;
570            tnorm += f1_layer[ti].V * f1_layer[ti].V;
571       }
572
573       /* Compute F1 layer - U values */
574       tnorm = sqrt((double) tnorm);
575       for (tj=0;tj<numf1s;tj++)
576             f1_layer[tj].U = f1_layer[tj].V/tnorm;
577
578
579
580       /* Compute F1 layer - P values */
581       tnorm =0;
582       tsum=0;
583       tresult = 1;
584       for (ti=0;ti<numf1s;ti++)
585       {
586         tsum = 0;
587         ttemp = f1_layer[ti].P;
588
589         for (tj=0;tj<numf2s;tj++)
590         {
591            if ((tj == winner)&&(Y[tj].y > 0))
592                  tsum += tds[ti][tj] * d;
593         }
594
595         f1_layer[ti].P = f1_layer[ti].U + tsum;
596
597         tnorm += f1_layer[ti].P * f1_layer[ti].P;
598
599         if (ttemp != f1_layer[ti].P)
600            tresult=0;
601       }
602       f1res = tresult;
603
604       /* Compute F1 - Q values */
605
606       tnorm = sqrt((double) tnorm);
607       for (tj=0;tj<numf1s;tj++)
608             f1_layer[tj].Q = f1_layer[tj].P;
609
610       /* Compute F2 - y values */
611       for (tj=0;tj<numf2s;tj++)
612       {
613         Y[tj].y = 0;
614         if ( !Y[tj].reset )
615         for (ti=0;ti<numf1s;ti++)
616            Y[tj].y += f1_layer[ti].P * bus[ti][tj];
617       }
618
619       /* Find match */
620       winner = 0;
621       for (ti=0;ti<numf2s;ti++)
622       {
623        if (Y[ti].y > Y[winner].y)
624           winner =ti;
625       }
626
627
628     }
629 #ifdef DEBUG
630     if (DB1) print_f12();
631     if (DB1) printf("\n num iterations for p to stabilize = %i \n",j);
632 #endif
633     match_confidence=simtest2();
634     if ((match_confidence) > rho)
635     {
636        /* If the winner is not the default F2 neuron (the highest one)
637         * we have a match.
638         */
639        if (winner!=numf2s-1)
640        {
641            pass_flag=1;
642            fprintf(stdout,"F2 neuron %d passes vigilance with a value of %0.4f\n",winner,match_confidence);
643            print_f12();
644            if (match_confidence > highest_confidence[winner])
645            {
646              highest_confidence[winner] = match_confidence;
647              set_high[winner] = TRUE;
648            }
649        }
650        matched = 1;
651     }
652     else
653     {    Y[winner].y = 0;
654          Y[winner].reset = 1;
655 #ifdef DEBUG
656          if (DB1) printf("#%i No",winner);
657 #endif
658          matchtest=0;
659          for (mt=0;mt<numf2s;mt++)
660               if (Y[mt].reset==0)
661                    matchtest =1;
662          if (matchtest)
663             find_match();
664          else
665             matched = 1;
666     }
667   } /* end while */
668 }
669
670
671 /*
672  *  loadimage - load image to scan
673  *  This was rewritten because Windows NT seems to have
674  *  problems with sequential calls to getc, scanf, fread,
675  *  and fread.  The bug is flaky.  It appears that I'd
676  *  only get one big read and all of the rest of the reads
677  *  would contain bogus data, yet no error condition is
678  *  generated by the read.  Solution: one big read of the
679  *  whole image and then a copy to where I really want it,
680  *  cimage.
681  */
682 void loadimage(char *input_file)
683 {
684    int i,j;
685    int fd;
686    char buffer[64];
687    char *superbuffer;
688    if ((fd=open(input_file,O_RDONLY))==-1)
689    {
690      fprintf(stderr,"Error opening %s\n",input_file);
691      exit(1);
692    }
693 #ifdef DEBUG
694    printf("made it to loadimage\n");
695 #endif
696
697    /* Strip Format descriptor */
698    read(fd,buffer,8);
699    /* Read width */
700    read(fd,buffer,4);
701    for (i=0;i<4;i++)
702      if (buffer[i] != ' ')
703        width = width * 10 + buffer[i] - '0';
704
705    /* Read height */
706    read(fd,buffer,4);
707    for (i=0;i<4;i++)
708      if (buffer[i] != ' ')
709        height = height * 10 + buffer[i] - '0';
710
711 #ifdef DEBUG
712    fprintf(stderr,"width %d, height %d\n",width,height);
713 #endif
714
715    superbuffer = (char *)malloc(width * height * sizeof(char ));
716    if (superbuffer == NULL)
717    {
718       fprintf(stderr,"Problems with malloc in loadimage()\n");
719       exit(1);
720    }
721    cimage = (unsigned char **) malloc(sizeof(unsigned char *) * height);
722    if (cimage == NULL)
723    {
724       fprintf(stderr,"Problems with malloc in loadimage()\n");
725       exit(1);
726    }
727
728    for (i=0;i<height;i++)
729    {
730       cimage[i] = (unsigned char *) malloc(width* sizeof(unsigned char));
731       if (cimage[i]==NULL)
732       {
733         fprintf(stderr,"Problems with malloc in loadimage()\n");
734         exit(1);
735       }
736    }
737
738    read(fd,superbuffer,width*height);
739    for (i=0;i<height;i++)
740    {
741      for (j=0;j<width;j++)
742      {
743        cimage[i][j] = superbuffer[i*width + j];
744      }
745    }
746
747
748 #ifdef DEBUG
749    printf(" upper left 10X10 corner of image\n");
750    for (i=0;i<10;i++)
751    {
752       for (j=0;j<10;j++)
753           printf("%4d",cimage[i][j]);
754       printf("\n");
755    }
756 #endif
757
758 }
759
760 /* load_weights - load neural net weights
761  * This seems to function properly which is odd because
762  * loadimage does not.  The only difference really is that
763  * loadimage is trying to load bytes of any value, whereas
764  * load_weights is looking at a file that only contains
765  * ascii characters and reading them as ints or doubles.
766  */
767 void load_weights(char *weightfile)
768 {  double a;
769    long i,j;
770
771    FILE *inp;
772
773    if ((inp=fopen(weightfile,"r"))==NULL)
774    {
775      fprintf(stderr,"Unable to open %s\n",weightfile);
776      exit(1);
777    }
778
779    printf("made it to load_weights\n");
780    fscanf (inp,"%d %d",&lwidth,&lheight);
781    numf1s = numinputs = lwidth * lheight;
782    numf2s = numpatterns+1;
783
784    alloc_td_bu();
785
786    j = 0;
787    for (i=0;i<numf1s;i++)
788    {   fscanf(inp,"%le",&a);
789        bus[i][j] = tds[i][j] =a;
790    }
791 } /* end of load_weights */
792
793 /* alloc_td_bu - memory alloc of top down and bottom up
794  *   connections
795  */
796 void alloc_td_bu()
797 {
798    bus = (double **)malloc(numf1s*sizeof(double *));
799    tds = (double **)malloc(numf1s*sizeof(double *));
800    if ((bus==NULL)||(tds==NULL))
801    {
802      fprintf(stderr,"Malloc problem in load_weights\n");
803      exit(1);
804    }
805    for (i=0;i<numf1s;i++)
806    {
807      bus[i] = (double *)malloc(numf2s*sizeof(double));
808      tds[i] = (double *)malloc(numf2s*sizeof(double));
809    }
810 } /* end of alloc_td_bu */
811
812 /* init_td - initialize top down weights
813  *   start signifies which F2 neuron to initialize for.  Enables
814  *   training on more than one image.
815  */
816 void init_td(int start)
817 {
818   int i,j;
819   for (i=0;i<numf1s;i++)
820     for (j=start;j<numf2s;j++)
821       tds[i][j] = 0.0;
822 } /* end of init_td */
823
824 /* init_bu - initialize bottom up weights
825  */
826 void init_bu(int start )
827 {
828   int i,j;
829   for (i=0;i<numf1s;i++)
830     for (j=start;j<numf2s;j++)
831       bus[i][j] = 1/(1.0 - d)/sqrt((double)numf1s);
832 } /* end of init_bu */
833
834 /* load_train - load a training file into
835  *   location f1_layer[].I[spot]
836  */
837 void load_train(char *trainfile,int mode, int objects)
838 {
839    int i;
840    int fd;
841    char buffer[64];
842    char *superbuffer;
843    unsigned char t;
844    int spot;
845
846    if (mode==MODE_TRAIN1)
847    {
848      spot=0;
849    }
850    else
851    {
852      spot=1;
853    }
854
855    if ((fd=open(trainfile,O_RDONLY))==-1)
856    {
857      fprintf(stderr,"Error opening %s\n",trainfile);
858      exit(1);
859    }
860 #ifdef DEBUG
861    printf("made it to load_train. opening %s\n",trainfile);
862 #endif
863
864    lwidth = 0;
865    lheight = 0;
866
867    /* Strip Format descriptor */
868    read(fd,buffer,8);
869    /* Read width */
870    read(fd,buffer,4);
871    for (i=0;i<4;i++)
872      if (buffer[i] != ' ')
873        lwidth = lwidth * 10 + buffer[i] - '0';
874    /* Read height */
875    read(fd,buffer,4);
876    for (i=0;i<4;i++)
877      if (buffer[i] != ' ')
878        lheight = lheight * 10 + buffer[i] - '0';
879
880 #ifdef DEBUG
881    fprintf(stderr,"width %d, height %d\n",lwidth,lheight);
882 #endif
883
884    /* The first time through we set up the network
885     * based on what is read from the file.
886     * The second time through (if we have more than
887     * one training file, we make sure the parameters
888     * match what was read the first time, e.g. the
889     * f1 layer is the same size.
890     */
891    if (mode==MODE_TRAIN1)
892    {
893      numf1s = numinputs = lwidth * lheight;
894      numf2s = objects+1;
895      init_globs(MODE_TRAIN1);
896      init_net();
897    }
898    else
899    {
900      if ((lwidth * lheight)!= numf1s)
901      {
902        fprintf(stderr,"Dimensions of first image do not match");
903        fprintf(stderr," dimensions of second.\n");
904        exit(1);
905      }
906    }
907
908    superbuffer = (char *)malloc(lwidth * lheight * sizeof(char ));
909    if (superbuffer == NULL)
910    {
911       fprintf(stderr,"Problems with malloc in loadimage()\n");
912       exit(1);
913    }
914
915    read(fd,superbuffer,lwidth*lheight);
916    for (i=0;i<lheight*lwidth;i++)
917    {
918      t = superbuffer[i];
919      f1_layer[i].I[spot] = (double) t;
920    }
921
922    free (superbuffer);
923
924 } /* end of load_train */
925
926 /* This routine is used to simulate training of other objects.
927  * Training on multiple objects would consume the entire execution
928  * time of the benchmark.  Instead we train on a few then we simulate
929  * others by copying the interconnections for the objects we are trained
930  * on and then adding noise to the connections.  This simulates training on
931  * other objects.  Need to blur the objects enough to overcome ART's
932  * noise filtering.
933  */
934 void sim_other_objects(int low, int high, int stop)
935 {
936   int i,j;
937   int noise1;
938   double noise2;
939 #ifdef DEBUG
940   printf("sim other low %d high %d stop %d\n",low,high,stop);
941   printf("sim other numf2s %d numpat %d\n",numf2s,numpatterns);
942 #endif
943   if (high<=low) {
944     return;
945   }
946   srand(10);
947   for (i=low;i<high;i++) {
948     for (j=0;j<numf1s;j++) {
949       if (i%low) {
950         tds[j][i] = tds[j][0];
951         tds[j][i] = bus[j][0];
952       } else {
953         tds[j][i] = tds[j][1];
954         tds[j][i] = bus[j][1];
955       }
956     }
957   }
958   for (i=low;i<high;i++) {
959     for (j=0;j<numf1s;j++) {
960         noise1 = rand()&0xffff;
961         noise2 = (double)noise1/(double)0xffff;
962         tds[j][i] += noise2;
963         bus[j][i] += noise2;
964     }
965   }
966 #if 0
967   for (i=low;i<high;i++) {
968     for (j=0;j<numf1s;j++) {
969         fprintf(stderr,"%d %d %f\n",i,j,tds[j][i]);
970     }
971   }
972 #endif
973 } /* sim_other_objects */
974
975 void setup_base_pattern(int spot)
976 { int i,j;
977
978   for (i=0;i<numf1s;i++)
979   {
980     for (j=spot;j<numf2s;j++)
981     {
982       tds[i][j] = bus[i][j] = 1.0 /sqrt((double)numf1s) /(1-d);
983     }
984   }
985 }
986
987 void scan_recognize(int startx, int starty, int endx, int endy, int stride)
988 {
989     int i,j,m,n;
990     long k;
991
992
993     if ((starty>(height-lheight+1))||(startx>(width-lwidth+1)))
994     {
995       fprintf(stderr,"Startx %d or Starty %d is out of range\n", startx, starty);
996       exit(1);
997     }
998     if ((endy>(height-lheight+1))||(endx>(width-lwidth+1)))
999     {
1000       fprintf(stderr,"endx %d or endy %d is out of range\n", endx, endy);
1001       exit(1);
1002     }
1003 #ifdef DEBUG
1004     if (DB3)
1005     {
1006       fprintf(stdout,"made it to scan_recognize\n");
1007       fprintf(stdout,"w= %d h = %d lw = %d lh = %d\n",width,height,lwidth,lheight);
1008     }
1009 #endif
1010     for (j=starty;j<endy;j=j+stride )
1011        for (i=startx;i<endx;i=i+stride)
1012        {
1013          k=0;
1014          for (m=j;m<(lheight+j);m++)
1015            for (n=i;n<(lwidth+i);n++)
1016                f1_layer[k++].I[0] = cimage[m][n];
1017          pass_flag =0;
1018          match();
1019          if (pass_flag==1)
1020          {
1021 #ifdef DEBUG
1022             printf(" at X= %d Y = %d\n",i,j);
1023 #endif
1024             if (set_high[0]==TRUE)
1025             {
1026               highx[0] = i;
1027               highy[0] = j;
1028               set_high[0] = FALSE;
1029             }
1030             if (set_high[1]==TRUE)
1031             {
1032               highx[1] = i;
1033               highy[1] = j;
1034               set_high[1] = FALSE;
1035             }
1036          }
1037 #ifdef DEBUG
1038          else if (DB3)
1039             printf("0.00#%dx%da%2.1fb%2.1f\n",i,j,a,b);
1040 #endif
1041        }
1042 }
1043
1044
1045
1046 int main(argc,argv)
1047 int argc;
1048 char *argv[];
1049 {  int k;
1050    int startx, starty;
1051    int endx, endy;
1052    int stride;
1053    int objects;
1054    int arg_index;
1055    char *scanfile=NULL;
1056    char *weightfile=NULL;
1057    char *trainfile1=NULL;
1058    char *trainfile2=NULL;
1059
1060    if (argc<2)
1061    {
1062      goto Usage;
1063    }
1064    if (argc == 2)
1065    {
1066      if (strcmp(argv[1],"-v")==0)
1067        goto Version;
1068      else if (strcmp(argv[1],"-h")==0)
1069        goto Usage;
1070    }
1071
1072    stride = 0;
1073    startx = 0;
1074    starty = 0;
1075    endy = 0;
1076    endx = 0;
1077    objects = 0;
1078
1079    /* Read command line options */
1080    arg_index = 1;
1081    while (arg_index < argc-1)
1082    {
1083      if (strcmp(argv[arg_index],"-scanfile")==0)
1084      {
1085        scanfile= argv[arg_index+1];
1086      }
1087      else if (strcmp(argv[arg_index],"-weightfile")==0)
1088      {
1089        weightfile= argv[arg_index+1];
1090      }
1091      else if (strcmp(argv[arg_index],"-trainfile1")==0)
1092      {
1093        trainfile1= argv[arg_index+1];
1094      }
1095      else if (strcmp(argv[arg_index],"-trainfile2")==0)
1096      {
1097        trainfile2= argv[arg_index+1];
1098      }
1099      else if (strcmp(argv[arg_index],"-startx")==0)
1100      {
1101        startx = atoi(argv[arg_index+1]);
1102      }
1103      else if (strcmp(argv[arg_index],"-starty")==0)
1104      {
1105        starty = atoi(argv[arg_index+1]);
1106      }
1107      else if (strcmp(argv[arg_index],"-endx")==0)
1108      {
1109        endx = atoi(argv[arg_index+1]);
1110      }
1111      else if (strcmp(argv[arg_index],"-endy")==0)
1112      {
1113        endy = atoi(argv[arg_index+1]);
1114      }
1115      else if (strcmp(argv[arg_index],"-stride")==0)
1116      {
1117        stride = atoi(argv[arg_index+1]);
1118      }
1119      else if (strcmp(argv[arg_index],"-objects")==0)
1120      {
1121        objects = atoi(argv[arg_index+1]);
1122      }
1123      else
1124      {
1125        fprintf(stderr,"ERROR: Unknown option -> %s\n",argv[arg_index]);
1126        goto Usage;
1127      }
1128      arg_index+=2; /* this works as long as options are duals!!! */
1129    }
1130
1131    /* Some basic error checking. */
1132
1133    if (scanfile==NULL)
1134    {
1135      fprintf(stderr,"ERROR: Must specify input files\n");
1136      goto Usage;
1137    }
1138    if ((weightfile==NULL)&&(trainfile1==NULL))
1139    {
1140      fprintf(stderr,"ERROR: Must specify weightfile or trainfile1\n");
1141      goto Usage;
1142    }
1143    if ((weightfile!=NULL)&&(trainfile1!=NULL))
1144    {
1145      fprintf(stderr,"ERROR: Cannot specify weightfile and trainfile1\n");
1146      goto Usage;
1147    }
1148
1149 #ifdef DEBUG
1150    fprintf(stdout,"scanfile = %s\n weightfile = %s\n startx = %d\n starty = %d\n stride = %d\n",scanfile,weightfile,startx,starty,stride);
1151 #endif
1152
1153    loadimage(scanfile);
1154
1155    /* Differentiate between loading pretrained network (load_weights)
1156     * and training.  Currently, loading a pretrained network
1157     * supports only 1 object.  If we train, we can learn to
1158     * recognize two objects.
1159     */
1160    if (weightfile!=NULL)
1161    {
1162      numpatterns = 1;
1163      if (objects==0)
1164          {
1165         objects = numpatterns;
1166          }
1167      load_weights(weightfile);
1168      init_globs(MODE_RECOGNIZE);
1169      init_net();
1170    }
1171    else
1172    {
1173      if (trainfile2!=NULL)
1174      {
1175        numpatterns = 2;
1176        if (objects<numpatterns)
1177            {
1178           objects = numpatterns;
1179            }
1180        load_train(trainfile1,MODE_TRAIN1,objects);
1181        alloc_td_bu();
1182        init_td(0);
1183        init_bu(0);
1184        resonant=k=0;
1185        while (!resonant)
1186        {
1187 #ifdef DEBUG
1188          fprintf(stdout,"k=%d\n",k);
1189 #endif
1190          train_match(0);
1191          k++;
1192        }
1193        load_train(trainfile2,MODE_TRAIN2,objects);
1194        init_globs(MODE_TRAIN2);
1195        init_td(1);
1196        init_bu(1);
1197        resonant=k=0;
1198        while (!resonant)
1199        {
1200 #ifdef DEBUG
1201          fprintf(stdout,"k=%d\n",k);
1202 #endif
1203          train_match(1);
1204          k++;
1205        }
1206        init_globs(MODE_RECOGNIZE);
1207        init_td(objects);
1208        init_bu(objects);
1209        sim_other_objects(numpatterns,objects,numf2s);
1210        setup_base_pattern(objects);
1211      }
1212      else
1213      {
1214        numpatterns = 1;
1215        if (objects<numpatterns)
1216            {
1217           objects = numpatterns;
1218            }
1219        load_train(trainfile1,MODE_TRAIN1,objects);
1220        alloc_td_bu();
1221        init_td(0);
1222        init_bu(0);
1223        resonant=k=0;
1224        while (!resonant)
1225        {
1226 #ifdef DEBUG
1227          fprintf(stdout,"k=%d\n",k);
1228 #endif
1229          train_match(0);
1230          k++;
1231        }
1232        init_globs(MODE_RECOGNIZE);
1233        init_td(1);
1234        init_bu(1);
1235        setup_base_pattern(1);
1236      }
1237    }
1238    /* Set endx and endy if user never specified */
1239    if (endy==0)
1240    {
1241      endy=height-lheight;
1242    }
1243    if (endx==0)
1244    {
1245      endx=width-lwidth;
1246    }
1247    highest_confidence[0] = 0.0;
1248    highest_confidence[1] = 0.0;
1249    highx[0] = 0;
1250    highx[1] = 0;
1251    highy[0] = 0;
1252    highy[1] = 0;
1253    set_high[0] = FALSE;
1254    set_high[1] = FALSE;
1255
1256    scan_recognize(startx, starty, endx, endy, stride);
1257
1258    fprintf(stdout,"Highest vigilance for 1 = %0.4f for object at X = %d, Y = %d\n", highest_confidence[0], highx[0], highy[0]);
1259    if (numpatterns==2) {
1260    fprintf(stdout,"Highest vigilance for 2 = %0.4f for object at X = %d, Y = %d\n", highest_confidence[1], highx[1], highy[1]);
1261    }
1262    return 0;
1263 Usage:
1264    fprintf(stderr,"Usage: scanner [-startx <num>] [-starty <num>] [-endx <num>] [-endy <num>] [-stride <num>] -scanfile <filename> -trainfile1 <filename> [-trainfile2 <filename>]\n");
1265    exit(1);
1266 Version:
1267    fprintf(stderr,"Version 1.00 \n");
1268    exit(1);
1269 }