00001 #ifndef HAMMING_CLASS 00002 #define HAMMING_CLASS 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : hamming network * 00007 * Author : Chris Koeritz * 00008 * * 00009 ******************************************************************************* 00010 * Copyright (c) 1992-$now By Author. This program is free software; you can * 00011 * redistribute it and/or modify it under the terms of the GNU General Public * 00012 * License as published by the Free Software Foundation; either version 2 of * 00013 * the License or (at your option) any later version. This is online at: * 00014 * http://www.fsf.org/copyleft/gpl.html * 00015 * Please send any updates to: fred@gruntose.com * 00016 \*****************************************************************************/ 00017 00018 #include "hamming_dll.h" 00019 00020 #include <basis/chaos.h> 00021 00022 #include <stdio.h> 00023 00024 //hmmm: move this constant stuff to inside the cpp file. 00025 00026 // The names below tell the program where to locate its data files. 00027 // defaults are necessary for it to know exemplar sizes and the number 00028 // of exemplars, while the prefix is what every exemplar starts with. 00029 // exemplars will be read in in the form exempl00.dat through 00030 // exempl{m-1}.dat, where {m} is the total number of exemplars. 00031 #define DEFAULTS_FILE_NAME "./data/defaults.dat" 00032 #define EXEMPLAR_PREFIX "./data/exempl" 00033 00034 // MBIP = largest value for N, ME = largest value for M 00035 // the following values are obtained from the defaults file. 00036 #define MAXIMUM_BITS_IN_PATTERN 100 00037 #define MAXIMUM_EXEMPLARS 50 00038 00039 // iterations allowed before abandoning convergence. 00040 #define MAXIMUM_ITERATION 30 00041 00042 // the size of the terminal's screen. 00043 #define SCREEN_WIDTH 80 00044 00045 // patterns are read from files or entered by the user. 00046 typedef int bit_pattern[MAXIMUM_BITS_IN_PATTERN]; 00047 00048 00049 00051 00052 class HAMMING_CLASS_STYLE hamming 00053 { 00054 public: 00055 // The unknown (and user specified) input pattern. 00056 bit_pattern x; 00057 00058 // the constructor and destructor do not do anything yet. 00059 hamming(); 00060 ~hamming(); 00061 00062 // corrupter: flips the number of bits specified by _faults_ 00063 // in an exemplar pattern. 00064 void corrupter(int ex[], int faults); 00065 00066 // init_lower_subnet: initialize the weight matrix for the lower network. 00067 // if _faults_ is positive, the specified number of weights 00068 // will be corrupted to some random value (see note about faults). 00069 void init_lower_subnet(int faults); 00070 00071 // init_upper_subnet: init the weight matrix for the upper subnet, Maxnet. 00072 // _faults_ is the number of faulty weight lines. (see note). 00073 void init_upper_subnet(int faults); 00074 00075 // f_thresh: implement a threshold logic non-linearity, the function 00076 // each node is calculating. 00077 double f_thresh(double alpha); 00078 00079 // init_with_unknown_pattern: apply an unknown input pattern to the 00080 // lower net and derive state 0 of the maxnet's outputs. 00081 // a number (faults) of the first output components are corrupted. 00082 void init_with_unknown_pattern(int faults); 00083 00084 // converge: inhibits the less likely outputs to achieve one optimal 00085 // solution. 00086 void converge(); 00087 00088 // iterate_until_converges: repeatedly calls converge until there 00089 // is only one positive output of maxnet. this is chosen as the 00090 // closest exemplar to the input pattern and returned. 00091 int iterate_until_convergence(); 00092 00093 // show_pattern_line: prints a particular line from the pattern ex[]. 00094 // the second version prints the line to a file. 00095 void show_pattern_line(int ex[], int line); 00096 void show_pattern_line(int ex[], int line, FILE *print_to); 00097 void show_pattern_line(int exemplar_number, int line, FILE *print_to); 00098 00099 // dump_pattern: prints one entire pattern. 00100 void dump_pattern(int ex[]); 00101 00102 // copy_pattern: 00103 void copy_pattern(bit_pattern destination, bit_pattern source); 00104 00105 // show_exemplars: display the whole set of exemplars. 00106 void show_exemplars(); 00107 00108 // get_sample: queries for patterns interactively. 00109 void get_sample(); 00110 00111 // save_sample: stores an example input. 00112 void save_sample(); 00113 00114 // read_file: reads a pattern out of the file specified 00115 // and stored it in the array. 00116 void read_file(char *filename, int pattern[]); 00117 00118 // get_defaults: 00119 void get_defaults(); 00120 00121 // get_exemplars: 00122 void get_exemplars(); 00123 00124 // print_instructions_and_exit: 00125 void print_instructions_and_exit(); 00126 00127 // current_time, pattern_rows, pattern_cols: windows into the program's variables. 00128 int current_time(); 00129 int pattern_rows(); 00130 int pattern_cols(); 00131 00132 private: 00133 00134 // maxnet_output_sum: sums all maxnet outputs, except at node j, 00135 // using the values as they were at time t. 00136 double maxnet_output_sum(int j); 00137 00138 // only_one_positive_output_left: if only one output (mu) at time t 00139 // is left standing, then that output is returned. otherwise, a 00140 // negative value is returned to denote that convergence has not 00141 // yet happened. 00142 int only_one_positive_output_left(); 00143 00144 // weighted_sum: 00145 double weighted_sum(int j); 00146 00147 // corrupted_sum: 00148 double corrupted_sum(); 00149 00150 // The current simulation time in "units", or simulation steps. 00151 int t; 00152 00153 int rows; // height of pattern 00154 int cols; // width of pattern 00155 00156 int M; // number of exemplar patterns 00157 int N; // number of bits per pattern (rows x cols) 00158 00159 // exemplars are the patterns to be recognized. 00160 int exemplars [MAXIMUM_EXEMPLARS] [MAXIMUM_BITS_IN_PATTERN]; 00161 00162 chaos randomizer; 00163 00164 // The weights of the lower subnet, set from the hamming distances 00165 // of the exemplars. 00166 double w [MAXIMUM_BITS_IN_PATTERN] [MAXIMUM_EXEMPLARS]; 00167 // The weights of Maxnet, which inhibits the outputs whose exemplars 00168 // are not close in hamming distance to the unknown input pattern. 00169 double maxnet [MAXIMUM_EXEMPLARS] [MAXIMUM_EXEMPLARS]; 00170 // Temporary pattern used to hold the input pattern between corruptions. 00171 bit_pattern y; 00172 // The output at time t. It is in matrix form because each output is 00173 // kept as time goes along discretely. Since the net often converges 00174 // by the tenth time unit, this is reasonable. 00175 double mu [MAXIMUM_ITERATION] [MAXIMUM_EXEMPLARS]; 00176 00177 // The threshold value that for maxnet's outputs. 00178 double THETA; 00179 // Maxnet inhibitory weight. 00180 double EPSILON; 00181 }; 00182 00183 // A NOTE about faults added to the net: 00184 // Major ASSUMPTION: Faults only occur between training periods of 00185 // the net; no faults will occur while the net is actually working 00186 // on an unknown input pattern. This is a reasonable assumption if 00187 // the duration between uses of the net is long compared to the duration 00188 // of time to recognize a pattern. Since our net is always initialized 00189 // before each attempt at recognition, that reasoning works here. 00190 // ASSUMPTION: in init_lower_subnet, the weight will only be corrupted 00191 // within the range in which it is usually valid. If, in reality, a fault 00192 // can cause the weight in the net to vary beyond -.5 to .5, then this 00193 // would not represent the behavior of the net very accurately. 00194 // ASSUMPTION: in init_upper_subnet, the faulty line could be at ANY of 00195 // the maxnet lines, including the self connection. 00196 // ASSUMPTION: in init_upper_subnet again, the value of the faulty line 00197 // ranges over the entire spectrum from -1 to 1, since these are valid 00198 // values that the net is programmed with (self con=1, all others equal 00199 // -EPSILON). If this is not really possible, the simulation is again not 00200 // going to mimic real faults very accurately. 00201 // ASSUMPTION: the corruption in init_with_unknown_pattern affects an 00202 // entire output for some exemplar. originally, the exemplar's output 00203 // took on a random value over the entire range for an output (N/2 to -N/2), 00204 // but this caused ...? 00205 // the same warning about real life applies. the output thus has nothing 00206 // to do with any of the maxnet lines; the error is totally unrelated to 00207 // the inputs that the output usually considers. 00208 00209 //-------------------------------------------------------------------------- 00210 // Revision History: 00211 // 3/1992-4/1992: modified by Chris Koeritz. 00212 // the program was made useable for the EE734 Fault Tolerance Project. 00213 // this meant numerous revisions. the prior program structure 00214 // was mostly tossed in favor of mimicking lippmann's exact 00215 // algorithm. this led to a result much like lippman's, whereas 00216 // the prior version of this program was _very_ different from what 00217 // lippmann described, to the point of ignoring the value for theta. 00218 //-------------------------------------------------------------------------- 00219 // modified for interactive input patterns - Marilyn Nelson, Feb. 1991 00220 // c version of the hamming net, david leasure, 9/25/87 00221 // this routine is a hamming classification network 00222 // described in IEEE ASSP April 1987 by Richard P. Lippmann pg. 9 00223 // correcting for a presumed bug in the presented routine 00224 // the bug is the value set for THETA by Lippmann. When THETA is 00225 // N / 2 it so overwhelms the outputs from the lower net that only 0 00226 // activation values are passed up from the threshold function. 00227 // I have chosen to set epsilon to 1 / 2M and to not have an upper 00228 // limit on the threshold function so no saturation occurs 00229 // the program is somewhat inefficient because of the use of 00230 // data storage for maxnet (t[k,l] in lippman's) and for output[t,M] 00231 // but they could be useful in a simulator of this network which allowed 00232 // things to be fiddled with. 00233 // the code could be improved by not encoding the size and values 00234 // of the node matrices directly, too, reading them instead from files 00235 // and/or a user interface. 00236 // 00237 // if you improve the code, please send me the diff's 00238 // david e. leasure 00239 // ihnp4!homxc!del or del@homxc.att.com 00240 00241 #endif 00242
1.5.1