Changeset 791 for cpp/frams/neuro/impl/neuroimpl-fuzzy.cpp
- Timestamp:
- 05/29/18 16:24:39 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/neuro/impl/neuroimpl-fuzzy.cpp
r348 r791 9 9 int NI_FuzzyNeuro::countOuts(const Model *m, const Neuro *fuzzy) 10 10 { 11 int outputs=0;12 for(int i=0;i<m->getNeuroCount();i++)13 for(int in=0;in<m->getNeuro(i)->getInputCount();in++)14 if (m->getNeuro(i)->getInput(in)==fuzzy) outputs++;15 11 int outputs = 0; 12 for (int i = 0; i < m->getNeuroCount(); i++) 13 for (int in = 0; in < m->getNeuro(i)->getInputCount(); in++) 14 if (m->getNeuro(i)->getInput(in) == fuzzy) outputs++; 15 return outputs; 16 16 } 17 17 18 18 int NI_FuzzyNeuro::lateinit() 19 19 { 20 21 22 23 if((fuzzySetsNr<1)||(rulesNr<1)||(fuzzySetString.len()==0)||(fuzzyRulesString.len()==0))24 25 26 27 fuzzySets = new double[4*fuzzySetsNr]; //because every fuzzy set consist of 4 numbers28 29 30 31 32 33 34 35 rulesDef = new int[2*rulesNr]; //for each rule remembers number of inputs and outputs36 37 38 39 40 41 42 for (i=0; i<rulesNr; i++) //...that contains rules body43 44 rules[i] = new int[2*(rulesDef[2*i]+rulesDef[2*i+1])]; //each rule can have different number of inputs and outputs45 46 47 48 49 50 51 52 53 54 55 20 int i, maxOutputNr; 21 22 //check correctness of given parameters: string must not be null, sets&rules number > 0 23 if ((fuzzySetsNr < 1) || (rulesNr < 1) || (fuzzySetString.len() == 0) || (fuzzyRulesString.len() == 0)) 24 return 0; //error 25 26 // this part contains transformation of fuzzy sets 27 fuzzySets = new double[4 * fuzzySetsNr]; //because every fuzzy set consist of 4 numbers 28 // converts fuzzy string from f0 to table of fuzzy numbers type 'double' 29 // (fill created space with numbers taken from string) 30 // also checks whether number of fuzzy sets in the string equals declared in the definition 31 if (FuzzyF0String::convertStrToSets(fuzzySetString, fuzzySets, fuzzySetsNr) != 0) 32 return 0; //error 33 34 // this part contains transformation of fuzzy rules and defuzzyfication parameters 35 rulesDef = new int[2 * rulesNr]; //for each rule remembers number of inputs and outputs 36 //check correctness of string and fill in the rulesDef 37 if (FuzzyF0String::countInputsOutputs(fuzzyRulesString.c_str(), rulesDef, rulesNr) == 0) 38 { 39 defuzzParam = new double[rulesNr]; // parameters used in defuzyfication process 40 // create space for rules according to rulesDef 41 rules = new int*[rulesNr]; //list of rules... 42 for (i = 0; i < rulesNr; i++) //...that contains rules body 43 { 44 rules[i] = new int[2 * (rulesDef[2 * i] + rulesDef[2 * i + 1])]; //each rule can have different number of inputs and outputs 45 defuzzParam[i] = 0; //should be done a little bit earlier, but why do not use this loop? 46 } 47 // fill created space with numbers taken from string 48 if (FuzzyF0String::convertStrToRules(fuzzyRulesString, rulesDef, rules, fuzzySetsNr, rulesNr, maxOutputNr) != 0) 49 return 0; //error 50 } 51 else 52 return 0; //error 53 54 setChannelCount(countOuts(neuro->owner, neuro)); 55 return 1; //success 56 56 } 57 57 58 58 NI_FuzzyNeuro::~NI_FuzzyNeuro() 59 59 { 60 if(rules) //delete rows and columns of **rules61 62 for (int i=0; i<rulesNr; i++) SAFEDELETEARRAY(rules[i])63 64 65 66 67 60 if (rules) //delete rows and columns of **rules 61 { 62 for (int i = 0; i < rulesNr; i++) SAFEDELETEARRAY(rules[i]) 63 SAFEDELETEARRAY(rules) 64 } 65 SAFEDELETEARRAY(defuzzParam) 66 SAFEDELETEARRAY(rulesDef) 67 SAFEDELETEARRAY(fuzzySets) 68 68 } 69 69 70 70 int NI_FuzzyNeuro::GetFuzzySetParam(int set_nr, double &left, double &midleft, double &midright, double &right) 71 71 { 72 if ( (set_nr>=0) && (set_nr<fuzzySetsNr))73 74 left = fuzzySets[4*set_nr];75 midleft = fuzzySets[4*set_nr+1];76 midright = fuzzySets[4*set_nr+2];77 right = fuzzySets[4*set_nr+3];78 79 80 81 72 if ((set_nr >= 0) && (set_nr < fuzzySetsNr)) 73 { 74 left = fuzzySets[4 * set_nr]; 75 midleft = fuzzySets[4 * set_nr + 1]; 76 midright = fuzzySets[4 * set_nr + 2]; 77 right = fuzzySets[4 * set_nr + 3]; 78 return 0; 79 } 80 else 81 return 1; 82 82 } 83 83 … … 85 85 void NI_FuzzyNeuro::go() 86 86 { 87 if (Fuzzyfication()!=0)88 89 if (Defuzzyfication()!=0)90 87 if (Fuzzyfication() != 0) 88 return; 89 if (Defuzzyfication() != 0) 90 return; 91 91 } 92 92 … … 97 97 int NI_FuzzyNeuro::Fuzzyfication() 98 98 { 99 100 101 102 103 for (i=0; i<rulesNr; i++)104 105 nrIn = rulesDef[2*i]; // nr of inputs in rule #i106 107 for (j=0; (j<nrIn)&&(minimumCut>0); j++) //minimumCut can not be <0, so if =0 then stop calculations108 109 nrFuzzySet = rules[i][j*2 + 1]; // j*2 moves pointer through each output, +1 moves to nr of fuzzy set110 inputNr = rules[i][j*2]; // as above but gives input number111 minimumCut = min(minimumCut, TrapeziumFuzz(nrFuzzySet, getWeightedInputState(inputNr))); // value of membership function for this input and given fuzzy set112 113 if ( (minimumCut>1) || (minimumCut<0))114 115 116 117 99 int i, j, nrIn, inputNr, nrFuzzySet; 100 double minimumCut; // actual minimal level of cut (= min. membership function) 101 102 // sets defuzzyfication parameters for each rule: 103 for (i = 0; i < rulesNr; i++) 104 { 105 nrIn = rulesDef[2 * i]; // nr of inputs in rule #i 106 minimumCut = 2; // the highest value of membership function is 1.0, so this value will definitely change 107 for (j = 0; (j < nrIn) && (minimumCut>0); j++) //minimumCut can not be <0, so if =0 then stop calculations 108 { 109 nrFuzzySet = rules[i][j * 2 + 1]; // j*2 moves pointer through each output, +1 moves to nr of fuzzy set 110 inputNr = rules[i][j * 2]; // as above but gives input number 111 minimumCut = min(minimumCut, TrapeziumFuzz(nrFuzzySet, getWeightedInputState(inputNr))); // value of membership function for this input and given fuzzy set 112 } 113 if ((minimumCut>1) || (minimumCut < 0)) 114 return 1; 115 defuzzParam[i] = minimumCut; 116 } 117 return 0; 118 118 } 119 119 … … 127 127 double NI_FuzzyNeuro::TrapeziumFuzz(int which_fuzzy_set, double input_val) 128 128 { 129 double range=0, left=0, midleft=0, midright=0, right=0;130 131 if ( (which_fuzzy_set < 0) || (which_fuzzy_set > fuzzySetsNr))132 133 if ( (input_val < -1) || (input_val > 1))134 135 136 137 138 139 if ( (input_val < left) || (input_val > right)) // greather than right value140 141 else if ( (input_val >= midleft) && (input_val <= midright)) // in the core of fuzzy set142 143 else if ( (input_val >= left) && (input_val < midleft)) // at the left side of trapezium144 145 146 return fabs(input_val-left)/((range>0)?range:1); // quotient of distance between input and extreme left point of trapezium and range of rising side, or 1147 148 else if ( (input_val > midright) && (input_val <= right)) // at the right side of trapezium149 150 151 return fabs(right-input_val)/((range>0)?range:1); // quotient of distance between input and extreme right point of trapezium and range of falling side, or 1152 153 154 155 129 double range = 0, left = 0, midleft = 0, midright = 0, right = 0; 130 131 if ((which_fuzzy_set < 0) || (which_fuzzy_set > fuzzySetsNr)) 132 return -2; 133 if ((input_val < -1) || (input_val > 1)) 134 return -3; 135 136 if (GetFuzzySetParam(which_fuzzy_set, left, midleft, midright, right) != 0) 137 return -4; 138 139 if ((input_val < left) || (input_val > right)) // greather than right value 140 return 0; 141 else if ((input_val >= midleft) && (input_val <= midright)) // in the core of fuzzy set 142 return 1; 143 else if ((input_val >= left) && (input_val < midleft)) // at the left side of trapezium 144 { 145 range = fabs(midleft - left); 146 return fabs(input_val - left) / ((range > 0) ? range : 1); // quotient of distance between input and extreme left point of trapezium and range of rising side, or 1 147 } 148 else if ((input_val > midright) && (input_val <= right)) // at the right side of trapezium 149 { 150 range = fabs(right - midright); 151 return fabs(right - input_val) / ((range > 0) ? range : 1); // quotient of distance between input and extreme right point of trapezium and range of falling side, or 1 152 }; 153 154 // should not occur 155 return 0; 156 156 157 157 } … … 165 165 int NI_FuzzyNeuro::Defuzzyfication() 166 166 { 167 int i, j, nrIn, nrOut, out, set, outputsNr; 168 double *numerators, *denominators, midleft, midright, unimp; 169 170 outputsNr = getChannelCount(); 171 172 numerators = new double[outputsNr]; 173 denominators = new double[outputsNr]; 174 175 for(i=0;i<outputsNr;i++) numerators[i] = denominators[i] = 0; 176 177 // for each rule... 178 for (i=0; i<rulesNr; i++) 179 { 180 nrIn = rulesDef[2*i]; // number of inputs in rule #i 181 nrOut = rulesDef[2*i + 1]; // number of outputs in rule #i 182 // ...calculate each output's product of middle fuzzy set value and minimum membership function (numerator) and sum of minimum membership function (denominator) 183 for (j=0; j<nrOut; j++) 184 { 185 out = rules[i][2*nrIn + 2*j]; //number of j-output 186 set = rules[i][2*nrIn + 2*j + 1]; //number of fuzzy set attributed to j-output 187 if (GetFuzzySetParam(set, unimp, midleft, midright, unimp) != 0) // gets range of core of given fuzzy set 188 { SAFEDELETEARRAY(denominators) SAFEDELETEARRAY(numerators) return 1; } 189 //defuzzParam[i] = minimum membership function for rule #i - calculated in fuzzyfication block 190 // defuzzyfication method of singletons (high): (fuzzy set modal value) * (minimum membership value) 191 numerators[out] += ((midleft + midright)/2.0) * defuzzParam[i]; 192 denominators[out] += defuzzParam[i]; 193 } 194 } 195 196 for (i=0; i<outputsNr; i++) 197 { 198 if (denominators[i] == 0) 199 setState(0, i); 200 else 201 setState(numerators[i]/denominators[i], i); 202 } 203 204 SAFEDELETEARRAY(denominators) 205 SAFEDELETEARRAY(numerators) 206 207 return 0; 208 } 209 167 int i, j, nrIn, nrOut, out, set, outputsNr; 168 double *numerators, *denominators, midleft, midright, unimp; 169 170 outputsNr = getChannelCount(); 171 172 numerators = new double[outputsNr]; 173 denominators = new double[outputsNr]; 174 175 for (i = 0; i < outputsNr; i++) numerators[i] = denominators[i] = 0; 176 177 // for each rule... 178 for (i = 0; i < rulesNr; i++) 179 { 180 nrIn = rulesDef[2 * i]; // number of inputs in rule #i 181 nrOut = rulesDef[2 * i + 1]; // number of outputs in rule #i 182 // ...calculate each output's product of middle fuzzy set value and minimum membership function (numerator) and sum of minimum membership function (denominator) 183 for (j = 0; j < nrOut; j++) 184 { 185 out = rules[i][2 * nrIn + 2 * j]; //number of j-output 186 set = rules[i][2 * nrIn + 2 * j + 1]; //number of fuzzy set attributed to j-output 187 if (GetFuzzySetParam(set, unimp, midleft, midright, unimp) != 0) // gets range of core of given fuzzy set 188 { 189 SAFEDELETEARRAY(denominators) SAFEDELETEARRAY(numerators) return 1; 190 } 191 //defuzzParam[i] = minimum membership function for rule #i - calculated in fuzzyfication block 192 // defuzzyfication method of singletons (high): (fuzzy set modal value) * (minimum membership value) 193 numerators[out] += ((midleft + midright) / 2.0) * defuzzParam[i]; 194 denominators[out] += defuzzParam[i]; 195 } 196 } 197 198 for (i = 0; i < outputsNr; i++) 199 { 200 if (denominators[i] == 0) 201 setState(0, i); 202 else 203 setState(numerators[i] / denominators[i], i); 204 } 205 206 SAFEDELETEARRAY(denominators) 207 SAFEDELETEARRAY(numerators) 208 209 return 0; 210 }
Note: See TracChangeset
for help on using the changeset viewer.