00001
00019
00020
00021
00022 #include "protos.h"
00023 #include "debug.h"
00024 #include "const.h"
00025 #include "emalloc.h"
00026 #include "freelist.h"
00027 #include "callcpp.h"
00028 #include "adaptmatch.h"
00029 #include "scanutils.h"
00030
00031 #include <stdio.h>
00032 #include <math.h>
00033
00034 #define PROTO_INCREMENT 32
00035 #define CONFIG_INCREMENT 16
00036
00037
00038
00039
00040 CLASS_STRUCT TrainingData[NUMBER_OF_CLASSES];
00041
00042 char *TrainingFile;
00043
00044
00045
00046
00047
00048
00055 int AddConfigToClass(CLASS_TYPE Class) {
00056 int NewNumConfigs;
00057 int NewConfig;
00058 int MaxNumProtos;
00059 BIT_VECTOR Config;
00060
00061 MaxNumProtos = Class->MaxNumProtos;
00062
00063 if (NumConfigsIn (Class) >= Class->MaxNumConfigs) {
00064
00065 NewNumConfigs = (((Class->MaxNumConfigs + CONFIG_INCREMENT) /
00066 CONFIG_INCREMENT) * CONFIG_INCREMENT);
00067
00068 Class->Configurations =
00069 (CONFIGS) Erealloc (Class->Configurations,
00070 sizeof (BIT_VECTOR) * NewNumConfigs);
00071
00072 Class->MaxNumConfigs = NewNumConfigs;
00073 }
00074 NewConfig = NumConfigsIn (Class);
00075 NumConfigsIn (Class)++;
00076 Config = NewBitVector (MaxNumProtos);
00077 ConfigIn (Class, NewConfig) = Config;
00078 zero_all_bits (Config, WordsInVectorOfSize (MaxNumProtos));
00079
00080 return (NewConfig);
00081 }
00082
00083
00090 int AddProtoToClass(CLASS_TYPE Class) {
00091 int i;
00092 int Bit;
00093 int NewNumProtos;
00094 int NewProto;
00095 BIT_VECTOR Config;
00096
00097 if (NumProtosIn (Class) >= Class->MaxNumProtos) {
00098
00099 NewNumProtos = (((Class->MaxNumProtos + PROTO_INCREMENT) /
00100 PROTO_INCREMENT) * PROTO_INCREMENT);
00101
00102 Class->Prototypes = (PROTO) Erealloc (Class->Prototypes,
00103 sizeof (PROTO_STRUCT) *
00104 NewNumProtos);
00105
00106 Class->MaxNumProtos = NewNumProtos;
00107
00108 for (i = 0; i < NumConfigsIn (Class); i++) {
00109 Config = ConfigIn (Class, i);
00110 ConfigIn (Class, i) = ExpandBitVector (Config, NewNumProtos);
00111
00112 for (Bit = NumProtosIn (Class); Bit < NewNumProtos; Bit++)
00113 reset_bit(Config, Bit);
00114 }
00115 }
00116 NewProto = NumProtosIn (Class);
00117 NumProtosIn (Class)++;
00118 return (NewProto);
00119 }
00120
00121
00125 FLOAT32 ClassConfigLength(CLASS_TYPE Class, BIT_VECTOR Config) {
00126 INT16 Pid;
00127 FLOAT32 TotalLength = 0;
00128
00129 for (Pid = 0; Pid < NumProtosIn (Class); Pid++) {
00130 if (test_bit (Config, Pid)) {
00131
00132 TotalLength += ProtoLength (ProtoIn (Class, Pid));
00133 }
00134 }
00135 return (TotalLength);
00136 }
00137
00138
00142 FLOAT32 ClassProtoLength(CLASS_TYPE Class) {
00143 INT16 Pid;
00144 FLOAT32 TotalLength = 0;
00145
00146 for (Pid = 0; Pid < NumProtosIn (Class); Pid++) {
00147 TotalLength += ProtoLength (ProtoIn (Class, Pid));
00148 }
00149 return (TotalLength);
00150 }
00151
00152
00156 void CopyProto(PROTO Src, PROTO Dest) {
00157 ProtoX (Dest) = ProtoX (Src);
00158 ProtoY (Dest) = ProtoY (Src);
00159 ProtoLength (Dest) = ProtoLength (Src);
00160 ProtoAngle (Dest) = ProtoAngle (Src);
00161 CoefficientA (Dest) = CoefficientA (Src);
00162 CoefficientB (Dest) = CoefficientB (Src);
00163 CoefficientC (Dest) = CoefficientC (Src);
00164 }
00165
00166
00170 void FillABC(PROTO Proto) {
00171 FLOAT32 Slope, Intercept, Normalizer;
00172
00173 Slope = tan (Proto->Angle * 2.0 * PI);
00174 Intercept = Proto->Y - Slope * Proto->X;
00175 Normalizer = 1.0 / sqrt (Slope * Slope + 1.0);
00176 Proto->A = Slope * Normalizer;
00177 Proto->B = -Normalizer;
00178 Proto->C = Intercept * Normalizer;
00179 }
00180
00181
00185 void FreeClass(CLASS_TYPE Class) {
00186 if (Class) {
00187 FreeClassFields(Class);
00188 memfree(Class);
00189 }
00190 }
00191
00192
00196 void FreeClassFields(CLASS_TYPE Class) {
00197 int i;
00198
00199 if (Class) {
00200 if (Class->MaxNumProtos > 0)
00201 memfree (Class->Prototypes);
00202 if (Class->MaxNumConfigs > 0) {
00203 for (i = 0; i < NumConfigsIn (Class); i++)
00204 FreeBitVector (ConfigIn (Class, i));
00205 memfree (Class->Configurations);
00206 }
00207 }
00208 }
00209
00210
00215 void InitPrototypes() {
00216 string_variable (TrainingFile, "TrainingFile", "MicroFeatures");
00217 }
00218
00219
00224 CLASS_TYPE NewClass(int NumProtos, int NumConfigs) {
00225 CLASS_TYPE Class;
00226
00227 Class = (CLASS_TYPE) Emalloc (sizeof (CLASS_STRUCT));
00228
00229 if (NumProtos > 0)
00230 Class->Prototypes = (PROTO) Emalloc (NumProtos * sizeof (PROTO_STRUCT));
00231
00232 if (NumConfigs > 0)
00233 Class->Configurations = (CONFIGS) Emalloc (NumConfigs *
00234 sizeof (BIT_VECTOR));
00235 Class->MaxNumProtos = NumProtos;
00236 Class->MaxNumConfigs = NumConfigs;
00237 Class->NumProtos = 0;
00238 Class->NumConfigs = 0;
00239 return (Class);
00240
00241 }
00242
00243
00247 void PrintProtos(CLASS_TYPE Class) {
00248 INT16 Pid;
00249
00250 for (Pid = 0; Pid < NumProtosIn (Class); Pid++) {
00251 cprintf ("Proto %d:\t", Pid);
00252 PrintProto (ProtoIn (Class, Pid));
00253 cprintf ("\t");
00254 PrintProtoLine (ProtoIn (Class, Pid));
00255 new_line();
00256 }
00257 }
00258
00259
00267 void ReadClassFile() {
00268 FILE *File;
00269 char TextLine[CHARS_PER_LINE];
00270
00271 cprintf ("Reading training data from '%s' ...", TrainingFile);
00272 fflush(stdout);
00273
00274 File = open_file (TrainingFile, "r");
00275 while (fgets (TextLine, CHARS_PER_LINE, File) != NULL) {
00276
00277 ReadClassFromFile (File, TextLine[0]);
00278 fgets(TextLine, CHARS_PER_LINE, File);
00279 fgets(TextLine, CHARS_PER_LINE, File);
00280 }
00281 fclose(File);
00282
00283 new_line();
00284 }
00285
00286
00292 void ReadClassFromFile(FILE *File, char ClassChar) {
00293 CLASS_TYPE Class;
00294
00295 Class = &TrainingData[ClassChar];
00296
00297 ReadProtos(File, Class);
00298
00299 ReadConfigs(File, Class);
00300 }
00301
00302
00308 void ReadConfigs(register FILE *File, CLASS_TYPE Class) {
00309 INT16 Cid;
00310 register INT16 Wid;
00311 register BIT_VECTOR ThisConfig;
00312 int NumWords;
00313 int NumConfigs;
00314
00315 fscanf (File, "%d %d\n", &NumConfigs, &NumWords);
00316 NumConfigsIn (Class) = NumConfigs;
00317 Class->MaxNumConfigs = NumConfigs;
00318 Class->Configurations =
00319 (CONFIGS) Emalloc (sizeof (BIT_VECTOR) * NumConfigs);
00320 NumWords = WordsInVectorOfSize (NumProtosIn (Class));
00321
00322 for (Cid = 0; Cid < NumConfigs; Cid++) {
00323
00324 ThisConfig = NewBitVector (NumProtosIn (Class));
00325 for (Wid = 0; Wid < NumWords; Wid++)
00326 fscanf (File, "%x", &ThisConfig[Wid]);
00327 ConfigIn (Class, Cid) = ThisConfig;
00328 }
00329 }
00330
00331
00337 void ReadProtos(register FILE *File, CLASS_TYPE Class) {
00338 register INT16 Pid;
00339 register PROTO Proto;
00340 int NumProtos;
00341
00342 fscanf (File, "%d\n", &NumProtos);
00343 NumProtosIn (Class) = NumProtos;
00344 Class->MaxNumProtos = NumProtos;
00345 Class->Prototypes = (PROTO) Emalloc (sizeof (PROTO_STRUCT) * NumProtos);
00346
00347 for (Pid = 0; Pid < NumProtos; Pid++) {
00348 Proto = ProtoIn (Class, Pid);
00349 fscanf (File, "%f %f %f %f %f %f %f\n",
00350 &ProtoX (Proto),
00351 &ProtoY (Proto),
00352 &ProtoLength (Proto),
00353 &ProtoAngle (Proto),
00354 &CoefficientA (Proto),
00355 &CoefficientB (Proto), &CoefficientC (Proto));
00356 }
00357 }
00358
00359
00370 int SplitProto(CLASS_TYPE Class, int OldPid) {
00371 int i;
00372 int NewPid;
00373 BIT_VECTOR Config;
00374
00375 NewPid = AddProtoToClass (Class);
00376
00377 for (i = 0; i < NumConfigsIn (Class); i++) {
00378 Config = ConfigIn (Class, i);
00379 if (test_bit (Config, OldPid))
00380 SET_BIT(Config, NewPid);
00381 }
00382 return (NewPid);
00383 }
00384
00385
00390 void WriteOldConfigFile(FILE *File, CLASS_TYPE Class) {
00391 int Cid, Pid;
00392 BIT_VECTOR Config;
00393
00394 fprintf (File, "%d %d\n", NumConfigsIn (Class), NumProtosIn (Class));
00395
00396 for (Cid = 0; Cid < NumConfigsIn (Class); Cid++) {
00397 fprintf (File, "1 ");
00398
00399 Config = ConfigIn (Class, Cid);
00400
00401 for (Pid = 0; Pid < NumProtosIn (Class); Pid++) {
00402 if (test_bit (Config, Pid))
00403 fprintf (File, "1");
00404 else
00405 fprintf (File, "0");
00406 }
00407 fprintf (File, "\n");
00408 }
00409 }
00410
00411
00415 void WriteOldProtoFile(FILE *File, CLASS_TYPE Class) {
00416 int Pid;
00417 PROTO Proto;
00418
00419
00420 fprintf (File, "6\n");
00421 fprintf (File, "linear essential -0.500000 0.500000\n");
00422 fprintf (File, "linear essential -0.250000 0.750000\n");
00423 fprintf (File, "linear essential 0.000000 1.000000\n");
00424 fprintf (File, "circular essential 0.000000 1.000000\n");
00425 fprintf (File, "linear non-essential -0.500000 0.500000\n");
00426 fprintf (File, "linear non-essential -0.500000 0.500000\n");
00427
00428 for (Pid = 0; Pid < NumProtosIn (Class); Pid++) {
00429 Proto = ProtoIn (Class, Pid);
00430
00431 fprintf (File, "significant elliptical 1\n");
00432 fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n",
00433 ProtoX (Proto), ProtoY (Proto),
00434 ProtoLength (Proto), ProtoAngle (Proto), 0.0, 0.0);
00435 fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n",
00436 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001);
00437 }
00438 }