source: cpp/frams/neuro/impl/neuroimpl-fuzzy-f0.cpp @ 1310

Last change on this file since 1310 was 1130, checked in by Maciej Komosinski, 4 years ago

Used std::min(), std::max() explicitly to avoid compiler confusion. Used std::size() explicitly instead of the equivalent macro

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5/// this is a module included into neuroimpl-fuzzy
6/// it converts string parameters - fuzzy sets and fuzzy rules - into appropriate variables
7
8#include "neuroimpl-fuzzy-f0.h"
9#include <algorithm>
10
11//this part concerns fuzzy sets transformation
12
13/** This function converts given string into numbers representing fuzzy sets */
14int FuzzyF0String::convertStrToSets(const SString& str, double numbers[], int nrOfSets)
15{
16        int pos = 0;
17        SString t;
18        int have = 0;
19        int maxnumbers = 4 * nrOfSets; //number of semicolons should be equal 4*nrOfSets
20
21        while (str.getNextToken(pos, t, ';'))
22                if (have >= maxnumbers)
23                        break;
24                else
25                        numbers[have++] = atof(t.c_str());
26
27        //check if number of read numbers (separated with semicolon) is equal to declared
28        if (have != 4 * nrOfSets)
29                return -1; //number of sets found is lower than declared!
30
31        //check corectness of sets - must not be decreasing
32        for (int i = 0; i < nrOfSets; i++)
33                if ((numbers[4 * i] > numbers[4 * i + 1]) || (numbers[4 * i + 1] > numbers[4 * i + 2]) || (numbers[4 * i + 2] > numbers[4 * i + 3]))
34                        return -2; //error
35
36        return 0;
37}
38
39//this part concerns fuzzy rules transformation
40
41/** This function counts number of inputs and outputs given in string consisting fuzzy rules.
42It counts number of separators:
43; between inputs/outputs and fuzzy sets number
44: between conditional and decision part of a rule
45/ end of rule
46*/
47int FuzzyF0String::countInputsOutputs(const char* str, int ruldef[], int rulesNr)
48{ //ruledef will remember counted number of inputs and outputs for every rule
49        const char* t;
50        int separators = 0, inouts = 0;
51
52        for (t = str; *t; t++)
53        {
54                while (isdigit(*t))
55                        t++; //only count, does not care about numbers now
56                if (!*t)
57                        break; //end of the string - get out of 'for' loop
58                if ((*t == ';') || (*t == ':') || (*t == '/')) //found sth different than digit - it must be a separator
59                {
60                        separators++; //one of separators
61                        if (*t != ';') // end of [conditional part of] rule
62                        {
63                                if (inouts >= 2 * rulesNr) //more rules declared in string than declared in rulesNr
64                                        return -2;
65                                ruldef[inouts] = (separators + 1) / 2; //cause fuzzy sets - for 1 in/out there are 2 semicolons
66                                separators = 0;  //begin counting number of in/out from zero
67                                inouts++; //next part of rule / or next rule
68                        }
69                }
70                else // illegal character
71                        return -1;
72        }
73
74        //check, if nr of found rules is equal to declared
75        if (inouts == 2 * rulesNr) //each rule has a conditional part (inputs) and decisional part (outputs)
76                return 0;
77        else
78                return -5; // ShowMessage("Inconsistent number of rules!");
79}
80
81/** This function converts given string into variable 'rules' that remembers all inputs/outputs and fuzzy set.
82The procedure is conduct according to ruledef, calculated earlier.*/
83int FuzzyF0String::convertStrToRules(const SString& str, const int ruledef[], int **rules, int setsNr, int rulesNr, int &maxOutputNr)
84{
85        int pos = 0, j, k, len = str.length();
86        int dNr = 0, sNr = 0;
87        int inNr, outNr; //number of inputs/outputs and corresponding fuzzy sets
88        SString t;
89        bool conditional = true; //which part of rule: conditional or decisional
90
91        maxOutputNr = 0; //sets maximum output nr found in rules string
92
93        //check corectness of the string: number semicolon ... separated with colon or slash
94        while (pos < len)
95        {
96                while ((pos < len) && (isdigit(str.charAt(pos)))) pos++;
97                if (!(pos < len))
98                        break; //end of the string
99                if (str.charAt(pos) != ';')
100                        if ((str.charAt(pos) == ':') && (conditional))
101                        {
102                                sNr++; conditional = false;
103                        }
104                        else if ((str.charAt(pos) == '/') && (!conditional))
105                        {
106                                dNr++; conditional = true;
107                        }
108                        else
109                                return -4; //error - illegal character
110                pos++;
111        }
112        if ((dNr != sNr) || (dNr != rulesNr))
113                return -5; //error - wrong number of rules
114
115        pos = 0;
116
117        for (j = 0; j < rulesNr; j++)
118        { //sum of inputs and outputs
119                inNr = 2 * ruledef[2 * j];
120                outNr = 2 * ruledef[2 * j + 1];
121                for (k = 0; k < inNr + outNr; k++)
122                {
123                        t = ""; //clear previous value
124                        //cuts next integer values
125                        while ((pos < len) && (isdigit(str.charAt(pos))))
126                                t += str.charAt(pos++);
127                        pos++;
128                        rules[j][k] = atol(t.c_str()); //convert cut out string into number
129                        //fuzzy sets - odd index table - are counted from 0,
130                        //so if 5 fuzzy sets declared, values acceptable are 0,1,2,3,4
131                        if (((k % 2) != 0) && (rules[j][k] >= setsNr))
132                                return -1;
133                        if ((k >= inNr) && ((k % 2) == 0))
134                                maxOutputNr = std::max(maxOutputNr, rules[j][k]);
135                }
136        }
137        return 0;
138}
Note: See TracBrowser for help on using the repository browser.