classify/clusttool.cpp

Go to the documentation of this file.
00001 
00020 //--------------------------Include Files----------------------------------
00021 #include "clusttool.h"
00022 #include "const.h"
00023 #include "danerror.h"
00024 #include "emalloc.h"
00025 #include "scanutils.h"
00026 #include <stdio.h>
00027 #include <math.h>
00028 
00029 //---------------Global Data Definitions and Declarations--------------------
00031 #define TOKENSIZE 80
00032 
00033 #define MAXSAMPLESIZE 65535
00034 //#define MAXBLOCKSIZE  65535   //max num of samples in a character (block size)
00035 
00036 /*---------------------------------------------------------------------------
00037           Public Code
00038 -----------------------------------------------------------------------------*/
00048 UINT16 ReadSampleSize(FILE *File) { 
00049   int SampleSize;
00050 
00051   if ((fscanf (File, "%d", &SampleSize) != 1) ||
00052     (SampleSize < 0) || (SampleSize > MAXSAMPLESIZE))
00053     DoError (ILLEGALSAMPLESIZE, "Illegal sample size");
00054   return (SampleSize);
00055 }                                // ReadSampleSize
00056 
00057 
00071 PARAM_DESC *ReadParamDesc(FILE *File, UINT16 N) { 
00072   int i;
00073   PARAM_DESC *ParamDesc;
00074   char Token[TOKENSIZE];
00075 
00076   ParamDesc = (PARAM_DESC *) Emalloc (N * sizeof (PARAM_DESC));
00077   for (i = 0; i < N; i++) {
00078     if (fscanf (File, "%s", Token) != 1)
00079       DoError (ILLEGALCIRCULARSPEC,
00080         "Illegal circular/linear specification");
00081     if (Token[0] == 'c')
00082       ParamDesc[i].Circular = TRUE;
00083     else
00084       ParamDesc[i].Circular = FALSE;
00085 
00086     if (fscanf (File, "%s", Token) != 1)
00087       DoError (ILLEGALESSENTIALSPEC,
00088         "Illegal essential/non-essential spec");
00089     if (Token[0] == 'e')
00090       ParamDesc[i].NonEssential = FALSE;
00091     else
00092       ParamDesc[i].NonEssential = TRUE;
00093     if (fscanf (File, "%f%f", &(ParamDesc[i].Min), &(ParamDesc[i].Max)) !=
00094       2)
00095       DoError (ILLEGALMINMAXSPEC, "Illegal min or max specification");
00096     ParamDesc[i].Range = ParamDesc[i].Max - ParamDesc[i].Min;
00097     ParamDesc[i].HalfRange = ParamDesc[i].Range / 2;
00098     ParamDesc[i].MidRange = (ParamDesc[i].Max + ParamDesc[i].Min) / 2;
00099   }
00100   return (ParamDesc);
00101 }                                // ReadParamDesc
00102 
00103 
00121 PROTOTYPE *ReadPrototype(FILE *File, UINT16 N) { 
00122   char Token[TOKENSIZE];
00123   int Status;
00124   PROTOTYPE *Proto;
00125   int SampleCount;
00126   int i;
00127 
00128   if ((Status = fscanf (File, "%s", Token)) == 1) {
00129     Proto = (PROTOTYPE *) Emalloc (sizeof (PROTOTYPE));
00130     Proto->Cluster = NULL;
00131     if (Token[0] == 's')
00132       Proto->Significant = TRUE;
00133     else
00134       Proto->Significant = FALSE;
00135 
00136     Proto->Style = ReadProtoStyle (File);
00137 
00138     if ((fscanf (File, "%d", &SampleCount) != 1) || (SampleCount < 0))
00139       DoError (ILLEGALSAMPLECOUNT, "Illegal sample count");
00140     Proto->NumSamples = SampleCount;
00141 
00142     Proto->Mean = ReadNFloats (File, N, NULL);
00143     if (Proto->Mean == NULL)
00144       DoError (ILLEGALMEANSPEC, "Illegal prototype mean");
00145 
00146     switch (Proto->Style) {
00147       case spherical:
00148         if (ReadNFloats (File, 1, &(Proto->Variance.Spherical)) == NULL)
00149           DoError (ILLEGALVARIANCESPEC, "Illegal prototype variance");
00150         Proto->Magnitude.Spherical =
00151           1.0 / sqrt ((double) (2.0 * PI * Proto->Variance.Spherical));
00152         Proto->TotalMagnitude =
00153           pow (Proto->Magnitude.Spherical, (double) N);
00154         Proto->LogMagnitude = log ((double) Proto->TotalMagnitude);
00155         Proto->Weight.Spherical = 1.0 / Proto->Variance.Spherical;
00156         Proto->Distrib = NULL;
00157         break;
00158       case elliptical:
00159         Proto->Variance.Elliptical = ReadNFloats (File, N, NULL);
00160         if (Proto->Variance.Elliptical == NULL)
00161           DoError (ILLEGALVARIANCESPEC, "Illegal prototype variance");
00162         Proto->Magnitude.Elliptical =
00163           (FLOAT32 *) Emalloc (N * sizeof (FLOAT32));
00164         Proto->Weight.Elliptical =
00165           (FLOAT32 *) Emalloc (N * sizeof (FLOAT32));
00166         Proto->TotalMagnitude = 1.0;
00167         for (i = 0; i < N; i++) {
00168           Proto->Magnitude.Elliptical[i] =
00169             1.0 /
00170             sqrt ((double) (2.0 * PI * Proto->Variance.Elliptical[i]));
00171           Proto->Weight.Elliptical[i] =
00172             1.0 / Proto->Variance.Elliptical[i];
00173           Proto->TotalMagnitude *= Proto->Magnitude.Elliptical[i];
00174         }
00175         Proto->LogMagnitude = log ((double) Proto->TotalMagnitude);
00176         Proto->Distrib = NULL;
00177         break;
00178       case mixed:
00179         Proto->Distrib =
00180           (DISTRIBUTION *) Emalloc (N * sizeof (DISTRIBUTION));
00181         for (i = 0; i < N; i++) {
00182           if (fscanf (File, "%s", Token) != 1)
00183             DoError (ILLEGALDISTRIBUTION,
00184               "Illegal prototype distribution");
00185           switch (Token[0]) {
00186             case 'n':
00187               Proto->Distrib[i] = normal;
00188               break;
00189             case 'u':
00190               Proto->Distrib[i] = uniform;
00191               break;
00192             case 'r':
00193               Proto->Distrib[i] = D_random;
00194               break;
00195             default:
00196               DoError (ILLEGALDISTRIBUTION,
00197                 "Illegal prototype distribution");
00198           }
00199         }
00200         Proto->Variance.Elliptical = ReadNFloats (File, N, NULL);
00201         if (Proto->Variance.Elliptical == NULL)
00202           DoError (ILLEGALVARIANCESPEC, "Illegal prototype variance");
00203         Proto->Magnitude.Elliptical =
00204           (FLOAT32 *) Emalloc (N * sizeof (FLOAT32));
00205         Proto->Weight.Elliptical =
00206           (FLOAT32 *) Emalloc (N * sizeof (FLOAT32));
00207         Proto->TotalMagnitude = 1.0;
00208         for (i = 0; i < N; i++) {
00209           switch (Proto->Distrib[i]) {
00210             case normal:
00211               Proto->Magnitude.Elliptical[i] = 1.0 /
00212                 sqrt ((double)
00213                 (2.0 * PI * Proto->Variance.Elliptical[i]));
00214               Proto->Weight.Elliptical[i] =
00215                 1.0 / Proto->Variance.Elliptical[i];
00216               break;
00217             case uniform:
00218             case D_random:
00219               Proto->Magnitude.Elliptical[i] = 1.0 /
00220                 (2.0 * Proto->Variance.Elliptical[i]);
00221               break;
00222           }
00223           Proto->TotalMagnitude *= Proto->Magnitude.Elliptical[i];
00224         }
00225         Proto->LogMagnitude = log ((double) Proto->TotalMagnitude);
00226         break;
00227     }
00228     return (Proto);
00229   }
00230   else if (Status == EOF)
00231     return (NULL);
00232   else {
00233     DoError (ILLEGALSIGNIFICANCESPEC, "Illegal significance specification");
00234     return (NULL);
00235   }
00236 }                                // ReadPrototype
00237 
00238 
00248 PROTOSTYLE ReadProtoStyle(FILE *File) { 
00249   char Token[TOKENSIZE];
00250   PROTOSTYLE Style;
00251 
00252   if (fscanf (File, "%s", Token) != 1)
00253     DoError (ILLEGALSTYLESPEC, "Illegal prototype style specification");
00254   switch (Token[0]) {
00255     case 's':
00256       Style = spherical;
00257       break;
00258     case 'e':
00259       Style = elliptical;
00260       break;
00261     case 'm':
00262       Style = mixed;
00263       break;
00264     case 'a':
00265       Style = automatic;
00266       break;
00267     default:
00268       Style = elliptical;
00269       DoError (ILLEGALSTYLESPEC, "Illegal prototype style specification");
00270   }
00271   return (Style);
00272 }                                // ReadProtoStyle
00273 
00274 
00290 FLOAT32 *
00291 ReadNFloats (FILE * File, UINT16 N, FLOAT32 Buffer[]) {
00292   int i;
00293   int NumFloatsRead;
00294 
00295   if (Buffer == NULL)
00296     Buffer = (FLOAT32 *) Emalloc (N * sizeof (FLOAT32));
00297 
00298   for (i = 0; i < N; i++) {
00299     NumFloatsRead = fscanf (File, "%f", &(Buffer[i]));
00300     if (NumFloatsRead != 1) {
00301       if ((NumFloatsRead == EOF) && (i == 0))
00302         return (NULL);
00303       else
00304         DoError (ILLEGALFLOAT, "Illegal float specification");
00305     }
00306   }
00307   return (Buffer);
00308 }                                // ReadNFloats
00309 
00310 
00321 void
00322 WriteParamDesc (FILE * File, UINT16 N, PARAM_DESC ParamDesc[]) {
00323   int i;
00324 
00325   for (i = 0; i < N; i++) {
00326     if (ParamDesc[i].Circular)
00327       fprintf (File, "circular ");
00328     else
00329       fprintf (File, "linear   ");
00330 
00331     if (ParamDesc[i].NonEssential)
00332       fprintf (File, "non-essential ");
00333     else
00334       fprintf (File, "essential     ");
00335 
00336     fprintf (File, "%10.6f %10.6f\n", ParamDesc[i].Min, ParamDesc[i].Max);
00337   }
00338 }                                // WriteParamDesc
00339 
00340 
00352 void WritePrototype(FILE *File, UINT16 N, PROTOTYPE *Proto) { 
00353   int i;
00354 
00355   if (Proto->Significant)
00356     fprintf (File, "significant   ");
00357   else
00358     fprintf (File, "insignificant ");
00359   WriteProtoStyle (File, (PROTOSTYLE) Proto->Style);
00360   fprintf (File, "%6d\n\t", Proto->NumSamples);
00361   WriteNFloats (File, N, Proto->Mean);
00362   fprintf (File, "\t");
00363 
00364   switch (Proto->Style) {
00365     case spherical:
00366       WriteNFloats (File, 1, &(Proto->Variance.Spherical));
00367       break;
00368     case elliptical:
00369       WriteNFloats (File, N, Proto->Variance.Elliptical);
00370       break;
00371     case mixed:
00372       for (i = 0; i < N; i++)
00373       switch (Proto->Distrib[i]) {
00374         case normal:
00375           fprintf (File, " %9s", "normal");
00376           break;
00377         case uniform:
00378           fprintf (File, " %9s", "uniform");
00379           break;
00380         case D_random:
00381           fprintf (File, " %9s", "random");
00382           break;
00383       }
00384       fprintf (File, "\n\t");
00385       WriteNFloats (File, N, Proto->Variance.Elliptical);
00386   }
00387 }                                // WritePrototype
00388 
00389 
00403 void
00404 WriteNFloats (FILE * File, UINT16 N, FLOAT32 Array[]) {
00405   int i;
00406 
00407   for (i = 0; i < N; i++)
00408     fprintf (File, " %9.6f", Array[i]);
00409   fprintf (File, "\n");
00410 }                                // WriteNFloats
00411 
00412 
00423 void WriteProtoStyle(FILE *File, PROTOSTYLE ProtoStyle) { 
00424   switch (ProtoStyle) {
00425     case spherical:
00426       fprintf (File, "spherical");
00427       break;
00428     case elliptical:
00429       fprintf (File, "elliptical");
00430       break;
00431     case mixed:
00432       fprintf (File, "mixed");
00433       break;
00434     case automatic:
00435       fprintf (File, "automatic");
00436       break;
00437   }
00438 }                                // WriteProtoStyle
00439 
00457 void WriteProtoList(
00458      FILE   *File,
00459      UINT16 N,
00460      PARAM_DESC   ParamDesc[],
00461      LIST   ProtoList,
00462      BOOL8  WriteSigProtos,
00463      BOOL8  WriteInsigProtos)
00464 {
00465   PROTOTYPE *Proto;
00466   
00467   /* write file header */
00468   fprintf(File,"%0d\n",N);
00469   WriteParamDesc(File,N,ParamDesc);
00470 
00471   /* write prototypes */
00472   iterate(ProtoList)
00473     {
00474       Proto = (PROTOTYPE *) first ( ProtoList );
00475       if (( Proto->Significant && WriteSigProtos ) ||
00476      ( ! Proto->Significant && WriteInsigProtos ) )
00477    WritePrototype( File, N, Proto );
00478     }
00479 }  /* WriteProtoList */
00480 
00491 FLOAT32 UniformRandomNumber(FLOAT32 MMin, FLOAT32 MMax) { 
00492   double fake_drand48(); 
00493   FLOAT32 RandomNumber;
00494 
00495   RandomNumber = fake_drand48 ();
00496   return (MMin + (RandomNumber * (MMax - MMin)));
00497 }                                // UniformRandomNumber
00498 
00499 
00504 double fake_drand48() { 
00505   return rand () / (RAND_MAX + 1.0);
00506 }

Generated on Wed Feb 28 19:49:09 2007 for Tesseract by  doxygen 1.5.1