classify/intmatcher.cpp

Go to the documentation of this file.
00001 
00024 /* =================
00025  Include Files and Type Defines
00026  ==================== */
00027 #include "intmatcher.h"
00028 #include "tordvars.h"
00029 #include "callcpp.h"
00030 #include <math.h>
00031 
00032 #define CLASS_MASK_SIZE ((MAX_NUM_CLASSES*NUM_BITS_PER_CLASS \
00033       +BITS_PER_WERD-1)/BITS_PER_WERD)
00034 
00035 /* =================
00036  Global Data Definitions and Declarations
00037  ==================== */
00038 #define  SE_TABLE_BITS    9
00039 #define  SE_TABLE_SIZE  512
00040 #define TEMPLATE_CACHE 2
00041 static UINT8 SimilarityEvidenceTable[SE_TABLE_SIZE];
00048 static UINT8 offset_table[256] = {
00049   255, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00050   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00051   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00052   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00053   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00054   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00055   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00056   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00057   7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00058   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00059   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00060   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00061   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00062   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00063   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00064   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
00065 };
00072 static UINT8 next_table[256] = {
00073   0, 0, 0, 0x2, 0, 0x4, 0x4, 0x6, 0, 0x8, 0x8, 0x0a, 0x08, 0x0c, 0x0c, 0x0e,
00074   0, 0x10, 0x10, 0x12, 0x10, 0x14, 0x14, 0x16, 0x10, 0x18, 0x18, 0x1a, 0x18,
00075   0x1c, 0x1c, 0x1e,
00076   0, 0x20, 0x20, 0x22, 0x20, 0x24, 0x24, 0x26, 0x20, 0x28, 0x28, 0x2a, 0x28,
00077   0x2c, 0x2c, 0x2e,
00078   0x20, 0x30, 0x30, 0x32, 0x30, 0x34, 0x34, 0x36, 0x30, 0x38, 0x38, 0x3a,
00079   0x38, 0x3c, 0x3c, 0x3e,
00080   0, 0x40, 0x40, 0x42, 0x40, 0x44, 0x44, 0x46, 0x40, 0x48, 0x48, 0x4a, 0x48,
00081   0x4c, 0x4c, 0x4e,
00082   0x40, 0x50, 0x50, 0x52, 0x50, 0x54, 0x54, 0x56, 0x50, 0x58, 0x58, 0x5a,
00083   0x58, 0x5c, 0x5c, 0x5e,
00084   0x40, 0x60, 0x60, 0x62, 0x60, 0x64, 0x64, 0x66, 0x60, 0x68, 0x68, 0x6a,
00085   0x68, 0x6c, 0x6c, 0x6e,
00086   0x60, 0x70, 0x70, 0x72, 0x70, 0x74, 0x74, 0x76, 0x70, 0x78, 0x78, 0x7a,
00087   0x78, 0x7c, 0x7c, 0x7e,
00088   0, 0x80, 0x80, 0x82, 0x80, 0x84, 0x84, 0x86, 0x80, 0x88, 0x88, 0x8a, 0x88,
00089   0x8c, 0x8c, 0x8e,
00090   0x80, 0x90, 0x90, 0x92, 0x90, 0x94, 0x94, 0x96, 0x90, 0x98, 0x98, 0x9a,
00091   0x98, 0x9c, 0x9c, 0x9e,
00092   0x80, 0xa0, 0xa0, 0xa2, 0xa0, 0xa4, 0xa4, 0xa6, 0xa0, 0xa8, 0xa8, 0xaa,
00093   0xa8, 0xac, 0xac, 0xae,
00094   0xa0, 0xb0, 0xb0, 0xb2, 0xb0, 0xb4, 0xb4, 0xb6, 0xb0, 0xb8, 0xb8, 0xba,
00095   0xb8, 0xbc, 0xbc, 0xbe,
00096   0x80, 0xc0, 0xc0, 0xc2, 0xc0, 0xc4, 0xc4, 0xc6, 0xc0, 0xc8, 0xc8, 0xca,
00097   0xc8, 0xcc, 0xcc, 0xce,
00098   0xc0, 0xd0, 0xd0, 0xd2, 0xd0, 0xd4, 0xd4, 0xd6, 0xd0, 0xd8, 0xd8, 0xda,
00099   0xd8, 0xdc, 0xdc, 0xde,
00100   0xc0, 0xe0, 0xe0, 0xe2, 0xe0, 0xe4, 0xe4, 0xe6, 0xe0, 0xe8, 0xe8, 0xea,
00101   0xe8, 0xec, 0xec, 0xee,
00102   0xe0, 0xf0, 0xf0, 0xf2, 0xf0, 0xf4, 0xf4, 0xf6, 0xf0, 0xf8, 0xf8, 0xfa,
00103   0xf8, 0xfc, 0xfc, 0xfe
00104 };
00111 static int cp_maxes[128] = {
00112   100,
00113   100, 100, 100, 100, 100, 100, 100, 100,
00114   100, 100, 100, 100, 100, 100, 100, 100,
00115   100, 100, 100, 100, 100, 100, 100, 100,
00116   100, 100, 100, 100, 100, 100, 100, 100,
00117   194,                           
00118   100,                           //"
00119   182,                           //#
00120   224,                           //$
00121   203,                           //%
00122   242,                           //&
00123   245,                           //'
00124   226,                           //(
00125   190,                           //)
00126   244,                           //*
00127   195,                           //+
00128   254,                           //,
00129   253,                           //-
00130   253,                           //.
00131   206,                           
00132   253,                           //0
00133   234,                           //1
00134   252,                           //2
00135   246,                           //3
00136   253,                           //4
00137   160,                           //5
00138   202,                           //6
00139   199,                           //7
00140   171,                           //8
00141   227,                           //9
00142   208,                           //:
00143   188,                           //;
00144   60,                            //<
00145   221,                           //=
00146   138,                           //>
00147   108,                           //?
00148   98,                            //@
00149   251,                           //A
00150   214,                           //B
00151   230,                           //C
00152   252,                           //D
00153   237,                           //E
00154   217,                           //F
00155   233,                           //G
00156   174,                           //H
00157   216,                           //I
00158   210,                           //J
00159   252,                           //K
00160   253,                           //L
00161   233,                           //M
00162   243,                           //N
00163   240,                           //O
00164   230,                           //P
00165   167,                           //Q
00166   248,                           //R
00167   250,                           //S
00168   232,                           //T
00169   209,                           //U
00170   193,                           //V
00171   254,                           //W
00172   146,                           //X
00173   198,                           //Y
00174   107,                           //Z
00175   167,                           //[
00176   163,                           //
00177   73,                            //]
00178   16,                            //^
00179   199,                           //_
00180   162,                           //`
00181   251,                           //a
00182   250,                           //b
00183   254,                           //c
00184   253,                           //d
00185   252,                           //e
00186   253,                           //f
00187   248,                           //g
00188   251,                           //h
00189   254,                           //i
00190   201,                           //j
00191   224,                           //k
00192   253,                           //l
00193   242,                           //m
00194   254,                           //n
00195   254,                           //o
00196   253,                           //p
00197   246,                           //q
00198   254,                           //r
00199   254,                           //s
00200   254,                           //t
00201   245,                           //u
00202   221,                           //v
00203   230,                           //w
00204   251,                           //x
00205   243,                           //y
00206   133,                           //z
00207   35,                            //{
00208   100,                           //|
00209   143,                           //}
00210   100,                           //~
00211   100
00212 };
00213 
00219 static float cp_ratios[128] = {
00220   1.5f,
00221   1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f,
00222   1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f,
00223   1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f,
00224   1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f,
00225   2.24775,                       
00226   1.5,                           //"
00227   1.90376,                       //#
00228   1.61443,                       //$
00229   1.87857,                       //%
00230   2.29167,                       //&
00231   7.4,                           //'
00232   4.7,                           //(
00233   9.4,                           //)
00234   2.13014,                       //*
00235   1.53175,                       //+
00236   2.86957,                       //,
00237   7.4,                           //-
00238   7.4,                           //.
00239   9.4,                           
00240   8.1,                           //0
00241   12.6,                          //1
00242   2.7439,                        //2
00243   4.22222,                       //3
00244   2.57447,                       //4
00245   2.93902,                       //5
00246   4.23684,                       //6
00247   6,                             //7
00248   2.78889,                       //8
00249   3.55,                          //9
00250   8.5,                           //:
00251   2.4,                           //;
00252   1.5,                           //<
00253   1.94737,                       //=
00254   1.89394,                       //>
00255   1.5,                           //?
00256   1.5,                           //@
00257   3.125,                         //A
00258   5.5,                           //B
00259   6.1,                           //C
00260   6,                             //D
00261   2.78205,                       //E
00262   2.03763,                       //F
00263   2.73256,                       //G
00264   2.57692,                       //H
00265   11.8,                          //I
00266   7.1,                           //J
00267   1.85227,                       //K
00268   7.4,                           //L
00269   2.26056,                       //M
00270   2.46078,                       //N
00271   6.85714,                       //O
00272   3.45238,                       //P
00273   2.47222,                       //Q
00274   3.74,                          //R
00275   10.2,                          //S
00276   3.08065,                       //T
00277   6.1,                           //U
00278   9.5,                           //V
00279   7.1,                           //W
00280   7.9,                           //X
00281   2.55714,                       //Y
00282   7.7,                           //Z
00283   2,                             //[
00284   1.5,                           //
00285   2.55714,                       //]
00286   1.5,                           //^
00287   1.80065,                       //_
00288   1.69512,                       //`
00289   5.34,                          //a
00290   7.3,                           //b
00291   6.43333,                       //c
00292   4.10606,                       //d
00293   4.41667,                       //e
00294   12.6,                          //f
00295   3.7093,                        //g
00296   2.38889,                       //h
00297   5.5,                           //i
00298   4.03125,                       //j
00299   2.24561,                       //k
00300   11.5,                          //l
00301   3.5,                           //m
00302   5.63333,                       //n
00303   11,                            //o
00304   2.52667,                       //p
00305   2.1129,                        //q
00306   6.56667,                       //r
00307   6.42857,                       //s
00308   11.4,                          //t
00309   3.62,                          //u
00310   2.77273,                       //v
00311   2.90909,                       //w
00312   6.5,                           //x
00313   4.98387,                       //y
00314   2.92857,                       //z
00315   1.5,                           //{
00316   1.5,                           //|
00317   2.02128,                       //}
00318   1.5,                           //~
00319   1.5f
00320 };
00326 static INT8 miss_table[256] = {
00327   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00328   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00329   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00330   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00331   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00332   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00333   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00334   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00335   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00336   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00337   4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
00338   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00339   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00340   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00341   3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1,
00342   2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 0
00343 };
00344 
00345 static UINT32 EvidenceTableMask;
00346 
00347 static UINT32 MultTruncShiftBits;
00348 
00349 static UINT32 TableTruncShiftBits;
00350 
00351 UINT32 EvidenceMultMask;
00352 
00353 static INT16 LocalMatcherMultiplier;
00354 
00357 make_int_var (ClassPrunerThreshold, 229, MakeClassPrunerThreshold,
00358 16, 20, SetClassPrunerThreshold,
00359 "Class Pruner Threshold 0-255:        ");
00360 
00361 make_int_var (ClassPrunerMultiplier, 15, MakeClassPrunerMultiplier,
00362 16, 21, SetClassPrunerMultiplier,
00363 "Class Pruner Multiplier 0-255:       ");
00364 
00365 make_int_var (IntegerMatcherMultiplier, 14, MakeIntegerMatcherMultiplier,
00366 16, 22, SetIntegerMatcherMultiplier,
00367 "Integer Matcher Multiplier  0-255:   ");
00368 
00369 make_int_var (IntThetaFudge, 128, MakeIntThetaFudge,
00370 16, 23, SetIntThetaFudge,
00371 "Integer Matcher Theta Fudge 0-255:   ");
00372 
00373 make_float_var (CPCutoffStrength, 0.15, MakeCPCutoffStrength,
00374 16, 24, SetCPCutoffStrength,
00375 "Class Pruner CutoffStrength:         ");
00376 
00377 make_int_var (EvidenceTableBits, 9, MakeEvidenceTableBits,
00378 16, 25, SetEvidenceTableBits,
00379 "Bits in Similarity to Evidence Lookup  8-9:   ");
00380 
00381 make_int_var (IntEvidenceTruncBits, 14, MakeIntEvidenceTruncBits,
00382 16, 26, SetIntEvidenceTruncBits,
00383 "Integer Evidence Truncation Bits (Distance) 8-14:   ");
00384 
00385 make_float_var (SEExponentialMultiplier, 0, MakeSEExponentialMultiplier,
00386 16, 27, SetSEExponentialMultiplier,
00387 "Similarity to Evidence Table Exponential Multiplier: ");
00388 
00389 make_float_var (SimilarityCenter, 0.0075, MakeSimilarityCenter,
00390 16, 28, SetSimilarityCenter, "Center of Similarity Curve: ");
00391 
00392 make_int_var (AdaptProtoThresh, 230, MakeAdaptProtoThresh,
00393 16, 29, SetAdaptProtoThresh,
00394 "Threshold for good protos during adaptive 0-255:   ");
00395 
00396 make_int_var (AdaptFeatureThresh, 230, MakeAdaptFeatureThresh,
00397 16, 30, SetAdaptFeatureThresh,
00398 "Threshold for good features during adaptive 0-255:   ");
00401 //extern int display_ratings;
00402 //extern "C" int            newcp_ratings_on;
00403 //extern "C" double         newcp_prune_threshold;
00404 //extern "C" double         tessedit_cp_ratio;
00405 //extern "C" int            feature_prune_percentile;
00406 //extern INT32              cp_maps[4];
00407 
00408 /*
00409 Other than being printed, these don't seem to be used in v1.03
00410 */
00411 int protoword_lookups;
00412 int zero_protowords;
00413 int proto_shifts;
00414 int set_proto_bits;
00415 int config_shifts;
00416 int set_config_bits;
00417 
00418 /* =================
00419  Public Code
00420  ==================== */
00441 int ClassPruner(INT_TEMPLATES IntTemplates,
00442                 INT16 NumFeatures,
00443                 INT_FEATURE_ARRAY Features,
00444                 CLASS_NORMALIZATION_ARRAY NormalizationFactors,
00445                 CLASS_CUTOFF_ARRAY ExpectedNumFeatures,
00446                 CLASS_PRUNER_RESULTS Results,
00447                 int Debug) {
00448   UINT32 PrunerWord;
00449   INT32 class_index;             // index to class
00450   int Word;
00451   UINT32 *BasePrunerAddress;
00452   UINT32 feature_address;        // current feature index
00453   INT_FEATURE feature;           // current feature
00454   CLASS_PRUNER *ClassPruner;
00455   int PrunerSet;
00456   int NumPruners;
00457   INT32 feature_index;           // current feature
00458 
00459   static INT32 ClassCount[MAX_NUM_CLASSES - 1];
00460   static INT16 NormCount[MAX_NUM_CLASSES - 1];
00461   static INT16 SortKey[MAX_NUM_CLASSES];
00462   static UINT8 SortIndex[MAX_NUM_CLASSES];
00463   CLASS_INDEX Class;
00464   int out_class;
00465   int MaxNumClasses;
00466   int MaxCount;
00467   int NumClasses;
00468   FLOAT32 max_rating;            // max allowed rating
00469   INT32 *ClassCountPtr;
00470   INT8 classch;
00471 
00472   MaxNumClasses = NumClassesIn (IntTemplates);
00473 
00474   /* Clear Class Counts */
00475   ClassCountPtr = &(ClassCount[0]);
00476   for (Class = 0; Class < MaxNumClasses; Class++) {
00477     *ClassCountPtr++ = 0;
00478   }
00479 
00480   /* Update Class Counts */
00481   NumPruners = NumClassPrunersIn (IntTemplates);
00482   for (feature_index = 0; feature_index < NumFeatures; feature_index++) {
00483     feature = &Features[feature_index];
00484     feature->CP_misses = 0;
00485     feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS
00486       +
00487       (feature->Y * NUM_CP_BUCKETS >> 8)) *
00488       NUM_CP_BUCKETS +
00489       (feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
00490     ClassPruner = ClassPrunersFor (IntTemplates);
00491     class_index = 0;
00492     for (PrunerSet = 0; PrunerSet < NumPruners; PrunerSet++, ClassPruner++) {
00493       BasePrunerAddress = (UINT32 *) (*ClassPruner) + feature_address;
00494 
00495       for (Word = 0; Word < WERDS_PER_CP_VECTOR; Word++) {
00496         PrunerWord = *BasePrunerAddress++;
00497         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00498         PrunerWord >>= 2;
00499         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00500         PrunerWord >>= 2;
00501         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00502         PrunerWord >>= 2;
00503         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00504         PrunerWord >>= 2;
00505         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00506         PrunerWord >>= 2;
00507         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00508         PrunerWord >>= 2;
00509         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00510         PrunerWord >>= 2;
00511         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00512         PrunerWord >>= 2;
00513         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00514         PrunerWord >>= 2;
00515         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00516         PrunerWord >>= 2;
00517         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00518         PrunerWord >>= 2;
00519         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00520         PrunerWord >>= 2;
00521         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00522         PrunerWord >>= 2;
00523         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00524         PrunerWord >>= 2;
00525         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00526         PrunerWord >>= 2;
00527         ClassCount[class_index++] += cp_maps[PrunerWord & 3];
00528       }
00529     }
00530   }
00531 
00532   /* Adjust Class Counts for Number of Expected Features */
00533   for (Class = 0; Class < MaxNumClasses; Class++)
00534     if (NumFeatures < ExpectedNumFeatures[Class])
00535       ClassCount[Class] =
00536         (int) (((FLOAT32) (ClassCount[Class] * NumFeatures)) /
00537         (NumFeatures +
00538         CPCutoffStrength * (ExpectedNumFeatures[Class] -
00539         NumFeatures)));
00540 
00541   /* Adjust Class Counts for Normalization Factors */
00542   MaxCount = 0;
00543   for (Class = 0; Class < MaxNumClasses; Class++) {
00544     NormCount[Class] = ClassCount[Class]
00545       - ((ClassPrunerMultiplier * NormalizationFactors[Class]) >> 8)
00546       * cp_maps[3] / 3;
00547     if (NormCount[Class] > MaxCount)
00548       MaxCount = NormCount[Class];
00549   }
00550 
00551   /* Prune Classes */
00552   MaxCount *= ClassPrunerThreshold;
00553   MaxCount >>= 8;
00554   /* Select Classes */
00555   if (MaxCount < 1)
00556     MaxCount = 1;
00557   NumClasses = 0;
00558   for (Class = 0; Class < MaxNumClasses; Class++)
00559   if (NormCount[Class] >= MaxCount) {
00560     NumClasses++;
00561     SortIndex[NumClasses] = Class;
00562     SortKey[NumClasses] = NormCount[Class];
00563   }
00564 
00565   /* Sort Classes using Heapsort Algorithm */
00566   if (NumClasses > 1)
00567     HeapSort(NumClasses, SortKey, SortIndex);
00568 
00569   if (display_ratings > 1) {
00570     cprintf ("CP:%d classes, %d features:\n", NumClasses, NumFeatures);
00571     for (Class = 0; Class < NumClasses; Class++) {
00572       classch =
00573         ClassIdForIndex (IntTemplates, SortIndex[NumClasses - Class]);
00574       cprintf ("%c:C=%d, E=%d, N=%d, Rat=%d\n", classch,
00575         ClassCount[SortIndex[NumClasses - Class]],
00576         ExpectedNumFeatures[SortIndex[NumClasses - Class]],
00577         SortKey[NumClasses - Class],
00578         (int) (10 +
00579         1000 * (1.0f -
00580         SortKey[NumClasses -
00581         Class] / ((float) cp_maps[3] *
00582         NumFeatures))));
00583     }
00584     if (display_ratings > 2) {
00585       NumPruners = NumClassPrunersIn (IntTemplates);
00586       for (feature_index = 0; feature_index < NumFeatures;
00587       feature_index++) {
00588         cprintf ("F=%3d,", feature_index);
00589         feature = &Features[feature_index];
00590         feature->CP_misses = 0;
00591         feature_address =
00592           (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS +
00593           (feature->Y * NUM_CP_BUCKETS >> 8)) * NUM_CP_BUCKETS +
00594           (feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
00595         ClassPruner = ClassPrunersFor (IntTemplates);
00596         class_index = 0;
00597         for (PrunerSet = 0; PrunerSet < NumPruners;
00598         PrunerSet++, ClassPruner++) {
00599           BasePrunerAddress = (UINT32 *) (*ClassPruner)
00600             + feature_address;
00601 
00602           for (Word = 0; Word < WERDS_PER_CP_VECTOR; Word++) {
00603             PrunerWord = *BasePrunerAddress++;
00604             for (Class = 0; Class < 16; Class++, class_index++) {
00605               if (NormCount[class_index] >= MaxCount)
00606                 cprintf (" %c=%d,",
00607                   ClassIdForIndex (IntTemplates,
00608                   class_index),
00609                   PrunerWord & 3);
00610               PrunerWord >>= 2;
00611             }
00612           }
00613         }
00614         cprintf ("\n");
00615       }
00616       cprintf ("Adjustments:");
00617       for (Class = 0; Class < MaxNumClasses; Class++) {
00618         if (NormCount[Class] > MaxCount)
00619           cprintf (" %c=%d,",
00620             ClassIdForIndex (IntTemplates, Class),
00621             -((ClassPrunerMultiplier *
00622             NormalizationFactors[Class]) >> 8) * cp_maps[3] /
00623             3);
00624       }
00625       cprintf ("\n");
00626     }
00627   }
00628 
00629   /* Set Up Results */
00630   max_rating = 0.0f;
00631   for (Class = 0, out_class = 0; Class < NumClasses; Class++) {
00632     Results[out_class].Class =
00633       ClassIdForIndex (IntTemplates, SortIndex[NumClasses - Class]);
00634     Results[out_class].config_mask = (UINT32) - 1;
00635     Results[out_class].Rating =
00636       1.0 - SortKey[NumClasses -
00637       Class] / ((float) cp_maps[3] * NumFeatures);
00638      Results[out_class].Rating2 =
00639       1.0 - SortKey[NumClasses -
00640       Class] / ((float) cp_maps[3] * NumFeatures);
00641     if (tessedit_cp_ratio == 0.0 || Class == 0
00642       || Results[out_class].Rating * 1000 + 10 <
00643       cp_maxes[Results[out_class].Class]
00644       && Results[out_class].Rating * 1000 + 10 <
00645       (Results[0].Rating * 1000 +
00646       10) * cp_ratios[Results[out_class].Class])
00647       out_class++;
00648   }
00649   NumClasses = out_class;
00650   if (blob_type != 0) {
00651     cp_classes = NumClasses;
00652     if (NumClasses > 0) {
00653       cp_chars[0] = Results[0].Class;
00654       cp_ratings[0] = (int) (1000 * Results[0].Rating + 10);
00655       cp_confs[0] = (int) (1000 * Results[0].Rating2 + 10);
00656       if (NumClasses > 1) {
00657         cp_chars[1] = Results[1].Class;
00658         cp_ratings[1] = (int) (1000 * Results[1].Rating + 10);
00659         cp_confs[1] = (int) (1000 * Results[1].Rating2 + 10);
00660       }
00661       else {
00662         cp_chars[1] = '~';
00663         cp_ratings[1] = -1;
00664         cp_confs[1] = -1;
00665       }
00666     }
00667     else {
00668       cp_chars[0] = '~';
00669       cp_ratings[0] = -1;
00670       cp_confs[0] = -1;
00671     }
00672     cp_bestindex = -1;
00673     cp_bestrating = -1;
00674     cp_bestconf = -1;
00675     for (Class = 0; Class < NumClasses; Class++) {
00676       classch = Results[Class].Class;
00677       if (classch == blob_answer) {
00678         cp_bestindex = Class;
00679         cp_bestrating = (int) (1000 * Results[Class].Rating + 10);
00680         cp_bestconf = (int) (1000 * Results[Class].Rating2 + 10);
00681       }
00682     }
00683   }
00684   return NumClasses;
00685 
00686 }
00687 
00688 
00689 /* =============================== */
00708 int feature_pruner(INT_TEMPLATES IntTemplates,
00709                    INT16 NumFeatures,
00710                    INT_FEATURE_ARRAY Features,
00711                    INT32 NumClasses,
00712                    CLASS_PRUNER_RESULTS Results) {
00713   UINT32 PrunerWord;
00714   CLASS_PRUNER *ClassPruner;
00715   INT32 class_index;             // index to class
00716   INT32 result_index;            // CP results index
00717   int PrunerSet;
00718   int NumPruners;
00719   int Word;
00720   INT_FEATURE feature;           // current feature
00721   INT32 feature_index;           // current feature
00722   INT32 CP_misses;               // missed features
00723   UINT32 feature_address;        // current feature index
00724   UINT32 *BasePrunerAddress;
00725   int MaxNumClasses;
00726   UINT32 class_mask[CLASS_MASK_SIZE];
00727   INT32 miss_histogram[MAX_NUM_CLASSES];
00728 
00729   MaxNumClasses = NumClassesIn (IntTemplates);
00730   for (class_index = 0; class_index < MaxNumClasses; class_index++)
00731     miss_histogram[class_index] = 0;
00732 
00733   /* Create class mask */
00734   for (class_index = 0; class_index < CLASS_MASK_SIZE; class_index++)
00735     class_mask[class_index] = (UINT32) - 1;
00736   for (result_index = 0; result_index < NumClasses; result_index++) {
00737     class_index =
00738       IndexForClassId (IntTemplates, Results[result_index].Class);
00739     class_mask[class_index / CLASSES_PER_CP_WERD] &=
00740       ~(3 << (class_index % CLASSES_PER_CP_WERD) * 2);
00741   }
00742 
00743   /* Update Class Counts */
00744   NumPruners = NumClassPrunersIn (IntTemplates);
00745   for (feature_index = 0; feature_index < NumFeatures; feature_index++) {
00746     feature = &Features[feature_index];
00747     feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS
00748       +
00749       (feature->Y * NUM_CP_BUCKETS >> 8)) *
00750       NUM_CP_BUCKETS +
00751       (feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
00752     CP_misses = 0;
00753     ClassPruner = ClassPrunersFor (IntTemplates);
00754     class_index = 0;
00755     for (PrunerSet = 0; PrunerSet < NumPruners; PrunerSet++, ClassPruner++) {
00756       BasePrunerAddress = (UINT32 *) (*ClassPruner) + feature_address;
00757 
00758       for (Word = 0; Word < WERDS_PER_CP_VECTOR; Word++) {
00759         PrunerWord = *BasePrunerAddress++;
00760         PrunerWord |= class_mask[class_index++];
00761         CP_misses += miss_table[PrunerWord & 255];
00762         PrunerWord >>= 8;
00763         CP_misses += miss_table[PrunerWord & 255];
00764         PrunerWord >>= 8;
00765         CP_misses += miss_table[PrunerWord & 255];
00766         PrunerWord >>= 8;
00767         CP_misses += miss_table[PrunerWord & 255];
00768       }
00769     }
00770     feature->CP_misses = CP_misses;
00771     if (display_ratings > 1) {
00772       cprintf ("F=%d: misses=%d\n", feature_index, CP_misses);
00773     }
00774     miss_histogram[CP_misses]++;
00775   }
00776 
00777   CP_misses = 0;
00778   feature_index = NumFeatures * feature_prune_percentile / 100;
00779   for (class_index = MaxNumClasses - 1; class_index >= 0; class_index--) {
00780     CP_misses += miss_histogram[class_index];
00781     if (CP_misses >= feature_index)
00782       break;
00783   }
00784 
00785   if (display_ratings > 1) {
00786     cprintf ("FP:Selected miss factor of %d for %d features (%g%%)\n",
00787       class_index, CP_misses, 100.0 * CP_misses / NumFeatures);
00788   }
00789   return class_index;
00790 }
00791 
00792 
00793 /* =============================== */
00816 int prune_configs(INT_TEMPLATES IntTemplates,
00817                   INT32 min_misses,
00818                   INT16 NumFeatures,
00819                   INT_FEATURE_ARRAY Features,
00820                   CLASS_NORMALIZATION_ARRAY NormalizationFactors,
00821                   INT32 class_count,
00822                   UINT16 BlobLength,
00823                   CLASS_PRUNER_RESULTS Results,
00824                   int Debug) {
00825   INT32 classindex;              // current Results index
00826   CLASS_INDEX Class;             // current class
00827   INT_CLASS ClassTemplate;       // info on current class
00828   FLOAT32 best_rating;           // best over all classes
00829   FLOAT32 best_class_rating;     // best over all classes
00830   INT32 output_count;            // number of classes out
00831   INT32 best_index;              // for sorting
00832   INT_RESULT_STRUCT IntResult;
00833   CLASS_PRUNER_RESULTS new_results; // results of pruning
00834 
00835   best_class_rating = 9999.0f;
00836   for (classindex = 0; classindex < class_count; classindex++) {
00837     Class = IndexForClassId (IntTemplates, Results[classindex].Class);
00838     ClassTemplate = ClassForIndex (IntTemplates, Class);
00839     PruningMatcher (ClassTemplate, BlobLength, NumFeatures, Features,
00840       min_misses, NormalizationFactors[Class],
00841       &IntResult, Debug);
00842 
00843     /* Prune configs */
00844                                  //save old rating
00845     new_results[classindex].Rating2 = Results[classindex].Rating;
00846                                  //save new rating
00847     new_results[classindex].Rating = IntResult.Rating;
00848                                  //save new rating
00849     new_results[classindex].config_mask = (1 << IntResult.Config) | (1 << IntResult.Config2);
00850                                  //save old class
00851     new_results[classindex].Class = Results[classindex].Class;
00852 
00853     if (display_ratings > 1) {
00854       cprintf ("PC:%c: old=%g, best_rating=%g, config1=%d, config2=%d\n",
00855         Results[classindex].Class,
00856         Results[classindex].Rating2,
00857         IntResult.Rating, IntResult.Config, IntResult.Config2);
00858     }
00859 
00860     if (IntResult.Rating < best_class_rating)
00861       best_class_rating = IntResult.Rating;
00862   }
00863   /* Select Classes */
00864   best_class_rating *= newcp_prune_threshold;
00865 
00866   output_count = 0;
00867   do {
00868     best_rating = best_class_rating;
00869     best_index = -1;
00870     for (classindex = 0; classindex < class_count; classindex++) {
00871       if (new_results[classindex].Rating <= best_rating) {
00872         best_rating = new_results[classindex].Rating;
00873         best_index = classindex;
00874       }
00875     }
00876     if (best_index >= 0) {
00877       Results[output_count].Class = new_results[best_index].Class;
00878       Results[output_count].Rating = best_rating;
00879       Results[output_count].Rating2 = new_results[best_index].Rating2;
00880       Results[output_count].config_mask =
00881         new_results[best_index].config_mask;
00882       new_results[best_index].Rating = 9999.0f;
00883       output_count++;
00884     }
00885   }
00886   while (best_index >= 0);
00887 
00888   if (display_ratings > 1) {
00889     cprintf ("%d classes reduced to %d\n", class_count, output_count);
00890     for (classindex = 0; classindex < output_count; classindex++) {
00891       cprintf ("%c=%g/%g/0x%x, ",
00892         Results[classindex].Class,
00893         Results[classindex].Rating,
00894         Results[classindex].Rating2,
00895         Results[classindex].config_mask);
00896     }
00897     cprintf ("\n");
00898   }
00899   return output_count;
00900 }
00901 
00902 
00903 /* =============================== */
00927 void PruningMatcher(INT_CLASS ClassTemplate,
00928                     UINT16 BlobLength,
00929                     INT16 NumFeatures,
00930                     INT_FEATURE_ARRAY Features,
00931                     INT32 min_misses,
00932                     UINT8 NormalizationFactor,
00933                     INT_RESULT Result,
00934                     int Debug) {
00935   static UINT8 FeatureEvidence[MAX_NUM_CONFIGS];
00936   static int SumOfFeatureEvidence[MAX_NUM_CONFIGS];
00937   int *IntPointer;
00938   int Feature;
00939   int BestMatch;
00940   int used_features;
00941   int NumConfigs;
00942 
00943   if (MatchDebuggingOn (Debug))
00944     cprintf ("Pruning Matcher -------------------------------------------\n");
00945 
00946   IntPointer = SumOfFeatureEvidence;
00947   for (NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs > 0;
00948     NumConfigs--)
00949   *IntPointer++ = 0;
00950 
00951   for (Feature = 0, used_features = 0; Feature < NumFeatures; Feature++) {
00952     if (Features[Feature].CP_misses >= min_misses) {
00953       PMUpdateTablesForFeature (ClassTemplate, Feature,
00954         &(Features[Feature]), FeatureEvidence,
00955         SumOfFeatureEvidence, Debug);
00956       used_features++;
00957     }
00958   }
00959 
00960   IMNormalizeSumOfEvidences(ClassTemplate,
00961                             SumOfFeatureEvidence,
00962                             NumFeatures,
00963                             used_features);
00964 
00965   BestMatch =
00966     IMFindBestMatch(ClassTemplate,
00967                     SumOfFeatureEvidence,
00968                     BlobLength,
00969                     NormalizationFactor,
00970                     Result);
00971 
00972 #ifndef GRAPHICS_DISABLED
00973   if (PrintMatchSummaryOn (Debug))
00974     IMDebugBestMatch(BestMatch, Result, BlobLength, NormalizationFactor); 
00975 #endif
00976 
00977   if (MatchDebuggingOn (Debug))
00978     cprintf ("Match Complete --------------------------------------------\n");
00979 
00980 }
00981 
00982 /* =============================== */
00995 void config_mask_to_proto_mask(INT_CLASS ClassTemplate,
00996                                BIT_VECTOR config_mask,
00997                                BIT_VECTOR proto_mask) {
00998   UINT32 ConfigWord;
00999   int ProtoSetIndex;
01000   UINT32 ProtoNum;
01001   PROTO_SET ProtoSet;
01002   int NumProtos;
01003   UINT32 ActualProtoNum;
01004 
01005   NumProtos = NumIntProtosIn (ClassTemplate);
01006 
01007   zero_all_bits (proto_mask, WordsInVectorOfSize (MAX_NUM_PROTOS));
01008   for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate);
01009   ProtoSetIndex++) {
01010     ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
01011     ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
01012     for (ProtoNum = 0;
01013       ((ProtoNum < PROTOS_PER_PROTO_SET)
01014     && (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) {
01015       ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
01016       ConfigWord &= *config_mask;
01017       if (ConfigWord != 0) {
01018         proto_mask[ActualProtoNum / 32] |= 1 << (ActualProtoNum % 32);
01019       }
01020     }
01021   }
01022 }
01023 
01024 
01025 /* =============================== */
01049 void IntegerMatcher(INT_CLASS ClassTemplate,
01050                     BIT_VECTOR ProtoMask,
01051                     BIT_VECTOR ConfigMask,
01052                     UINT16 BlobLength,
01053                     INT16 NumFeatures,
01054                     INT_FEATURE_ARRAY Features,
01055                     INT32 min_misses,
01056                     UINT8 NormalizationFactor,
01057                     INT_RESULT Result,
01058                     int Debug) {
01059   static UINT8 FeatureEvidence[MAX_NUM_CONFIGS];
01060   static int SumOfFeatureEvidence[MAX_NUM_CONFIGS];
01061   static UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX];
01062   int Feature;
01063   int BestMatch;
01064   int used_features;
01065 
01066   if (MatchDebuggingOn (Debug))
01067     cprintf ("Integer Matcher -------------------------------------------\n");
01068 
01069   IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
01070 
01071   for (Feature = 0, used_features = 0; Feature < NumFeatures; Feature++) {
01072     if (Features[Feature].CP_misses >= min_misses) {
01073       IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask,
01074         Feature, &(Features[Feature]),
01075         FeatureEvidence, SumOfFeatureEvidence,
01076         ProtoEvidence, Debug);
01077       used_features++;
01078     }
01079   }
01080 
01081 #ifndef GRAPHICS_DISABLED
01082   if (PrintProtoMatchesOn (Debug) || PrintMatchSummaryOn (Debug))
01083     IMDebugFeatureProtoError(ClassTemplate,
01084                              ProtoMask,
01085                              ConfigMask,
01086                              SumOfFeatureEvidence,
01087                              ProtoEvidence,
01088                              NumFeatures,
01089                              Debug);
01090 
01091   if (DisplayProtoMatchesOn (Debug))
01092     IMDisplayProtoDebugInfo(ClassTemplate,
01093                             ProtoMask,
01094                             ConfigMask,
01095                             ProtoEvidence,
01096                             Debug);
01097 
01098   if (DisplayFeatureMatchesOn (Debug))
01099     IMDisplayFeatureDebugInfo(ClassTemplate,
01100                               ProtoMask,
01101                               ConfigMask,
01102                               NumFeatures,
01103                               Features,
01104                               Debug);
01105 #endif
01106 
01107   IMUpdateSumOfProtoEvidences(ClassTemplate,
01108                               ConfigMask,
01109                               SumOfFeatureEvidence,
01110                               ProtoEvidence,
01111                               NumFeatures);
01112 
01113   IMNormalizeSumOfEvidences(ClassTemplate,
01114                             SumOfFeatureEvidence,
01115                             NumFeatures,
01116                             used_features);
01117 
01118   BestMatch =
01119     IMFindBestMatch(ClassTemplate,
01120                     SumOfFeatureEvidence,
01121                     BlobLength,
01122                     NormalizationFactor,
01123                     Result);
01124 
01125 #ifndef GRAPHICS_DISABLED
01126   if (PrintMatchSummaryOn (Debug))
01127     IMDebugBestMatch(BestMatch, Result, BlobLength, NormalizationFactor);
01128 
01129   if (MatchDebuggingOn (Debug))
01130     cprintf ("Match Complete --------------------------------------------\n");
01131 #endif
01132 
01133 }
01134 
01135 
01136 /* =============================== */
01156 int FindGoodProtos(INT_CLASS ClassTemplate,
01157                    BIT_VECTOR ProtoMask,
01158                    BIT_VECTOR ConfigMask,
01159                    UINT16 BlobLength,
01160                    INT16 NumFeatures,
01161                    INT_FEATURE_ARRAY Features,
01162                    PROTO_ID *ProtoArray,
01163                    int Debug) {
01164   static UINT8 FeatureEvidence[MAX_NUM_CONFIGS];
01165   static int SumOfFeatureEvidence[MAX_NUM_CONFIGS];
01166   static UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX];
01167   int Feature;
01168   register UINT8 *UINT8Pointer;
01169   register int ProtoIndex;
01170   int NumProtos;
01171   int NumGoodProtos;
01172   UINT16 ActualProtoNum;
01173   register int Temp;
01174 
01175   /* DEBUG opening heading */
01176   if (MatchDebuggingOn (Debug))
01177     cprintf
01178       ("Find Good Protos -------------------------------------------\n");
01179 
01180   IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
01181 
01182   for (Feature = 0; Feature < NumFeatures; Feature++)
01183     IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
01184       &(Features[Feature]), FeatureEvidence,
01185       SumOfFeatureEvidence, ProtoEvidence, Debug);
01186 
01187 #ifndef GRAPHICS_DISABLED
01188   if (PrintProtoMatchesOn (Debug) || PrintMatchSummaryOn (Debug))
01189     IMDebugFeatureProtoError(ClassTemplate,
01190                              ProtoMask,
01191                              ConfigMask,
01192                              SumOfFeatureEvidence,
01193                              ProtoEvidence,
01194                              NumFeatures,
01195                              Debug);
01196 #endif
01197 
01198   /* Average Proto Evidences & Find Good Protos */
01199   NumProtos = NumIntProtosIn (ClassTemplate);
01200   NumGoodProtos = 0;
01201   for (ActualProtoNum = 0; ActualProtoNum < NumProtos; ActualProtoNum++) {
01202     /* Compute Average for Actual Proto */
01203     Temp = 0;
01204     UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
01205     for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum);
01206       ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
01207     Temp += *UINT8Pointer;
01208 
01209     Temp /= LengthForProtoId (ClassTemplate, ActualProtoNum);
01210 
01211     /* Find Good Protos */
01212     if (Temp >= AdaptProtoThresh) {
01213       *ProtoArray = ActualProtoNum;
01214       ProtoArray++;
01215       NumGoodProtos++;
01216     }
01217   }
01218 
01219   if (MatchDebuggingOn (Debug))
01220     cprintf ("Match Complete --------------------------------------------\n");
01221 
01222   return NumGoodProtos;
01223 
01224 }
01225 
01226 
01227 /* =============================== */
01246 int FindBadFeatures(INT_CLASS ClassTemplate,
01247                     BIT_VECTOR ProtoMask,
01248                     BIT_VECTOR ConfigMask,
01249                     UINT16 BlobLength,
01250                     INT16 NumFeatures,
01251                     INT_FEATURE_ARRAY Features,
01252                     FEATURE_ID *FeatureArray,
01253                     int Debug) {
01254   static UINT8 FeatureEvidence[MAX_NUM_CONFIGS];
01255   static int SumOfFeatureEvidence[MAX_NUM_CONFIGS];
01256   static UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX];
01257   int Feature;
01258   register UINT8 *UINT8Pointer;
01259   register int ConfigNum;
01260   int NumConfigs;
01261   int NumBadFeatures;
01262   register int Temp;
01263 
01264   /* DEBUG opening heading */
01265   if (MatchDebuggingOn (Debug))
01266     cprintf
01267       ("Find Bad Features -------------------------------------------\n");
01268 
01269   IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
01270 
01271   NumBadFeatures = 0;
01272   NumConfigs = NumIntConfigsIn (ClassTemplate);
01273   for (Feature = 0; Feature < NumFeatures; Feature++) {
01274     IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
01275       &(Features[Feature]), FeatureEvidence,
01276       SumOfFeatureEvidence, ProtoEvidence, Debug);
01277 
01278     /* Find Best Evidence for Current Feature */
01279     Temp = 0;
01280     UINT8Pointer = FeatureEvidence;
01281     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, UINT8Pointer++)
01282       if (*UINT8Pointer > Temp)
01283         Temp = *UINT8Pointer;
01284 
01285     /* Find Bad Features */
01286     if (Temp < AdaptFeatureThresh) {
01287       *FeatureArray = Feature;
01288       FeatureArray++;
01289       NumBadFeatures++;
01290     }
01291   }
01292 
01293 #ifndef GRAPHICS_DISABLED
01294   if (PrintProtoMatchesOn (Debug) || PrintMatchSummaryOn (Debug))
01295     IMDebugFeatureProtoError(ClassTemplate,
01296                              ProtoMask,
01297                              ConfigMask,
01298                              SumOfFeatureEvidence,
01299                              ProtoEvidence,
01300                              NumFeatures,
01301                              Debug);
01302 #endif
01303 
01304   if (MatchDebuggingOn (Debug))
01305     cprintf ("Match Complete --------------------------------------------\n");
01306 
01307   return NumBadFeatures;
01308 
01309 }
01310 
01311 
01312 /* =============================== */
01323 void InitIntegerMatcher() { 
01324   int i;
01325   UINT32 IntSimilarity;
01326   double Similarity;
01327   double Evidence;
01328   double ScaleFactor;
01329 
01330   /* Set default mode of operation of IntegerMatcher */
01331   SetCharNormMatch();
01332 
01333   /* Initialize table for evidence to similarity lookup */
01334   for (i = 0; i < SE_TABLE_SIZE; i++) {
01335     IntSimilarity = i << (27 - SE_TABLE_BITS);
01336     Similarity = ((double) IntSimilarity) / 65536.0 / 65536.0;
01337     Evidence = Similarity / SimilarityCenter;
01338     Evidence *= Evidence;
01339     Evidence += 1.0;
01340     Evidence = 1.0 / Evidence;
01341     Evidence *= 255.0;
01342 
01343     if (SEExponentialMultiplier > 0.0) {
01344       ScaleFactor = 1.0 - exp (-SEExponentialMultiplier) *
01345         exp (SEExponentialMultiplier * ((double) i / SE_TABLE_SIZE));
01346       if (ScaleFactor > 1.0)
01347         ScaleFactor = 1.0;
01348       if (ScaleFactor < 0.0)
01349         ScaleFactor = 0.0;
01350       Evidence *= ScaleFactor;
01351     }
01352 
01353     SimilarityEvidenceTable[i] = (UINT8) (Evidence + 0.5);
01354   }
01355 
01356   /* Initialize evidence computation variables */
01357   EvidenceTableMask =
01358     ((1 << EvidenceTableBits) - 1) << (9 - EvidenceTableBits);
01359   MultTruncShiftBits = (14 - IntEvidenceTruncBits);
01360   TableTruncShiftBits = (27 - SE_TABLE_BITS - (MultTruncShiftBits << 1));
01361   EvidenceMultMask = ((1 << IntEvidenceTruncBits) - 1);
01362 
01363 }
01364 
01365 
01366 /* =============================== */
01374 void InitIntegerMatcherVars() { 
01375   MakeClassPrunerThreshold(); 
01376   MakeClassPrunerMultiplier(); 
01377   MakeIntegerMatcherMultiplier(); 
01378   MakeIntThetaFudge(); 
01379   MakeCPCutoffStrength(); 
01380   MakeEvidenceTableBits(); 
01381   MakeIntEvidenceTruncBits(); 
01382   MakeSEExponentialMultiplier(); 
01383   MakeSimilarityCenter(); 
01384 }
01385 
01386 
01387 /* =============================== */
01396 void PrintIntMatcherStats(FILE *f) { 
01397   fprintf (f, "protoword_lookups=%d, zero_protowords=%d, proto_shifts=%d\n",
01398     protoword_lookups, zero_protowords, proto_shifts);
01399   fprintf (f, "set_proto_bits=%d, config_shifts=%d, set_config_bits=%d\n",
01400     set_proto_bits, config_shifts, set_config_bits);
01401 }
01402 
01403 
01404 /* =============================== */
01412 void SetProtoThresh(FLOAT32 Threshold) { 
01413   AdaptProtoThresh = (int) (255 * Threshold);
01414   if (AdaptProtoThresh < 0)
01415     AdaptProtoThresh = 0;
01416   if (AdaptProtoThresh > 255)
01417     AdaptProtoThresh = 255;
01418 }
01419 
01420 
01421 /* =============================== */
01429 void SetFeatureThresh(FLOAT32 Threshold) { 
01430   AdaptFeatureThresh = (int) (255 * Threshold);
01431   if (AdaptFeatureThresh < 0)
01432     AdaptFeatureThresh = 0;
01433   if (AdaptFeatureThresh > 255)
01434     AdaptFeatureThresh = 255;
01435 }
01436 
01437 
01438 /* =============================== */
01446 void SetBaseLineMatch() { 
01447   LocalMatcherMultiplier = 0;
01448 }
01449 
01450 
01451 /* =============================== */
01460 void SetCharNormMatch() { 
01461   LocalMatcherMultiplier = IntegerMatcherMultiplier;
01462 }
01463 
01464 
01465 /* =================
01466               Private Code
01467  ==================== */
01478 void
01479 IMClearTables (INT_CLASS ClassTemplate,
01480 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
01481 UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX]) {
01482   register UINT8 *UINT8Pointer;
01483   register int *IntPointer;
01484   register int ConfigNum;
01485   int NumConfigs;
01486   register UINT16 ProtoNum;
01487   int NumProtos;
01488   register int ProtoIndex;
01489 
01490   NumProtos = NumIntProtosIn (ClassTemplate);
01491   NumConfigs = NumIntConfigsIn (ClassTemplate);
01492 
01493   IntPointer = SumOfFeatureEvidence;
01494   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++)
01495     *IntPointer = 0;
01496   UINT8Pointer = (UINT8 *) ProtoEvidence;
01497   for (ProtoNum = 0; ProtoNum < NumProtos; ProtoNum++)
01498     for (ProtoIndex = 0; ProtoIndex < MAX_PROTO_INDEX;
01499     ProtoIndex++, UINT8Pointer++)
01500   *UINT8Pointer = 0;
01501 
01502 }
01503 
01504 
01505 /* =============================== */
01516 void
01517 IMClearFeatureEvidenceTable (UINT8 FeatureEvidence[MAX_NUM_CONFIGS],
01518 int NumConfigs) {
01519   register UINT8 *UINT8Pointer;
01520   register int ConfigNum;
01521 
01522   UINT8Pointer = FeatureEvidence;
01523   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, UINT8Pointer++)
01524     *UINT8Pointer = 0;
01525 
01526 }
01527 
01528 
01529 /* =============================== */
01542 void IMDebugConfiguration(int FeatureNum,
01543                           UINT16 ActualProtoNum,
01544                           UINT8 Evidence,
01545                           BIT_VECTOR ConfigMask,
01546                           UINT32 ConfigWord) {
01547   cprintf ("F = %3d, P = %3d, E = %3d, Configs = ",
01548     FeatureNum, (int) ActualProtoNum, (int) Evidence);
01549   while (ConfigWord) {
01550     if (ConfigWord & 1)
01551       cprintf ("1");
01552     else
01553       cprintf ("0");
01554     ConfigWord >>= 1;
01555   }
01556   cprintf ("\n");
01557 }
01558 
01559 
01560 /* =============================== */
01571 void IMDebugConfigurationSum(int FeatureNum,
01572                              UINT8 *FeatureEvidence,
01573                              INT32 ConfigCount) {
01574   int ConfigNum;
01575 
01576   cprintf ("F=%3d, C=", (int) FeatureNum);
01577 
01578   for (ConfigNum = 0; ConfigNum < ConfigCount; ConfigNum++) {
01579     cprintf ("%4d", FeatureEvidence[ConfigNum]);
01580   }
01581   cprintf ("\n");
01582 
01583 }
01584 
01585 
01586 /* =============================== */
01601 void PMUpdateTablesForFeature (INT_CLASS ClassTemplate,
01602 int FeatureNum,
01603 INT_FEATURE Feature,
01604 UINT8 FeatureEvidence[MAX_NUM_CONFIGS],
01605 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
01606 int Debug) {
01607   UINT8 config_byte;
01608   UINT8 proto_byte;
01609   UINT8 Evidence;
01610   INT32 config_offset;
01611   UINT8 *UINT8Pointer;
01612   UINT32 ConfigWord;
01613   UINT32 ProtoWord;
01614   INT32 M3;
01615   INT32 A3;
01616   UINT32 A4;
01617   INT32 proto_word_offset;
01618   INT32 proto_offset;
01619   UINT32 ProtoNum;
01620   UINT32 ActualProtoNum;
01621   PROTO_SET ProtoSet;
01622   UINT32 *ProtoPrunerPtr;
01623   INT_PROTO Proto;
01624   int ProtoSetIndex;
01625   UINT32 XFeatureAddress;
01626   UINT32 YFeatureAddress;
01627   UINT32 ThetaFeatureAddress;
01628   int *IntPointer;
01629   int ConfigNum;
01630 
01631   IMClearFeatureEvidenceTable (FeatureEvidence,
01632     NumIntConfigsIn (ClassTemplate));
01633 
01634   /* Precompute Feature Address offset for Proto Pruning */
01635   XFeatureAddress = ((Feature->X >> 2) << 1);
01636   YFeatureAddress = (NUM_PP_BUCKETS << 1) + ((Feature->Y >> 2) << 1);
01637   ThetaFeatureAddress = (NUM_PP_BUCKETS << 2) + ((Feature->Theta >> 2) << 1);
01638 
01639   for (ProtoSetIndex = 0, ActualProtoNum = 0;
01640   ProtoSetIndex < NumProtoSetsIn (ClassTemplate); ProtoSetIndex++) {
01641     ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
01642     ProtoPrunerPtr = (UINT32 *) ((*ProtoSet).ProtoPruner);
01643     for (ProtoNum = 0; ProtoNum < PROTOS_PER_PROTO_SET;
01644       ProtoNum += (PROTOS_PER_PROTO_SET >> 1), ActualProtoNum +=
01645     (PROTOS_PER_PROTO_SET >> 1), ProtoPrunerPtr++) {
01646       /* Prune Protos of current Proto Set */
01647       ProtoWord = *(ProtoPrunerPtr + XFeatureAddress);
01648       ProtoWord &= *(ProtoPrunerPtr + YFeatureAddress);
01649       ProtoWord &= *(ProtoPrunerPtr + ThetaFeatureAddress);
01650 
01651       if (ProtoWord != 0) {
01652         proto_byte = ProtoWord & 0xff;
01653         ProtoWord >>= 8;
01654         proto_word_offset = 0;
01655         while (ProtoWord != 0 || proto_byte != 0) {
01656           while (proto_byte == 0) {
01657             proto_byte = ProtoWord & 0xff;
01658             ProtoWord >>= 8;
01659             proto_word_offset += 8;
01660           }
01661           proto_offset = offset_table[proto_byte] + proto_word_offset;
01662           proto_byte = next_table[proto_byte];
01663           /* Compute Evidence */
01664           Proto = &(ProtoSet->Protos[ProtoNum + proto_offset]);
01665           ConfigWord = Proto->Configs[0];
01666           A3 = (((Proto->A * (Feature->X - 128)) << 1)
01667             - (Proto->B * (Feature->Y - 128)) + (Proto->C << 9));
01668           M3 =
01669             (((INT8) (Feature->Theta - Proto->Angle)) *
01670             IntThetaFudge) << 1;
01671 
01672           if (A3 < 0)
01673             A3 = ~A3;
01674           if (M3 < 0)
01675             M3 = ~M3;
01676           A3 >>= MultTruncShiftBits;
01677           M3 >>= MultTruncShiftBits;
01678           if (A3 > EvidenceMultMask)
01679             A3 = EvidenceMultMask;
01680           if (M3 > EvidenceMultMask)
01681             M3 = EvidenceMultMask;
01682 
01683           A4 = (A3 * A3) + (M3 * M3);
01684           A4 >>= TableTruncShiftBits;
01685           if (A4 > EvidenceTableMask)
01686             Evidence = 0;
01687           else
01688             Evidence = SimilarityEvidenceTable[A4];
01689 
01690           UINT8Pointer = FeatureEvidence - 8;
01691           config_byte = 0;
01692           while (ConfigWord != 0 || config_byte != 0) {
01693             while (config_byte == 0) {
01694               config_byte = ConfigWord & 0xff;
01695               ConfigWord >>= 8;
01696               UINT8Pointer += 8;
01697             }
01698             config_offset = offset_table[config_byte];
01699             config_byte = next_table[config_byte];
01700             if (Evidence > UINT8Pointer[config_offset])
01701               UINT8Pointer[config_offset] = Evidence;
01702           }
01703         }
01704       }
01705     }
01706   }
01707 
01708   if (PrintFeatureMatchesOn (Debug))
01709     IMDebugConfigurationSum (FeatureNum, FeatureEvidence,
01710       NumIntConfigsIn (ClassTemplate));
01711   IntPointer = SumOfFeatureEvidence;
01712   UINT8Pointer = FeatureEvidence;
01713   for (ConfigNum = NumIntConfigsIn (ClassTemplate); ConfigNum > 0;
01714     ConfigNum--)
01715   *IntPointer++ += (*UINT8Pointer++);
01716 }
01717 
01718 
01719 /* =============================== */
01737 void IMUpdateTablesForFeature (INT_CLASS ClassTemplate,
01738 BIT_VECTOR ProtoMask,
01739 BIT_VECTOR ConfigMask,
01740 int FeatureNum,
01741 INT_FEATURE Feature,
01742 UINT8 FeatureEvidence[MAX_NUM_CONFIGS],
01743 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
01744 UINT8
01745 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX],
01746 int Debug) {
01747   register UINT32 ConfigWord;
01748   register UINT32 ProtoWord;
01749   register UINT32 ProtoNum;
01750   register UINT32 ActualProtoNum;
01751   UINT8 proto_byte;
01752   INT32 proto_word_offset;
01753   INT32 proto_offset;
01754   UINT8 config_byte;
01755   INT32 config_offset;
01756   PROTO_SET ProtoSet;
01757   UINT32 *ProtoPrunerPtr;
01758   INT_PROTO Proto;
01759   int ProtoSetIndex;
01760   UINT8 Evidence;
01761   UINT32 XFeatureAddress;
01762   UINT32 YFeatureAddress;
01763   UINT32 ThetaFeatureAddress;
01764   register UINT8 *UINT8Pointer;
01765   register int ProtoIndex;
01766   UINT8 Temp;
01767   register int *IntPointer;
01768   int ConfigNum;
01769   register INT32 M3;
01770   register INT32 A3;
01771   register UINT32 A4;
01772 
01773   IMClearFeatureEvidenceTable (FeatureEvidence,
01774     NumIntConfigsIn (ClassTemplate));
01775 
01776   /* Precompute Feature Address offset for Proto Pruning */
01777   XFeatureAddress = ((Feature->X >> 2) << 1);
01778   YFeatureAddress = (NUM_PP_BUCKETS << 1) + ((Feature->Y >> 2) << 1);
01779   ThetaFeatureAddress = (NUM_PP_BUCKETS << 2) + ((Feature->Theta >> 2) << 1);
01780 
01781   for (ProtoSetIndex = 0, ActualProtoNum = 0;
01782   ProtoSetIndex < NumProtoSetsIn (ClassTemplate); ProtoSetIndex++) {
01783     ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
01784     ProtoPrunerPtr = (UINT32 *) ((*ProtoSet).ProtoPruner);
01785     for (ProtoNum = 0; ProtoNum < PROTOS_PER_PROTO_SET;
01786       ProtoNum += (PROTOS_PER_PROTO_SET >> 1), ActualProtoNum +=
01787     (PROTOS_PER_PROTO_SET >> 1), ProtoMask++, ProtoPrunerPtr++) {
01788       /* Prune Protos of current Proto Set */
01789       ProtoWord = *(ProtoPrunerPtr + XFeatureAddress);
01790       ProtoWord &= *(ProtoPrunerPtr + YFeatureAddress);
01791       ProtoWord &= *(ProtoPrunerPtr + ThetaFeatureAddress);
01792       ProtoWord &= *ProtoMask;
01793 
01794       if (ProtoWord != 0) {
01795         proto_byte = ProtoWord & 0xff;
01796         ProtoWord >>= 8;
01797         proto_word_offset = 0;
01798         while (ProtoWord != 0 || proto_byte != 0) {
01799           while (proto_byte == 0) {
01800             proto_byte = ProtoWord & 0xff;
01801             ProtoWord >>= 8;
01802             proto_word_offset += 8;
01803           }
01804           proto_offset = offset_table[proto_byte] + proto_word_offset;
01805           proto_byte = next_table[proto_byte];
01806           Proto = &(ProtoSet->Protos[ProtoNum + proto_offset]);
01807           ConfigWord = Proto->Configs[0];
01808           A3 = (((Proto->A * (Feature->X - 128)) << 1)
01809             - (Proto->B * (Feature->Y - 128)) + (Proto->C << 9));
01810           M3 =
01811             (((INT8) (Feature->Theta - Proto->Angle)) *
01812             IntThetaFudge) << 1;
01813 
01814           if (A3 < 0)
01815             A3 = ~A3;
01816           if (M3 < 0)
01817             M3 = ~M3;
01818           A3 >>= MultTruncShiftBits;
01819           M3 >>= MultTruncShiftBits;
01820           if (A3 > EvidenceMultMask)
01821             A3 = EvidenceMultMask;
01822           if (M3 > EvidenceMultMask)
01823             M3 = EvidenceMultMask;
01824 
01825           A4 = (A3 * A3) + (M3 * M3);
01826           A4 >>= TableTruncShiftBits;
01827           if (A4 > EvidenceTableMask)
01828             Evidence = 0;
01829           else
01830             Evidence = SimilarityEvidenceTable[A4];
01831 
01832           if (PrintFeatureMatchesOn (Debug))
01833             IMDebugConfiguration (FeatureNum,
01834               ActualProtoNum + proto_offset,
01835               Evidence, ConfigMask, ConfigWord);
01836 
01837           ConfigWord &= *ConfigMask;
01838 
01839           UINT8Pointer = FeatureEvidence - 8;
01840           config_byte = 0;
01841           while (ConfigWord != 0 || config_byte != 0) {
01842             while (config_byte == 0) {
01843               config_byte = ConfigWord & 0xff;
01844               ConfigWord >>= 8;
01845               UINT8Pointer += 8;
01846               // config_shifts++;
01847             }
01848             config_offset = offset_table[config_byte];
01849             config_byte = next_table[config_byte];
01850             if (Evidence > UINT8Pointer[config_offset])
01851               UINT8Pointer[config_offset] = Evidence;
01852           }
01853 
01854           UINT8Pointer =
01855             &(ProtoEvidence[ActualProtoNum + proto_offset][0]);
01856           for (ProtoIndex =
01857             LengthForProtoId (ClassTemplate,
01858             ActualProtoNum + proto_offset);
01859           ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) {
01860             if (Evidence > *UINT8Pointer) {
01861               Temp = *UINT8Pointer;
01862               *UINT8Pointer = Evidence;
01863               Evidence = Temp;
01864             }
01865             else if (Evidence == 0)
01866               break;
01867           }
01868         }
01869       }
01870     }
01871   }
01872 
01873   if (PrintFeatureMatchesOn (Debug))
01874     IMDebugConfigurationSum (FeatureNum, FeatureEvidence,
01875       NumIntConfigsIn (ClassTemplate));
01876   IntPointer = SumOfFeatureEvidence;
01877   UINT8Pointer = FeatureEvidence;
01878   for (ConfigNum = NumIntConfigsIn (ClassTemplate); ConfigNum > 0;
01879     ConfigNum--)
01880   *IntPointer++ += (*UINT8Pointer++);
01881 
01882 }
01883 
01884 
01885 /* =============================== */
01901 #ifndef GRAPHICS_DISABLED
01902 void IMDebugFeatureProtoError (INT_CLASS ClassTemplate,
01903 BIT_VECTOR ProtoMask,
01904 BIT_VECTOR ConfigMask,
01905 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
01906 UINT8
01907 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX],
01908 INT16 NumFeatures, int Debug) {
01909   UINT8 *UINT8Pointer;
01910   int *IntPointer;
01911   FLOAT32 ProtoConfigs[MAX_NUM_CONFIGS];
01912   int ConfigNum;
01913   UINT32 ConfigWord;
01914   int ProtoSetIndex;
01915   UINT16 ProtoNum;
01916   UINT8 ProtoWordNum;
01917   PROTO_SET ProtoSet;
01918   int ProtoIndex;
01919   int NumProtos;
01920   UINT16 ActualProtoNum;
01921   int Temp;
01922   int NumConfigs;
01923 
01924   NumProtos = NumIntProtosIn (ClassTemplate);
01925   NumConfigs = NumIntConfigsIn (ClassTemplate);
01926 
01927   if (PrintMatchSummaryOn (Debug)) {
01928     cprintf ("Configuration Mask:\n");
01929     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
01930       cprintf ("%1d", (((*ConfigMask) >> ConfigNum) & 1));
01931     cprintf ("\n");
01932 
01933     cprintf ("Feature Error for Configurations:\n");
01934     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
01935       cprintf (" %5.1f",
01936         100.0 * (1.0 -
01937         (FLOAT32) SumOfFeatureEvidence[ConfigNum] /
01938         NumFeatures / 256.0));
01939     cprintf ("\n\n\n");
01940   }
01941 
01942   if (PrintMatchSummaryOn (Debug)) {
01943     cprintf ("Proto Mask:\n");
01944     for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate);
01945     ProtoSetIndex++) {
01946       ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
01947       for (ProtoWordNum = 0; ProtoWordNum < 2;
01948       ProtoWordNum++, ProtoMask++) {
01949         ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
01950         for (ProtoNum = 0;
01951           ((ProtoNum < (PROTOS_PER_PROTO_SET >> 1))
01952           && (ActualProtoNum < NumProtos));
01953           ProtoNum++, ActualProtoNum++)
01954         cprintf ("%1d", (((*ProtoMask) >> ProtoNum) & 1));
01955         cprintf ("\n");
01956       }
01957     }
01958     cprintf ("\n");
01959   }
01960 
01961   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
01962     ProtoConfigs[ConfigNum] = 0;
01963 
01964   if (PrintProtoMatchesOn (Debug)) {
01965     cprintf ("Proto Evidence:\n");
01966     for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate);
01967     ProtoSetIndex++) {
01968       ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
01969       ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
01970       for (ProtoNum = 0;
01971         ((ProtoNum < PROTOS_PER_PROTO_SET)
01972         && (ActualProtoNum < NumProtos));
01973       ProtoNum++, ActualProtoNum++) {
01974         cprintf ("P %3d =", ActualProtoNum);
01975         Temp = 0;
01976         UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
01977         for (ProtoIndex = 0;
01978           ProtoIndex < LengthForProtoId (ClassTemplate,
01979           ActualProtoNum);
01980         ProtoIndex++, UINT8Pointer++) {
01981           cprintf (" %d", *UINT8Pointer);
01982           Temp += *UINT8Pointer;
01983         }
01984 
01985         cprintf (" = %6.4f%%\n", Temp /
01986           256.0 / LengthForProtoId (ClassTemplate,
01987           ActualProtoNum));
01988 
01989         ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
01990         IntPointer = SumOfFeatureEvidence;
01991         ConfigNum = 0;
01992         while (ConfigWord) {
01993           cprintf ("%5d", ConfigWord & 1 ? Temp : 0);
01994           if (ConfigWord & 1)
01995             ProtoConfigs[ConfigNum] += Temp;
01996           IntPointer++;
01997           ConfigNum++;
01998           ConfigWord >>= 1;
01999         }
02000         cprintf ("\n");
02001       }
02002     }
02003   }
02004 
02005   if (PrintMatchSummaryOn (Debug)) {
02006     cprintf ("Proto Error for Configurations:\n");
02007     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
02008       cprintf (" %5.1f",
02009         100.0 * (1.0 -
02010         ProtoConfigs[ConfigNum] /
02011         LengthForConfigId (ClassTemplate,
02012         ConfigNum) / 256.0));
02013     cprintf ("\n\n");
02014   }
02015 
02016   if (PrintProtoMatchesOn (Debug)) {
02017     cprintf ("Proto Sum for Configurations:\n");
02018     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
02019       cprintf (" %4.1f", ProtoConfigs[ConfigNum] / 256.0);
02020     cprintf ("\n\n");
02021 
02022     cprintf ("Proto Length for Configurations:\n");
02023     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
02024       cprintf (" %4.1f",
02025         (float) LengthForConfigId (ClassTemplate, ConfigNum));
02026     cprintf ("\n\n");
02027   }
02028 
02029 }
02030 
02031 
02032 /* =============================== */
02045 void IMDisplayProtoDebugInfo (INT_CLASS ClassTemplate,
02046 BIT_VECTOR ProtoMask,
02047 BIT_VECTOR ConfigMask,
02048 UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX],
02049 int Debug) {
02050   register UINT8 *UINT8Pointer;
02051   register UINT32 ConfigWord;
02052   register UINT16 ProtoNum;
02053   register UINT16 ActualProtoNum;
02054   PROTO_SET ProtoSet;
02055   int ProtoSetIndex;
02056   int ProtoIndex;
02057   int NumProtos;
02058   register int Temp;
02059 
02060   extern void *IntMatchWindow;
02061 
02062   if (IntMatchWindow == NULL) {
02063     IntMatchWindow = c_create_window ("IntMatchWindow", 50, 200,
02064       520, 520,
02065       -130.0, 130.0, -130.0, 130.0);
02066   }
02067   NumProtos = NumIntProtosIn (ClassTemplate);
02068 
02069   for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate);
02070   ProtoSetIndex++) {
02071     ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
02072     ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
02073     for (ProtoNum = 0;
02074       ((ProtoNum < PROTOS_PER_PROTO_SET)
02075     && (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) {
02076       /* Compute Average for Actual Proto */
02077       Temp = 0;
02078       UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
02079       for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum);
02080         ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
02081       Temp += *UINT8Pointer;
02082 
02083       Temp /= LengthForProtoId (ClassTemplate, ActualProtoNum);
02084 
02085       ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
02086       ConfigWord &= *ConfigMask;
02087       if (ConfigWord)
02088         /* Update display for current proto */
02089       if (ClipMatchEvidenceOn (Debug)) {
02090         if (Temp < AdaptProtoThresh)
02091           DisplayIntProto (ClassTemplate, ActualProtoNum,
02092             (Temp / 255.0));
02093         else
02094           DisplayIntProto (ClassTemplate, ActualProtoNum,
02095             (Temp / 255.0));
02096       }
02097       else {
02098         DisplayIntProto (ClassTemplate, ActualProtoNum,
02099           (Temp / 255.0));
02100       }
02101     }
02102   }
02103 }
02104 
02105 
02106 /* =============================== */
02120 void IMDisplayFeatureDebugInfo(INT_CLASS ClassTemplate,
02121                                BIT_VECTOR ProtoMask,
02122                                BIT_VECTOR ConfigMask,
02123                                INT16 NumFeatures,
02124                                INT_FEATURE_ARRAY Features,
02125                                int Debug) {
02126   static UINT8 FeatureEvidence[MAX_NUM_CONFIGS];
02127   static int SumOfFeatureEvidence[MAX_NUM_CONFIGS];
02128   static UINT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX];
02129   int Feature;
02130   register UINT8 *UINT8Pointer;
02131   register int ConfigNum;
02132   int NumConfigs;
02133   register int Temp;
02134 
02135   IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
02136 
02137   NumConfigs = NumIntConfigsIn (ClassTemplate);
02138   for (Feature = 0; Feature < NumFeatures; Feature++) {
02139     IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
02140       &(Features[Feature]), FeatureEvidence,
02141       SumOfFeatureEvidence, ProtoEvidence, 0);
02142 
02143     /* Find Best Evidence for Current Feature */
02144     Temp = 0;
02145     UINT8Pointer = FeatureEvidence;
02146     for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, UINT8Pointer++)
02147       if (*UINT8Pointer > Temp)
02148         Temp = *UINT8Pointer;
02149 
02150     /* Update display for current feature */
02151     if (ClipMatchEvidenceOn (Debug)) {
02152       if (Temp < AdaptFeatureThresh)
02153         DisplayIntFeature (&(Features[Feature]), 0.0);
02154       else
02155         DisplayIntFeature (&(Features[Feature]), 1.0);
02156     }
02157     else {
02158       DisplayIntFeature (&(Features[Feature]), (Temp / 255.0));
02159     }
02160   }
02161 }
02162 #endif
02163 
02164 
02165 /* =============================== */
02178 void
02179 IMUpdateSumOfProtoEvidences (INT_CLASS ClassTemplate,
02180 BIT_VECTOR ConfigMask,
02181 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
02182 UINT8
02183 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX],
02184 INT16 NumFeatures) {
02185   register UINT8 *UINT8Pointer;
02186   register int *IntPointer;
02187   register UINT32 ConfigWord;
02188   int ProtoSetIndex;
02189   register UINT16 ProtoNum;
02190   PROTO_SET ProtoSet;
02191   register int ProtoIndex;
02192   int NumProtos;
02193   UINT16 ActualProtoNum;
02194   int Temp;
02195 
02196   NumProtos = NumIntProtosIn (ClassTemplate);
02197 
02198   for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate);
02199   ProtoSetIndex++) {
02200     ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex);
02201     ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
02202     for (ProtoNum = 0;
02203       ((ProtoNum < PROTOS_PER_PROTO_SET)
02204     && (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) {
02205       Temp = 0;
02206       UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
02207       for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum);
02208         ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
02209       Temp += *UINT8Pointer;
02210 
02211       ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
02212       ConfigWord &= *ConfigMask;
02213       IntPointer = SumOfFeatureEvidence;
02214       while (ConfigWord) {
02215         if (ConfigWord & 1)
02216           *IntPointer += Temp;
02217         IntPointer++;
02218         ConfigWord >>= 1;
02219       }
02220     }
02221   }
02222 }
02223 
02224 
02225 /* =============================== */
02238 void
02239 PMNormalizeSumOfEvidences (INT_CLASS ClassTemplate,
02240 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
02241 INT16 NumFeatures, INT32 used_features) {
02242   register int *IntPointer;
02243   register int ConfigNum;
02244   int NumConfigs;
02245 
02246   NumConfigs = NumIntConfigsIn (ClassTemplate);
02247   if (used_features <= 0)
02248     used_features = 1;
02249 
02250   IntPointer = SumOfFeatureEvidence;
02251   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++)
02252     *IntPointer = (*IntPointer << 8) / used_features;
02253 }
02254 
02255 
02256 /* =============================== */
02269 void
02270 IMNormalizeSumOfEvidences (INT_CLASS ClassTemplate,
02271 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
02272 INT16 NumFeatures, INT32 used_features) {
02273   register int *IntPointer;
02274   register int ConfigNum;
02275   int NumConfigs;
02276 
02277   NumConfigs = NumIntConfigsIn (ClassTemplate);
02278 
02279   IntPointer = SumOfFeatureEvidence;
02280   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++)
02281     *IntPointer = (*IntPointer << 8) /
02282       (NumFeatures + LengthForConfigId (ClassTemplate, ConfigNum));
02283 }
02284 
02285 /* =============================== */
02299 int
02300 IMFindBestMatch (INT_CLASS ClassTemplate,
02301 int SumOfFeatureEvidence[MAX_NUM_CONFIGS],
02302 UINT16 BlobLength,
02303 UINT8 NormalizationFactor, INT_RESULT Result) {
02304   register int *IntPointer;
02305   register int ConfigNum;
02306   register int NumConfigs;
02307   register int BestMatch;
02308   register int Best2Match;
02309 
02310   NumConfigs = NumIntConfigsIn (ClassTemplate);
02311 
02312   /* Find best match */
02313   BestMatch = 0;
02314   Best2Match = 0;
02315   IntPointer = SumOfFeatureEvidence;
02316   for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++) {
02317     if (display_ratings > 1)
02318       cprintf ("Config %d, rating=%d\n", ConfigNum, *IntPointer);
02319     if (*IntPointer > BestMatch) {
02320       if (BestMatch > 0) {
02321         Result->Config2 = Result->Config;
02322         Best2Match = BestMatch;
02323       }
02324       else
02325         Result->Config2 = ConfigNum;
02326       Result->Config = ConfigNum;
02327       BestMatch = *IntPointer;
02328     }
02329     else if (*IntPointer > Best2Match) {
02330       Result->Config2 = ConfigNum;
02331       Best2Match = *IntPointer;
02332     }
02333   }
02334 
02335   /* Compute Certainty Rating */
02336   (*Result).Rating = ((65536.0 - BestMatch) / 65536.0 * BlobLength +
02337     LocalMatcherMultiplier * NormalizationFactor / 256.0) /
02338     (BlobLength + LocalMatcherMultiplier);
02339 
02340   return BestMatch;
02341 }
02342 
02343 
02344 /* =============================== */
02357 void IMDebugBestMatch(int BestMatch,
02358                       INT_RESULT Result,
02359                       UINT16 BlobLength,
02360                       UINT8 NormalizationFactor) {
02361   cprintf ("Rating          = %5.1f%%     Best Config   = %3d\n",
02362     100.0 * ((*Result).Rating), (int) ((*Result).Config));
02363   cprintf
02364     ("Matcher Error   = %5.1f%%     Blob Length   = %3d     Weight = %4.1f%%\n",
02365     100.0 * (65536.0 - BestMatch) / 65536.0, (int) BlobLength,
02366     100.0 * BlobLength / (BlobLength + LocalMatcherMultiplier));
02367   cprintf
02368     ("Char Norm Error = %5.1f%%     Norm Strength = %3d     Weight = %4.1f%%\n",
02369     100.0 * NormalizationFactor / 256.0, LocalMatcherMultiplier,
02370     100.0 * LocalMatcherMultiplier / (BlobLength + LocalMatcherMultiplier));
02371 }
02372 
02373 /* =============================== */
02385 void
02386 HeapSort (int n, register INT16 ra[], register UINT8 rb[]) {
02387   register int i, rra, rrb;
02388   int l, j, ir;
02389 
02390   l = (n >> 1) + 1;
02391   ir = n;
02392   for (;;) {
02393     if (l > 1) {
02394       rra = ra[--l];
02395       rrb = rb[l];
02396     }
02397     else {
02398       rra = ra[ir];
02399       rrb = rb[ir];
02400       ra[ir] = ra[1];
02401       rb[ir] = rb[1];
02402       if (--ir == 1) {
02403         ra[1] = rra;
02404         rb[1] = rrb;
02405         return;
02406       }
02407     }
02408     i = l;
02409     j = l << 1;
02410     while (j <= ir) {
02411       if (j < ir && ra[j] < ra[j + 1])
02412         ++j;
02413       if (rra < ra[j]) {
02414         ra[i] = ra[j];
02415         rb[i] = rb[j];
02416         j += (i = j);
02417       }
02418       else
02419         j = ir + 1;
02420     }
02421     ra[i] = rra;
02422     rb[i] = rrb;
02423   }
02424 }

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