00001
00024
00025
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
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,
00133 234,
00134 252,
00135 246,
00136 253,
00137 160,
00138 202,
00139 199,
00140 171,
00141 227,
00142 208,
00143 188,
00144 60,
00145 221,
00146 138,
00147 108,
00148 98,
00149 251,
00150 214,
00151 230,
00152 252,
00153 237,
00154 217,
00155 233,
00156 174,
00157 216,
00158 210,
00159 252,
00160 253,
00161 233,
00162 243,
00163 240,
00164 230,
00165 167,
00166 248,
00167 250,
00168 232,
00169 209,
00170 193,
00171 254,
00172 146,
00173 198,
00174 107,
00175 167,
00176 163,
00177 73,
00178 16,
00179 199,
00180 162,
00181 251,
00182 250,
00183 254,
00184 253,
00185 252,
00186 253,
00187 248,
00188 251,
00189 254,
00190 201,
00191 224,
00192 253,
00193 242,
00194 254,
00195 254,
00196 253,
00197 246,
00198 254,
00199 254,
00200 254,
00201 245,
00202 221,
00203 230,
00204 251,
00205 243,
00206 133,
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,
00241 12.6,
00242 2.7439,
00243 4.22222,
00244 2.57447,
00245 2.93902,
00246 4.23684,
00247 6,
00248 2.78889,
00249 3.55,
00250 8.5,
00251 2.4,
00252 1.5,
00253 1.94737,
00254 1.89394,
00255 1.5,
00256 1.5,
00257 3.125,
00258 5.5,
00259 6.1,
00260 6,
00261 2.78205,
00262 2.03763,
00263 2.73256,
00264 2.57692,
00265 11.8,
00266 7.1,
00267 1.85227,
00268 7.4,
00269 2.26056,
00270 2.46078,
00271 6.85714,
00272 3.45238,
00273 2.47222,
00274 3.74,
00275 10.2,
00276 3.08065,
00277 6.1,
00278 9.5,
00279 7.1,
00280 7.9,
00281 2.55714,
00282 7.7,
00283 2,
00284 1.5,
00285 2.55714,
00286 1.5,
00287 1.80065,
00288 1.69512,
00289 5.34,
00290 7.3,
00291 6.43333,
00292 4.10606,
00293 4.41667,
00294 12.6,
00295 3.7093,
00296 2.38889,
00297 5.5,
00298 4.03125,
00299 2.24561,
00300 11.5,
00301 3.5,
00302 5.63333,
00303 11,
00304 2.52667,
00305 2.1129,
00306 6.56667,
00307 6.42857,
00308 11.4,
00309 3.62,
00310 2.77273,
00311 2.90909,
00312 6.5,
00313 4.98387,
00314 2.92857,
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
00402
00403
00404
00405
00406
00407
00408
00409
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
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;
00450 int Word;
00451 UINT32 *BasePrunerAddress;
00452 UINT32 feature_address;
00453 INT_FEATURE feature;
00454 CLASS_PRUNER *ClassPruner;
00455 int PrunerSet;
00456 int NumPruners;
00457 INT32 feature_index;
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;
00469 INT32 *ClassCountPtr;
00470 INT8 classch;
00471
00472 MaxNumClasses = NumClassesIn (IntTemplates);
00473
00474
00475 ClassCountPtr = &(ClassCount[0]);
00476 for (Class = 0; Class < MaxNumClasses; Class++) {
00477 *ClassCountPtr++ = 0;
00478 }
00479
00480
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
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
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
00552 MaxCount *= ClassPrunerThreshold;
00553 MaxCount >>= 8;
00554
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
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
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;
00716 INT32 result_index;
00717 int PrunerSet;
00718 int NumPruners;
00719 int Word;
00720 INT_FEATURE feature;
00721 INT32 feature_index;
00722 INT32 CP_misses;
00723 UINT32 feature_address;
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
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
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;
00826 CLASS_INDEX Class;
00827 INT_CLASS ClassTemplate;
00828 FLOAT32 best_rating;
00829 FLOAT32 best_class_rating;
00830 INT32 output_count;
00831 INT32 best_index;
00832 INT_RESULT_STRUCT IntResult;
00833 CLASS_PRUNER_RESULTS new_results;
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
00844
00845 new_results[classindex].Rating2 = Results[classindex].Rating;
00846
00847 new_results[classindex].Rating = IntResult.Rating;
00848
00849 new_results[classindex].config_mask = (1 << IntResult.Config) | (1 << IntResult.Config2);
00850
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
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
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
01199 NumProtos = NumIntProtosIn (ClassTemplate);
01200 NumGoodProtos = 0;
01201 for (ActualProtoNum = 0; ActualProtoNum < NumProtos; ActualProtoNum++) {
01202
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
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
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
01279 Temp = 0;
01280 UINT8Pointer = FeatureEvidence;
01281 for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, UINT8Pointer++)
01282 if (*UINT8Pointer > Temp)
01283 Temp = *UINT8Pointer;
01284
01285
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
01331 SetCharNormMatch();
01332
01333
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
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
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
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
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
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
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
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
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
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
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
02144 Temp = 0;
02145 UINT8Pointer = FeatureEvidence;
02146 for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, UINT8Pointer++)
02147 if (*UINT8Pointer > Temp)
02148 Temp = *UINT8Pointer;
02149
02150
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
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
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 }