Neural Networks Source Codes - Bidirectional Associative Memory -------------------------------------------------------------------------------- Bidirectional Associative Memory -------------------------------------------------------------------------------- This program is copyright (c) 1996 by the author. It is made available as is, and no warranty - about the program, its performance, or its conformity to any specification - is given or implied. It may be used, modified, and distributed freely for private and commercial purposes, as long as the original author is credited as part of the final work. Bidirectional Associative Memory Simulator /****************************************************************************** ================================ Network: Bidirectional Associative Memory ================================ Application: Heteroassociative Memory Association of Names and Phone Numbers Author: Karsten Kutza Date: 24.1.96 Reference: B. Kosko Bidirectional Associative Memories IEEE Transactions on Systems, Man, and Cybernetics, 18, pp. 49-60, 1988 ******************************************************************************/ /****************************************************************************** D E C L A R A T I O N S ******************************************************************************/ #include #include typedef int BOOL; typedef char CHAR; typedef int INT; #define FALSE 0 #define TRUE 1 #define NOT ! #define AND && #define OR || #define LO -1 #define HI +1 #define BINARY(x) ((x)==LO ? FALSE : TRUE) #define BIPOLAR(x) ((x)==FALSE ? LO : HI) typedef struct { /* A LAYER OF A NET: */ INT Units; /* - number of units in this layer */ INT* Output; /* - output of ith unit */ INT** Weight; /* - connection weights to ith unit */ } LAYER; typedef struct { /* A NET: */ LAYER* X; /* - X layer */ LAYER* Y; /* - Y layer */ } NET; /****************************************************************************** R A N D O M S D R A W N F R O M D I S T R I B U T I O N S ******************************************************************************/ void InitializeRandoms() { srand(4711); } BOOL RandomEqualBOOL() { return rand() % 2; } /****************************************************************************** A P P L I C A T I O N - S P E C I F I C C O D E ******************************************************************************/ #define NUM_DATA 3 #define IN_CHARS 5 #define OUT_CHARS 7 #define BITS_PER_CHAR 6 #define FIRST_CHAR ' ' #define N (IN_CHARS * BITS_PER_CHAR) #define M (OUT_CHARS * BITS_PER_CHAR) CHAR Names [NUM_DATA][IN_CHARS] = { "TINA ", "ANTJE", "LISA " }; CHAR Names_[NUM_DATA][IN_CHARS] = { "TINE ", "ANNJE", "RITA " }; CHAR Phones[NUM_DATA][OUT_CHARS] = { "6843726", "8034673", "7260915" }; INT Input [NUM_DATA][N]; INT Input_[NUM_DATA][N]; INT Output[NUM_DATA][M]; FILE* f; void InitializeApplication(NET* Net) { INT n,i,j,a,a_; for (n=0; nUnits / BITS_PER_CHAR); i++) { a = 0; p = 1; for (j=0; jOutput[i*BITS_PER_CHAR+j]) * p; p *= 2; } fprintf(f, "%c", a + FIRST_CHAR); } } void FinalizeApplication(NET* Net) { fclose(f); } /****************************************************************************** I N I T I A L I Z A T I O N ******************************************************************************/ void GenerateNetwork(NET* Net) { INT i; Net->X = (LAYER*) malloc(sizeof(LAYER)); Net->Y = (LAYER*) malloc(sizeof(LAYER)); Net->X->Units = N; Net->X->Output = (INT*) calloc(N, sizeof(INT)); Net->X->Weight = (INT**) calloc(N, sizeof(INT*)); Net->Y->Units = M; Net->Y->Output = (INT*) calloc(M, sizeof(INT)); Net->Y->Weight = (INT**) calloc(M, sizeof(INT*)); for (i=0; iX->Weight[i] = (INT*) calloc(M, sizeof(INT)); } for (i=0; iY->Weight[i] = (INT*) calloc(N, sizeof(INT)); } } void CalculateWeights(NET* Net) { INT i,j,n; INT Weight; for (i=0; iX->Units; i++) { for (j=0; jY->Units; j++) { Weight = 0; for (n=0; nX->Weight[i][j] = Weight; Net->Y->Weight[j][i] = Weight; } } } void SetInput(LAYER* Layer, INT* Input) { INT i; for (i=0; iUnits; i++) { Layer->Output[i] = Input[i]; } WriteLayer(Layer); } void SetRandom(LAYER* Layer) { INT i; for (i=0; iUnits; i++) { Layer->Output[i] = BIPOLAR(RandomEqualBOOL()); } WriteLayer(Layer); } void GetOutput(LAYER* Layer, INT* Output) { INT i; for (i=0; iUnits; i++) { Output[i] = Layer->Output[i]; } WriteLayer(Layer); } /****************************************************************************** P R O P A G A T I N G S I G N A L S ******************************************************************************/ BOOL PropagateLayer(LAYER* From, LAYER* To) { INT i,j; INT Sum, Out; BOOL Stable; Stable = TRUE; for (i=0; iUnits; i++) { Sum = 0; for (j=0; jUnits; j++) { Sum += To->Weight[i][j] * From->Output[j]; } if (Sum != 0) { if (Sum < 0) Out = LO; if (Sum > 0) Out = HI; if (Out != To->Output[i]) { Stable = FALSE; To->Output[i] = Out; } } } return Stable; } void PropagateNet(LAYER* From, LAYER* To) { BOOL Stable1, Stable2; do { Stable1 = PropagateLayer(From, To); Stable2 = PropagateLayer(To, From); } while (NOT (Stable1 AND Stable2)); } /****************************************************************************** S I M U L A T I N G T H E N E T ******************************************************************************/ void SimulateNet(LAYER* From, LAYER* To, INT* Pattern, INT* Input, INT* Output) { SetInput(From, Pattern); fprintf(f, " -> "); SetRandom(To); fprintf(f, " | "); PropagateNet(From, To); GetOutput(From, Input); fprintf(f, " -> "); GetOutput(To, Output); fprintf(f, "\n\n"); } /****************************************************************************** M A I N ******************************************************************************/ void main() { NET Net; INT n; INT I[N], O[M]; InitializeRandoms(); GenerateNetwork(&Net); InitializeApplication(&Net); CalculateWeights(&Net); for (n=0; n P:*[HBQ | TINA -> 6843726 ANTJE -> !_+87&9 | ANTJE -> 8034673 LISA -> )@;ZV)- | LISA -> 7260915 6843726 -> SP4^L | 6843726 -> TINA 8034673 -> ^;GI# | 8034673 -> ANTJE 7260915 -> A-/%1 | 7260915 -> LISA TINE -> CW48F ^ | TINA -> 6843726 ANNJE -> @ZB%8Q! | ANTJE -> 8034673 RITA -> H0(@=^/ | DIVA -> 6060737