// Sample FLC program: 1 FLC, single or grid output // #include "stdafx.h" #include "conio.h" #include "time.h" #include "math.h" #include "ConfigString.h" #include using namespace std; inline int numdigits(int n) { // get num digits in number (radix 10) int i, pow10; i = pow10 = 1; if (n<0) return 0; while (n / pow10 > 1) {pow10*=10;i++;}; return i; } int _tmain(int argc, _TCHAR* argv[]) { CFLC * FLC = new CFLC; // instantiate a new FL 'empty' controller printf("sFLC3 Sample Console Program\n"); printf("\n1. Create FLC Name: %s (FLC number:%i)\n", FLC->Name().c_str(), FLC->GetFLCNum()); int sn = 0; // Shape is either 0 or 1 cout << "2. Enter Shape Number (0 for 3x3 or 1 for 5x5) :"; cin >> sn; FLC->SetShape(sn); // Define a 3x3 or a 5x5 FLC model int m_nDefaultFuzzySetModel[3] = { 0, 0, 0 }; int m_nDefaultRuleSetModel = 0; cout << "3. Enter Default Fuzzy Set Model for Input 1.(Min 0, Max " << FLC->FSModelMax() << ")" ; cin >> m_nDefaultFuzzySetModel[0]; cout << "4. Enter Default Fuzzy Set Model for Input 2. (Min 0, Max " << FLC->FSModelMax() << ")" ; cin >> m_nDefaultFuzzySetModel[1]; cout << "5. Enter Default Fuzzy Set Model for Output. (Min 0, Max " << FLC->FSModelMax() << ")" ; cin >> m_nDefaultFuzzySetModel[2]; cout << "6. Enter Default Rule Set Model. (Min 0, Max:" << FLC->RSModelMax()<< ")";; cin >> m_nDefaultRuleSetModel; FLC->SetRSModel(m_nDefaultRuleSetModel); // In this sample program, we choose to have only 1 FS per Variable // Num fuzzy sets could be any positive number, here 3 int ret = FLC->InitFuzzySets( 3 ); if (ret < 0) { printf("Fuzzy Sets could not be created. Error:%i\n", ret); FLC->Reset(); delete FLC; _getch(); return -1; } else printf("\n%i Fuzzy Sets have been created.", FLC->GetNumFuzzySets()); int nNumFuzzyStates = (sn == 0) ? 3 : 5; int nNumFuzzySets = FLC->GetNumFuzzySets(); CFuzzySet* pFSet = FLC->FSArray(); for (int i = 0; i < nNumFuzzySets; i++) { int ret = pFSet[i].InitFuzzySet(nNumFuzzyStates,1); if (ret < 0) { printf("\nFuzzy Sets could not be initialised. Error:%i\n", ret); FLC->Reset(); delete FLC; _getch(); return -1; } ret = pFSet[i].DefineFuzzySet(m_nDefaultFuzzySetModel[i]); // before any possible change if (ret < 0) { printf("\nFuzzy Sets could not be defined. Error:%i\n", ret); FLC->Reset(); delete FLC; _getch(); return -1; } printf("\n%i. FS%i is defined with model %i: %s (Wording:%i)", i+1, i+1, m_nDefaultFuzzySetModel[i], pFSet[i].GetFSmodelname().c_str(), pFSet[i].GetFSwording()); } int nv = 3; // 2 inputs and 1 output ret = FLC->InitVarSet(nv); // (default constructor for variables) if (ret < 0) { printf("\nVar Set could not be created: %i\n", ret); FLC->Reset(); delete FLC; _getch(); return -1; } else printf("\n\n%i Variables have been created (1=Input,0=Output)", nv = FLC->GetNumVars()); CFLVariable* pVars = FLC->VarArray(); for (int i = 0; i < nv; i++) { // Assuming here the last variable is the output BOOL bInputOutput = (i == nv - 1) ? FALSE : TRUE; int ret = pVars[i].LoadFuzzySet(pFSet[i],bInputOutput); if (ret < 0) { printf("\nFuzzy Set could not be linked to Var: %i. Error:%i\n", i, ret); FLC->Reset(); delete FLC; _getch(); return -1; } else { printf("\nVar%i (%i) has FS%i loaded (num states: %i)", i+1, bInputOutput, i+1, pVars[i].NumStates() ); } } ret = FLC->DetermineRuleSetSize(); if (ret < 0) { printf("\nRule Set could not be created: %i", ret); FLC->Reset(); delete FLC; _getch(); return -1; } else printf("\nRule Set size: %i \n", ret); int irs = FLC->InitRuleSet(); // generate an array of rules (RuleSetSize can be given or not) if (ret < 0) { printf("\nRule Set could not be initialised: %i\n", irs); FLC->Reset(); delete FLC; _getch(); return -1; } ret = FLC->AllocateRuleSpace(); int NumRules = FLC->GetRuleSetSize(); CFLRule *pFLR = FLC->RuleArray(); // get a pointer to the rule set int RS_ret; if (sn == 0) RS_ret = FLC->LoadDefault33RuleSet(pFLR, NumRules, m_nDefaultRuleSetModel); else RS_ret = FLC->LoadDefault55RuleSet(pFLR, NumRules, m_nDefaultRuleSetModel); if (RS_ret < 0) { printf("\nDefault Rule Set could not be loaded: %i", RS_ret); FLC->Reset(); delete FLC; _getch(); return -1; } else printf("\nRule Set follows model %i: '%s'", m_nDefaultRuleSetModel, FLC->RSModel().c_str()); printf("\n\nThe logic is always the same:\nCreate Fuzzy Sets (FS), then a Variable Set (VS)"); printf("\nThen attach a Fuzzy Set to each variable"); printf("\nThen create a Rule Set and... that's it: run the FLC!!"); double ArrInput[2]; int nG = 0; cout << "\n\nOutput Grid ? (yes=1) or single calculation (0)"; cin >> nG; if (nG != 1) { ArrInput[0] = 0; cout << "\nInput1 (range [-1;+1]) : "; cin >> ArrInput[0]; ArrInput[1] = 0; cout << "Input2 (range [-1;+1]) : "; cin >> ArrInput[1]; printf("\nInputs:\nVar1:\t%.3f\nVar2:\t%.3f\n\n",ArrInput[0], ArrInput[1]); FLC->Calculate(ArrInput); int OutVarNo = FLC->GetNumVars() - 1; // last var is the output CFuzzySet *vFS = pVars[OutVarNo].FuzzySet(); int NumOutputStates = vFS->NumStates(); for (int i = 0; i < NumOutputStates; i++) printf("Fuzzy Output %i (%s): \t%.3f\n", i+1, vFS->FuzzyStateArray()[i].GetName().c_str(), FLC->OutState(i)); double Output = FLC->Output(); printf("\nDefuzzified Output: %.4f\n", Output); } else { // We will now produce a CSV file pour fuzzy output + 1 for the // defuzzified output. FILE* file[6]; int nNF = (sn == 0) ? 3 : 5; for (int i = 0 ; i < nNF + 1 ; i++) { // files are identified uniquely string str = ".\\flc"; int nd = numdigits(sn); // shape number char* Num = new char[nd+1]; _itoa_s(sn, Num, nd+1, 10); str.append(Num); delete [] Num; str.append("_"); for (int j = 0; j < 3; j++) { nd = numdigits(m_nDefaultFuzzySetModel[j]); Num = new char[nd+1]; _itoa_s(m_nDefaultFuzzySetModel[j], Num, nd+1, 10); str.append(Num); delete [] Num; } nd = numdigits(m_nDefaultRuleSetModel); Num = new char[nd+1]; _itoa_s(m_nDefaultRuleSetModel, Num, nd+1, 10); str.append(Num); delete [] Num; str.append("_"); nd = numdigits(i); Num = new char[nd+1]; _itoa_s(i, Num, nd+1, 10); str.append(Num); delete [] Num; str += ".csv"; errno_t err = fopen_s(&file[i], str.c_str(), "wb"); if (err != 0) { cout << "Error opening output files"; FLC->Reset(); delete FLC; _getch(); return -1; } cout << "\nCreating file: " << str.c_str(); } double dInc = 0.05; cout << "\nGrid increment? (default: 0.05) ? "; cin >> dInc; if (dInc <= 0) dInc = 0.05; if (dInc > 1) dInc = 0.2; string X = "XY,"; for (double x = -1.0; x <= 1.0 + dInc/2; x += dInc) { char xx[10]; sprintf_s(xx,9,"%.3f,",x); X.append( xx ) ; } for (int i = 0; i < nNF + 1; i++) LineToFile(file[i],X); for (double x = -1.0; x <= 1.0 + dInc/2; x += dInc) { char xx[10]; sprintf_s(xx,9,"%2.2f", x ); string str[6]; for (int i = 0; i < nNF + 1; i++) { str[i].assign(xx); str[i].append(","); } for (double y = -1.0; y <= 1.0 +dInc/2; y += dInc) { char val[6][10]; ArrInput[0] = x; ArrInput[1] = y; FLC->Calculate(ArrInput); for (int i = 0 ; i < nNF; i++) { sprintf_s(val[i],8,"%2.4f",FLC->OutState(i)); str[i].append(val[i]); if (y != 1) str[i].append(","); } sprintf_s(val[nNF],8,"%2.4f",FLC->Output() ); str[nNF].append(val[nNF]); if (y != 1) str[nNF].append(","); } for (int i = 0; i < nNF + 1; i++) LineToFile(file[i],str[i]); } for (int i = 0; i < nNF + 1; i++) fclose(file[i]); printf("\nDone!"); } printf("\nPress a key to close"); FLC->Reset(); delete FLC; _getch(); return 0; }