Here is some code I wrote to compute FCM. I used this while learning about Fuzzy Systems. Just posted here for storage.
FCM is one of the technologies in field of Soft Computing.
// ************************************************************************* // File: FCM2.H ver. 0.03 Date: September 25, 1993 // By: Josef Betancourt System: Borland C++ ver. 2.0. // ************************************************************************* /* Purpose: Illustrate the Fuzzy Cognitive Map computations. This is a very very simple implementation of the FCM example found in: "Neural Networks and Fuzzy Systems". Kosko, B. page 154. "Fuzzy Thinking, the new science of fuzzy logic". Kosko, B. page 222. "Fuzzy Logic". McNeill D., Freiberger, P. page 237. I used a very nice matrix class called Beginner's Understandable Matrix Package, BUMP.ZIP, by Clopper Almon. It is found in the Borland C++ forum on CIS. This version of my FCM implementation allows the setting of more than one policy variable in the policy vector. This is accomplished by loading a state setting i by 2 matrix. If column one is zero than cell i in the policy vector is not reset by the state vector, else during the reasoning process that cell is reset to the value in column two. ------------------------------------------------------------------------- Of course, a general purpose interactive graphical system where the FCM can be entered graphically by multiple experts and the inference process is visually presented would be nice. It should be a FCM CAD system! But are FCMs really useful? How are they used in control systems? -------------------------------------------------------------------------- USE: This must be compiled and linked with BUMP.CPP. Large memory model. Example FCM file Policy State ------------------------------------------------------------------ Africa AFRICA.TXT INVEST.TXT INVEST2.TXT Africa AFRICA.TXT DIVEST.TXT DIVEST2.TXT Cocaine COCAINE.TXT INTERDIC.TXT INTERDI2.TXT To test the africa example, Use the syntax: FCM africa.txt invest.txt invest2.txt 9 .5 or FCM africa.txt divest.txt divest2.txt 9 .5 To test the cocaine example in the book Fuzzy Thinking, Use the syntax: FCM cocaine.txt interdic.txt interdi2.txt 11 .5 ( this example does not result in cocaine supply falling as stated in the book.) */ #ifndef FCM2_H #define FCM2_H // ----------------------- // dependencies #include <iostream.h> // for cout #include <ctype.h> // for isdigit() #include <stdio.h> // for fgets() #include <alloc.h> // for coreleft() #include <stdlib.h> // for atof() #include <conio.h> // for cprintf() #include "bump.h" // for Matrix class // ----------------------- #define TRUE (1==1) #define FALSE (!TRUE) class FCM; // forward reference. // Prototypes void Reason( FCM &fcm); void Again(void); void ThresholdMF( Matrix & mat, float thresh = .5); void ConvertMat( Matrix & matDest, Matrix &matSrc); void ResetPolicy( Matrix & matDest, Matrix &matSrc); void ShowCondenseMP( Matrix &Mat); void DrawBorder(void); class FCM{ // Fuzzy Cognitive Map protected: Matrix *pmatFCM; // directed graph. Matrix *pmatPolicy; // initial policy. Matrix *pmatState; // policies to reset after epoch. char *Names[]; // the labels of each node. int nPolicies; // number of nodes. float fThreshold; public: FCM( int n); // constructor. // FCM( FCM other); // copy constructor. // ~FCM(); // destructor. void SetSizeI( int size){ nPolicies = size;} void SetThresh( float fthr){ fThreshold = fthr; } int IGetSize( void){ return nPolicies;} void SetFCM( Matrix *fcm){ pmatFCM = fcm;} void SetPolicy( Matrix *Policy){ pmatPolicy = Policy;} void SetState( Matrix *State){ pmatState = State; } void ReadFCM( char *psz); float &Cell( Matrix *pmat, int i, int j); float GetCell( Matrix *pmat, int i, int j); void ReasonStep( void); void ThresholdMF(void); void ResetPolicy( void ); void DisplayPolicy( char *msg); Matrix &WhatIsPolicy( void){ return *pmatPolicy ; } void DumpPolicy(void); }; // end of file FCM2.H #endif // ************************************************************************* // File: FCM2.CPP ver. 0.03 Date: September 25, 1993 // By: Josef Betancourt tcmits1@cs.com System: Borland C++ 4.0 // ************************************************************************* /* Purpose: Illustrate the Fuzzy Cognitive Map computations. */ // dependencies.... #include "fcm2.h" // ----------------------------------------- // constructor. FCM::FCM( int size){ SetSizeI(size ); fThreshold = .5; } // ----------------------------------------- // get address of Cell. float &FCM::Cell( Matrix *pmat, int i, int j){ return pmat->operator[](i)[j]; } // ----------------------------------------- // get cell contents. float FCM::GetCell( Matrix *pmat, int i, int j){ return pmat->operator[](i)[j]; } // ----------------------------------------- // void FCM::ReasonStep( void){ // Matrix multiply. Nice syntax! *pmatPolicy = (*pmatPolicy)*(*pmatFCM); //DisplayPolicy( "policy after multiply: "); ThresholdMF(); //DisplayPolicy( "policy after threshold: "); ResetPolicy(); //DisplayPolicy( "policy after reset: "); } // ----------------------------------------- // threshold policy vector. void FCM::ThresholdMF( void ){ // apply thresh to policy matrix, default thresh is 0.5. for( int i = 1; i < nPolicies + 1; i++){ if( GetCell( pmatPolicy, 1, i) >= fThreshold ){ Cell(pmatPolicy, 1, i) = 1.; }else{ Cell( pmatPolicy, 1, i) = 0; } } } // ----------------------------------------- // reset policy with state vector. void FCM::ResetPolicy( void ){ for( int i = 1; i < nPolicies+1; i++){ if( GetCell( pmatState, i,1) == 1){ Cell( pmatPolicy, 1, i) = GetCell(pmatState, i, 2) ; } } } // ----------------------------------------- // show policy using matrix library display routine. void FCM::DisplayPolicy( char *message){ pmatPolicy->Display(message); } // ----------------------------------------- // dump policy as simple number dump. void FCM::DumpPolicy(void){ for( int i=1; i < nPolicies+1; i++){ cout << GetCell( pmatPolicy, 1, i); } } // ----------------------- int main(int argc, char * argv[]){ cout << "\n*** Fuzzy Cognitive Map example. By Josef Betancourt ***\n"; if( argc != 6 ){ cerr << "\nUsage: fcm <FCM file> <policy file> <state file>"; cerr << "<matrix size> <thresh>\n"; cerr << " Where cell and value refer to policy vector.\n"; exit (-1); } // convert strings to integers........... int iSize = atoi(argv[4]); // matrix order. float fThresh = atof( argv[5]); // threshold value. FCM theFCM( iSize); // create the helper matrices. Matrix matFCM(iSize,iSize), matPolicy(1, iSize), matVPolicy(1,iSize), matState( iSize, 2); // link them into the FCM theFCM.SetFCM( &matFCM); theFCM.SetPolicy( &matPolicy); theFCM.SetState( &matState); theFCM.SetThresh( fThresh); // populate using files matFCM.ReadA( argv[1] ); matPolicy.ReadA( argv[2] ); matState.ReadA( argv[3] ); // and show matrices .......... matFCM.Display("This is the FCM matrix:"); matPolicy.Display("This is the policy matrix: "); matState.Display("This is the state matrix: "); cout << "test of dump\n" ; theFCM.DumpPolicy(); Again(); // wait for key tap or escape. // perform the FCM process using the object. Reason(theFCM ); return FALSE; } // end of main. // ----------------------- void Reason( FCM &fcm ){ // apply simple FCM computation using matrices. int i = 1; // epoch counter. while( 1){ cout << "Epoch " << i << '\n'; fcm.ReasonStep(); fcm.DisplayPolicy("New policy vector: "); // for ease in seeing limit cycles. ShowCondenseMP( fcm.WhatIsPolicy() ); DrawBorder(); Again(); // wait for key tap or escape. i++; } } // reason end. // ----------------------- void ShowCondenseMP( Matrix &Mat){ // print policy vector in a more visual pattern. cout << "\nPattern: "; char temp ; for( int i=1; i< Mat.columns()+1; i++){ if( Mat[1][i] > 0 ){ temp = 0x2; }else{ if( Mat[1][i] < 0){ temp = 0x1F; }else{ temp = 0x1; } } cout.put( temp); } cout << '\n' ; } // ----------------------- void DrawBorder(void){ cout << '\n'; for( int i=0; i<75; i++){ cout.put( char(0xDF) ); } cout << '\n'; } // ----------------------- void Again(void){ // query user for continuation or end of run. cerr << "\n\t\t\t< Tap a key to continue. ESC to exit. >\n"; if(getch() == 27){ exit(0); } } // ---------------------------------------------------------------------- /* computing Eigenvectors is similar to computing a FCM without the thresholding. Here is such an algorithm. void EigenTest(int size, char *pszName){ // algorithim from Computational Linear Algebra with Models. // Williams, Gareth. Allyn and Bacon, Massachusetts. 1978. page 449. float e, s, t; int i, j, k, M; Matrix A(size,size), X(size,1),Y(size,1),Z(size,1); A.ReadA(pszName); A.Display("Here is the B matrix:"); AllOnes( X); while(1){ cout << "Iteration " << i << "\n"; Y = A * X; Y.Display("Here is the Y matrix:"); k=1; for( j=2; j < Y.rows()+1;j++){ if( fabs( Y[k][1]) >= fabs( Y[j][1]) ){ continue; } k= j; } Y = ( 1/ fabs( Y[k][1])) * Y; X = Y; X.Display("the adjusted vector is:"); Z = A*X; s=0; t=0; for( M=1; M<size + 1; M++){ s += X[M][1] * Z[M][1]; t += X[M][1] * X[M][1]; } e = s/t; cout << "Approx eigenvalue is " << e << "\n" ; Again(); } } */ // ----------------------- // End of file FCM.CPP *********************************
Off topic
There are a lot of examples of connectionist presentations. I wonder if these could be coupled with the FCM technique to create computable structures. For example, look at the work of Mark Lombardi.
Links
- Predictive Interface using Fuzzy Logic
- “Fuzzy cognitive maps“, Bart Kosko. Int. J. Man-Machine Studies (1986) 24, 65-75. http://sipi.usc.edu/~kosko/FCM.pdf Accessed January 20, 2014.
- Fuzzy cognitive map
- Fuzzy Logic: An Introduction
- NOVA scienceNOW Robots (2013)
- “Fuzzy Cognitive Map Software” by Chrysostomos stylios