README.md
1fuzzylite 6.0 ®
2=================
3<img src="https://raw.githubusercontent.com/fuzzylite/fuzzylite/release/fuzzylite.png" align="right" alt="fuzzylite">
4
5
6A Fuzzy Logic Control Library in C++
7------------------------------------
8
9By: [Juan Rada-Vilela](http://www.fuzzylite.com/jcrada), Ph.D.
10
11Released: 20/March/2017
12
13[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0)
14[![Build Status](https://travis-ci.org/fuzzylite/fuzzylite.svg?branch=release)](https://travis-ci.org/fuzzylite/fuzzylite)
15[![Build status](https://ci.appveyor.com/api/projects/status/065g596yxdhkt2se/branch/release)](https://ci.appveyor.com/project/jcrada/fuzzylite/branch/release)
16[![Coverity Status](https://scan.coverity.com/projects/5759/badge.svg)](https://scan.coverity.com/projects/5759)
17
18
19***
20
21
22### Table of Contents
23[License](#license) <br/>
24[Introduction](#introduction)<br/>
25[Features](#features)<br/>
26[Example](#example) <br/>
27[Compile, Link, and Execute](#compile-build-execute)<br/>
28[Bulding from Source](#building)<br/>
29[Binaries](#binaries) <br/>
30[What's new](#whatsnew)<br/>
31[What's next](#whatsnext) <br/>
32
33
34
35
36***
37
38### <a name="license">License</a>
39`fuzzylite 6.0` is licensed under the [**GNU General Public License (GPL) 3.0**](https://www.gnu.org/licenses/gpl.html). You are **strongly** encouraged to support the development of the FuzzyLite Libraries by purchasing a license of [`QtFuzzyLite 6`](http://www.fuzzylite.com/downloads).
40
41[`QtFuzzyLite 6`](http://www.fuzzylite.com/downloads/) is the new and (very likely) the best graphical user interface available to easily design and directly operate fuzzy logic controllers in real time. Available for Windows, Mac, and Linux, its goal is to significantly **speed up** the design of your fuzzy logic controllers, while providing a very **useful**, **functional** and **beautiful** user interface.
42Please, download it and check it out for free at [www.fuzzylite.com/downloads/](http://www.fuzzylite.com/downloads/).
43
44***
45
46
47### <a name="introduction">Introduction</a>
48
49
50`fuzzylite` is a free and open-source fuzzy logic control library programmed in C++ for multiple platforms (e.g., Windows, Linux, Mac, iOS). [`jfuzzylite`](https://github.com/fuzzylite/jfuzzylite/) is the equivalent library for Java and Android platforms. Together, they are the FuzzyLite Libraries for Fuzzy Logic Control.
51
52<center>
53```
54The goal of the FuzzyLite Libraries is to easily design and efficiently operate fuzzy logic controllers following an object-oriented programming model without relying on external libraries.
55```
56</center>
57
58#### Reference
59If you are using the FuzzyLite Libraries, please cite the following reference in your article:
60
61Juan Rada-Vilela. fuzzylite: a fuzzy logic control library, 2017. URL http://www.fuzzylite.com/.
62
63```bibtex
64 @misc{fl::fuzzylite,
65 author={Juan Rada-Vilela},
66 title={fuzzylite: a fuzzy logic control library},
67 url={http://www.fuzzylite.com/},
68 year={2017}}
69```
70
71#### Documentation
72The documentation for the `fuzzylite` library is available at: [www.fuzzylite.com/documentation/](http://www.fuzzylite.com/documentation/).
73
74***
75
76### <a name="features">Features</a>
77
78**(6) Controllers**: Mamdani, Takagi-Sugeno, Larsen, Tsukamoto, Inverse Tsukamoto, Hybrids
79
80**(21) Linguistic terms**: (4) *Basic*: triangle, trapezoid, rectangle, discrete.
81(9) *Extended*: bell, cosine, gaussian, gaussian product, pi-shape, sigmoid difference, sigmoid product, spike.
82(5) *Edges*: binary, concave, ramp, sigmoid, s-shape, z-shape.
83(3) *Functions*: constant, linear, function.
84
85**(7) Activation methods**: general, proportional, threshold, first, last, lowest, highest.
86
87**(8) Conjunction and Implication (T-Norms)**: minimum, algebraic product, bounded difference, drastic product, einstein product, hamacher product, nilpotent minimum, function.
88
89**(10) Disjunction and Aggregation (S-Norms)**: maximum, algebraic sum, bounded sum, drastic sum, einstein sum, hamacher sum, nilpotent maximum, normalized sum, unbounded sum, function.
90
91**(7) Defuzzifiers**: (5) *Integral*: centroid, bisector, smallest of maximum, largest of maximum, mean of maximum.
92(2) *Weighted*: weighted average, weighted sum.
93
94**(7) Hedges**: any, not, extremely, seldom, somewhat, very, function.
95
96**(3) Importers**: FuzzyLite Language `fll`, Fuzzy Inference System `fis`, Fuzzy Control Language `fcl`.
97
98**(7) Exporters**: `C++`, `Java`, FuzzyLite Language `fll`, FuzzyLite Dataset `fld`, `R` script, Fuzzy Inference System `fis`, Fuzzy Control Language `fcl`.
99
100**(30+) Examples** of Mamdani, Takagi-Sugeno, Tsukamoto, and Hybrid controllers from `fuzzylite`, Octave, and Matlab, each included in the following formats: `C++`, `Java`, `fll`, `fld`, `R`, `fis`, and `fcl`.
101
102
103
104
105***
106
107### <a name="example">Example</a>
108#### FuzzyLite Language
109```yaml
110#File: ObstacleAvoidance.fll
111Engine: ObstacleAvoidance
112InputVariable: obstacle
113 enabled: true
114 range: 0.000 1.000
115 lock-range: false
116 term: left Ramp 1.000 0.000
117 term: right Ramp 0.000 1.000
118OutputVariable: mSteer
119 enabled: true
120 range: 0.000 1.000
121 lock-range: false
122 aggregation: Maximum
123 defuzzifier: Centroid 100
124 default: nan
125 lock-previous: false
126 term: left Ramp 1.000 0.000
127 term: right Ramp 0.000 1.000
128RuleBlock: mamdani
129 enabled: true
130 conjunction: none
131 disjunction: none
132 implication: AlgebraicProduct
133 activation: General
134 rule: if obstacle is left then mSteer is right
135 rule: if obstacle is right then mSteer is left
136```
137```cpp
138//File: ObstacleAvoidance.cpp
139#include "fl/Headers.h"
140
141int main(int argc, char* argv[]){
142 using namespace fl;
143 Engine* engine = FllImporter().fromFile("ObstacleAvoidance.fll");
144
145 std::string status;
146 if (not engine->isReady(&status))
147 throw Exception("[engine error] engine is not ready:\n" + status, FL_AT);
148
149 InputVariable* obstacle = engine->getInputVariable("obstacle");
150 OutputVariable* steer = engine->getOutputVariable("mSteer");
151
152 for (int i = 0; i <= 50; ++i){
153 scalar location = obstacle->getMinimum() + i * (obstacle->range() / 50);
154 obstacle->setValue(location);
155 engine->process();
156 FL_LOG("obstacle.input = " << Op::str(location) <<
157 " => " << "steer.output = " << Op::str(steer->getValue()));
158 }
159}
160```
161
162#### C++
163```cpp
164//File: ObstacleAvoidance.cpp
165#include "fl/Headers.h"
166
167int main(int argc, char* argv[]){
168 using namespace fl;
169 //Code automatically generated with fuzzylite 6.0.
170
171 using namespace fl;
172
173 Engine* engine = new Engine;
174 engine->setName("ObstacleAvoidance");
175 engine->setDescription("");
176
177 InputVariable* obstacle = new InputVariable;
178 obstacle->setName("obstacle");
179 obstacle->setDescription("");
180 obstacle->setEnabled(true);
181 obstacle->setRange(0.000, 1.000);
182 obstacle->setLockValueInRange(false);
183 obstacle->addTerm(new Ramp("left", 1.000, 0.000));
184 obstacle->addTerm(new Ramp("right", 0.000, 1.000));
185 engine->addInputVariable(obstacle);
186
187 OutputVariable* mSteer = new OutputVariable;
188 mSteer->setName("mSteer");
189 mSteer->setDescription("");
190 mSteer->setEnabled(true);
191 mSteer->setRange(0.000, 1.000);
192 mSteer->setLockValueInRange(false);
193 mSteer->setAggregation(new Maximum);
194 mSteer->setDefuzzifier(new Centroid(100));
195 mSteer->setDefaultValue(fl::nan);
196 mSteer->setLockPreviousValue(false);
197 mSteer->addTerm(new Ramp("left", 1.000, 0.000));
198 mSteer->addTerm(new Ramp("right", 0.000, 1.000));
199 engine->addOutputVariable(mSteer);
200
201 RuleBlock* mamdani = new RuleBlock;
202 mamdani->setName("mamdani");
203 mamdani->setDescription("");
204 mamdani->setEnabled(true);
205 mamdani->setConjunction(fl::null);
206 mamdani->setDisjunction(fl::null);
207 mamdani->setImplication(new AlgebraicProduct);
208 mamdani->setActivation(new General);
209 mamdani->addRule(Rule::parse("if obstacle is left then mSteer is right", engine));
210 mamdani->addRule(Rule::parse("if obstacle is right then mSteer is left", engine));
211 engine->addRuleBlock(mamdani);
212
213 std::string status;
214 if (not engine->isReady(&status))
215 throw Exception("[engine error] engine is not ready:\n" + status, FL_AT);
216
217 for (int i = 0; i <= 50; ++i){
218 scalar location = obstacle->getMinimum() + i * (obstacle->range() / 50);
219 obstacle->setValue(location);
220 engine->process();
221 FL_LOG("obstacle.input = " << Op::str(location) <<
222 " => " << "steer.output = " << Op::str(steer->getValue()));
223 }
224}
225```
226
227### <a name="compile-build-execute">Compile, Link, and Execute</a>
228
229Once you have an engine written in C++, you can compile it to create an executable file which links to the `fuzzylite` library. The linking can be either static or dynamic. Basically, the differences between static and dynamic linking are the following. **Static linking** includes the `fuzzylite` library into your executable file, hence increasing its size, but the executable no longer needs to have access to the `fuzzylite` library files. **Dynamic linking** does not include the `fuzzylite` library into your executable file, hence reducing its size, but the executable needs to have access to the `fuzzylite` shared library file. When using dynamic linking, make sure that the shared library files are either in the same directory as the executable, or are reachable via environmental variables:
230
231```posh
232rem Windows:
233set PATH="\path\to\fuzzylite\release\bin;%PATH%"
234```
235```bash
236#Unix:
237export LD_LIBRARY_PATH="/path/to/fuzzylite/release/bin/:$LD_LIBRARY_PATH"
238```
239
240#### Windows
241The commands to compile your engine in Windows are the following:
242
243C++11 (default)
244```posh
245rem static linking:
246cl.exe ObstacleAvoidance.cpp fuzzylite-static.lib /Ipath/to/fuzzylite /EHsc /MD
247```
248```posh
249rem dynamic linking:
250cl.exe ObstacleAvoidance.cpp fuzzylite.lib /Ipath/to/fuzzylite /DFL_IMPORT_LIBRARY /EHsc /MD
251```
252
253C++98
254```posh
255rem static linking:
256cl.exe ObstacleAvoidance.cpp fuzzylite-static.lib /Ipath/to/fuzzylite /DFL_CPP98=ON /EHsc /MD
257```
258```posh
259rem dynamic linking:
260cl.exe ObstacleAvoidance.cpp fuzzylite.lib /Ipath/to/fuzzylite /DFL_IMPORT_LIBRARY /DFL_CPP98=ON /EHsc /MD
261```
262
263#### Unix
264The commands to compile your engine in Unix are the following:
265
266C++11 (default)
267```bash
268#static linking
269g++ ObstacleAvoidance.cpp -o ObstacleAvoidance -I/path/to/fuzzylite -L/path/to/fuzzylite/release/bin -lfuzzylite-static --std=c++11
270```
271```bash
272#dynamic linking
273g++ ObstacleAvoidance.cpp -o ObstacleAvoidance -I/path/to/fuzzylite -L/path/to/fuzzylite/release/bin -lfuzzylite -Wno-non-literal-null-conversion
274```
275
276C++98
277```bash
278#static linking
279g++ ObstacleAvoidance.cpp -o ObstacleAvoidance -I/path/to/fuzzylite -L/path/to/fuzzylite/release/bin -lfuzzylite-static -DFL_CPP98=ON
280```
281```bash
282#dynamic linking
283g++ ObstacleAvoidance.cpp -o ObstacleAvoidance -I/path/to/fuzzylite -L/path/to/fuzzylite/release/bin -lfuzzylite -DFL_CPP98=ON -Wno-non-literal-null-conversion
284```
285
286#### CMake
287Alternatively, you can use CMake to build your project linking to `fuzzylite`. Please, refer to the example application available at [examples/application]([/examples/application]).
288
289
290
291***
292
293
294### <a name="building">Building from Source</a>
295You can build the `fuzzylite` library from source using `CMake` [(cmake.org)](https://cmake.org/).
296
297The files [`fuzzylite/build.bat`](/fuzzylite/build.bat) and [`fuzzylite/build.sh`](/fuzzylite/build.sh) are build scripts for the Windows and Unix platforms, respectively.
298After building from source, the resulting binaries will be located in the sub-folders `fuzzylite/release/bin` and `fuzzylite/debug/bin`. The usage of these scripts is presented as follows.
299
300#### Windows
301```bash
302> build.bat help
303Usage: build.bat [options]
304where [options] can be any of the following:
305 all builds fuzzylite in debug and release mode (default)
306 debug builds fuzzylite in debug mode
307 release builds fuzzylite in release mode
308 clean erases previous builds
309 help shows this information
310```
311
312#### Unix
313```bash
314$ ./build.sh help
315Usage: [bash] ./build.sh [options]
316where [options] can be any of the following:
317 all builds fuzzylite in debug and release mode (default)
318 debug builds fuzzylite in debug mode
319 release builds fuzzylite in release mode
320 clean erases previous builds
321 help shows this information
322```
323
324
325
326#### Building Options
327For advanced building options, please check the contents of [`fuzzylite/build.bat`](/fuzzylite/build.bat) or [`fuzzylite/build.sh`](/fuzzylite/build.sh), and the contents of [`fuzzylite/CMakeLists.txt`](/fuzzylite/CMakeLists.txt).
328
329The following building options available:
330
331* `-DFL_USE_FLOAT=ON` builds the binaries utilizing the `fl::scalar` data type as a `float` represented in 4 bytes. By default, the binaries are built utilizing `-DFL_USE_FLOAT=OFF` to utilize `fl::scalar` as a `double` represented in 8 bytes and hence providing better accuracy. If `fuzzylite` is built with `-DFL_USE_FLOAT=ON`, then the applications linking to `fuzzylite` also need to specify this compilation flag.
332
333
334* `-DFL_CPP98=ON` builds binaries utilizing `C++98` features. By default, `fuzzylite` is built with `-DFL_CPP98=OFF` to utilize `C++11` features. If compiling for `C++98`, be aware that you will not be able to benchmark the performance of your engine using the `Benchmark` class.
335
336
337* `-DFL_BACKTRACE=OFF` disables the backtrace information in case of errors (default is ON). In Windows, the backtrace information requires the external library `dbghelp`, which is generally available in your system.
338
339* `-DCMAKE_BUILD_TYPE=[Debug|Release]` sets the mode of your build. You can only build one mode at a time with a single CMake script.
340
341
342#### Documentation
343The source code of `fuzzylite` is very well documented using [`doxygen`](www.doxygen.org/) formatting, and the documentation is available at [fuzzylite.com/documentation](http://fuzzylite.com/documentation). If you want to generate the documentation locally, you can produce the `html` documentation from the file [Doxyfile](/Doxyfile) using the command line: `doxygen Doxyfile`. The documentation will be created in the [`documentation`](/documentation) folder.
344
345
346
347***
348
349### <a name="binaries">Binaries</a>
350
351After building from source, the following are the relevant binaries that will be created in `Release` mode. In `Debug` mode, the file names end with `-debug` (e.g., `fuzzylite-debug.exe`).
352
353#### Windows
354
355- console application: `fuzzylite.exe`
356- shared library: `fuzzylite.dll`, `fuzzylite.lib`
357- static library: `fuzzylite-static.lib`
358
359#### Linux
360
361- console application: `fuzzylite`
362- shared library: `libfuzzylite.so`
363- static library: `libfuzzylite-static.a`
364
365#### Mac
366
367- console application: `fuzzylite`
368- shared library: `libfuzzylite.dylib`
369- static library: `libfuzzylite-static.a`
370
371
372#### Console
373The console application of `fuzzylite` allows you to import and export your engines. Its usage can be obtained executing the console binary. In addition, the console can be set in interactive mode. The `FuzzyLite Interactive Console` allows you to evaluate a given controller by manually providing the input values. The interactive console is triggered by specifying an input file and an output format. For example, to interact with the `ObstacleAvoidance` controller, the interactive console is launched as follows:
374
375```bash
376fuzzylite -i ObstacleAvoidance.fll -of fld
377```
378
379
380
381***
382
383### <a name="whatsnew">What's New?</a>
384* The FuzzyLite Libraries, namely fuzzylite and jfuzzylite, both in version 6.0, are dual licensed under the GNU General Public License version 3 and the Apache License version 2.
385
386* By default, fuzzylite builds using C++11 instead of C++98.
387
388* Important performance improvements.
389
390* Refactored the following names for the operation of engines: from activation operator to implication operator, from accumulation operator to aggregation operator.
391
392* Renamed the term `Accumulated` to `Aggregated`.
393
394* New activation methods decouple the activation of rules from the rule block and provide different methods for activating rules (see Activation Methods).
395
396* New class `ActivationFactory` provides a factory of activation methods.
397
398* New class `Benchmark` to evaluate the performance and accuracy of engines.
399
400* New class `Complexity` to estimate the computational complexity of an engine.
401
402* New class `RScriptExporter` to export the surfaces of an engine using the `ggplot2` library.
403
404* New class `Binary` term for binary edges.
405
406* New `UnboundedSum` S-Norm in `SNormFactory`.
407
408* New classes `SNormFunction` and `TNormFunction` to create custom functions on any two values using the `Function` class.
409
410* Added description strings to `Engine`, `Variable` and `RuleBlock`
411
412* Privatized previously protected members of classes and subclasses of `Term`, `Variable`, `Rule`, `Defuzzifier`, `[Cloning|Construction]Factory`, `Importer`, `Exporter`, amongst others.
413
414* Improved portability by replacing `int` for `std::size_t` where necessary, thereby additionally removing warnings in Windows 64bit
415
416* Deleted `Operation.cpp` and inlined its methods into `Operation.h`
417
418* Updated `.travis.yml` to use Docker, and build using g++ (versions 6, 5, 4.9, 4.8, 4.7) and clang (versions 3.8, 3.7, 3.6, and 3.5).
419
420* Added `appveyor.yml` to use continuous integration in Windows under Visual Studio 2013 and 2015.
421
422* Added some unit tests and support for future unit tests.
423
424* Bug fixes.
425
426* New example of hybrid engines.
427
428* New example on obstacle avoidance for Mamdani, Takagi-Sugeno, and Hybrid engines.
429
430* New R scripts for each example and its respective surfaces in `pdf` formats.
431
432#### Bug fixes
433* Fixed bug in `CloningFactory::deregisterObject()`. Bug: Object was deleted before removing it from the map, leaving an invalid object in the map which would cause a segmentation fault. Solution: Remove the object from the map before deleting it.
434* Fixed bug causing segmentation fault when malformed term in FuzzyLite Language
435* Fixed bug computing the `NormalizedSum` S-Norm.
436* Fixed bug in `RuleBlock` to reset and clone the implication operator. Bug: implication operator is not copied and reset. Fix: copy and reset implication operator when cloning the `RuleBlock`.
437* Fixed bug in `Function` term. Bug: given a formula = "tan(y)" and a map["y"] = 1.0, and executing `Function::load(formula)`, then the map of variables is reset because `load()` calls `unload()` first, causing the deregistration of variable `y`. Solution: Removed method `unload()` from `load()`, thereby causing future `load()` not to reset variables.
438* Fixed bug in `Function` when enclosing variable in double parenthesis.
439
440
441***
442
443### <a name="whatsnext">What's Next?</a>
444
445+ Optimization of Fuzzy Logic Controllers
446+ Type-2 Fuzzy Logic Controllers
447+ Adaptive Neuro-Fuzzy Inference System (ANFIS)
448+ Fuzzy C-means data clustering
449
450***
451
452fuzzylite® is a registered trademark of FuzzyLite Limited.<br>
453jfuzzylite™ is a trademark of FuzzyLite Limited.<br>
454QtFuzzyLite™ is a trademark of FuzzyLite Limited.<br>
455
456
457Copyright © 2010-2017 FuzzyLite Limited. All rights reserved.
458