1 /* 2 fuzzylite (R), a fuzzy logic control library in C++. 3 Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. 4 Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> 5 6 This file is part of fuzzylite. 7 8 fuzzylite is free software: you can redistribute it and/or modify it under 9 the terms of the FuzzyLite License included with the software. 10 11 You should have received a copy of the FuzzyLite License along with 12 fuzzylite. If not, see <http://www.fuzzylite.com/license/>. 13 14 fuzzylite is a registered trademark of FuzzyLite Limited. 15 */ 16 17 #include "fl/Complexity.h" 18 19 #include "fl/Engine.h" 20 21 #include "fl/variable/InputVariable.h" 22 #include "fl/variable/OutputVariable.h" 23 24 #include "fl/rule/RuleBlock.h" 25 #include "fl/rule/Rule.h" 26 27 namespace fl { 28 Complexity(scalar all)29 Complexity::Complexity(scalar all) : 30 _comparison(all), _arithmetic(all), _function(all) { } 31 Complexity(scalar comparison,scalar arithmetic,scalar function)32 Complexity::Complexity(scalar comparison, scalar arithmetic, 33 scalar function) 34 : _comparison(comparison), _arithmetic(arithmetic), _function(function) { } 35 ~Complexity()36 Complexity::~Complexity() { } 37 operator +=(const Complexity & other)38 Complexity& Complexity::operator+=(const Complexity& other) { 39 return this->plus(other); 40 } 41 operator -=(const Complexity & other)42 Complexity& Complexity::operator-=(const Complexity& other) { 43 return this->minus(other); 44 } 45 operator *=(const Complexity & other)46 Complexity& Complexity::operator*=(const Complexity& other) { 47 return this->multiply(other); 48 } 49 operator /=(const Complexity & other)50 Complexity& Complexity::operator/=(const Complexity& other) { 51 return this->divide(other); 52 } 53 operator +(const Complexity & rhs) const54 Complexity Complexity::operator+(const Complexity& rhs) const { 55 return Complexity(*this).plus(rhs); 56 } 57 operator -(const Complexity & rhs) const58 Complexity Complexity::operator-(const Complexity& rhs) const { 59 return Complexity(*this).minus(rhs); 60 } 61 operator *(const Complexity & rhs) const62 Complexity Complexity::operator*(const Complexity& rhs) const { 63 return Complexity(*this).multiply(rhs); 64 } 65 operator /(const Complexity & rhs) const66 Complexity Complexity::operator/(const Complexity& rhs) const { 67 return Complexity(*this).divide(rhs); 68 } 69 operator ==(const Complexity & rhs) const70 bool Complexity::operator==(const Complexity& rhs) const { 71 return equals(rhs); 72 } 73 operator !=(const Complexity & rhs) const74 bool Complexity::operator!=(const Complexity& rhs) const { 75 return not equals(rhs); 76 } 77 operator <(const Complexity & rhs) const78 bool Complexity::operator<(const Complexity& rhs) const { 79 return lessThan(rhs); 80 } 81 operator <=(const Complexity & rhs) const82 bool Complexity::operator<=(const Complexity& rhs) const { 83 return lessThanOrEqualsTo(rhs); 84 } 85 operator >(const Complexity & rhs) const86 bool Complexity::operator>(const Complexity& rhs) const { 87 return greaterThan(rhs); 88 } 89 operator >=(const Complexity & rhs) const90 bool Complexity::operator>=(const Complexity& rhs) const { 91 return greaterThanOrEqualsTo(rhs); 92 } 93 plus(const Complexity & other)94 Complexity& Complexity::plus(const Complexity& other) { 95 this->_arithmetic += other._arithmetic; 96 this->_comparison += other._comparison; 97 this->_function += other._function; 98 return *this; 99 } 100 plus(scalar x)101 Complexity& Complexity::plus(scalar x) { 102 return this->plus(Complexity().arithmetic(x).comparison(x).function(x)); 103 } 104 minus(const Complexity & other)105 Complexity& Complexity::minus(const Complexity& other) { 106 this->_comparison -= other._comparison; 107 this->_arithmetic -= other._arithmetic; 108 this->_function -= other._function; 109 return *this; 110 } 111 minus(scalar x)112 Complexity& Complexity::minus(scalar x) { 113 return this->minus(Complexity().arithmetic(x).comparison(x).function(x)); 114 } 115 multiply(const Complexity & other)116 Complexity& Complexity::multiply(const Complexity& other) { 117 this->_comparison *= other._comparison; 118 this->_arithmetic *= other._arithmetic; 119 this->_function *= other._function; 120 return *this; 121 } 122 multiply(scalar x)123 Complexity& Complexity::multiply(scalar x) { 124 return this->multiply(Complexity().arithmetic(x).comparison(x).function(x)); 125 } 126 divide(const Complexity & other)127 Complexity& Complexity::divide(const Complexity& other) { 128 this->_comparison /= other._comparison; 129 this->_arithmetic /= other._arithmetic; 130 this->_function /= other._function; 131 return *this; 132 } 133 divide(scalar x)134 Complexity& Complexity::divide(scalar x) { 135 return this->divide(Complexity().arithmetic(x).comparison(x).function(x)); 136 } 137 equals(const Complexity & x,scalar macheps) const138 bool Complexity::equals(const Complexity& x, scalar macheps) const { 139 return Op::isEq(_comparison, x._comparison, macheps) and 140 Op::isEq(_arithmetic, x._arithmetic, macheps) and 141 Op::isEq(_function, x._function, macheps); 142 } 143 lessThan(const Complexity & x,scalar macheps) const144 bool Complexity::lessThan(const Complexity& x, scalar macheps) const { 145 return Op::isLt(_comparison, x._comparison, macheps) and 146 Op::isLt(_arithmetic, x._arithmetic, macheps) and 147 Op::isLt(_function, x._function, macheps); 148 } 149 lessThanOrEqualsTo(const Complexity & x,scalar macheps) const150 bool Complexity::lessThanOrEqualsTo(const Complexity& x, scalar macheps) const { 151 return Op::isLE(_comparison, x._comparison, macheps) and 152 Op::isLE(_arithmetic, x._arithmetic, macheps) and 153 Op::isLE(_function, x._function, macheps); 154 } 155 greaterThan(const Complexity & x,scalar macheps) const156 bool Complexity::greaterThan(const Complexity& x, scalar macheps) const { 157 return Op::isGt(_comparison, x._comparison, macheps) and 158 Op::isGt(_arithmetic, x._arithmetic, macheps) and 159 Op::isGt(_function, x._function, macheps); 160 } 161 greaterThanOrEqualsTo(const Complexity & x,scalar macheps) const162 bool Complexity::greaterThanOrEqualsTo(const Complexity& x, scalar macheps) const { 163 return Op::isGE(_comparison, x._comparison, macheps) and 164 Op::isGE(_arithmetic, x._arithmetic, macheps) and 165 Op::isGE(_function, x._function, macheps); 166 } 167 comparison(scalar comparison)168 Complexity& Complexity::comparison(scalar comparison) { 169 this->_comparison += comparison; 170 return *this; 171 } 172 setComparison(scalar comparison)173 void Complexity::setComparison(scalar comparison) { 174 this->_comparison = comparison; 175 } 176 getComparison() const177 scalar Complexity::getComparison() const { 178 return _comparison; 179 } 180 arithmetic(scalar arithmetic)181 Complexity& Complexity::arithmetic(scalar arithmetic) { 182 this->_arithmetic += arithmetic; 183 return *this; 184 } 185 setArithmetic(scalar arithmetic)186 void Complexity::setArithmetic(scalar arithmetic) { 187 this->_arithmetic = arithmetic; 188 } 189 getArithmetic() const190 scalar Complexity::getArithmetic() const { 191 return _arithmetic; 192 } 193 function(scalar trigonometric)194 Complexity& Complexity::function(scalar trigonometric) { 195 this->_function += trigonometric; 196 return *this; 197 } 198 setFunction(scalar trigonometric)199 void Complexity::setFunction(scalar trigonometric) { 200 this->_function = trigonometric; 201 } 202 getFunction() const203 scalar Complexity::getFunction() const { 204 return _function; 205 } 206 measures() const207 std::vector<Complexity::Measure> Complexity::measures() const { 208 std::vector<Measure> result; 209 result.push_back(Measure("arithmetic", _arithmetic)); 210 result.push_back(Measure("comparison", _comparison)); 211 result.push_back(Measure("function", _function)); 212 return result; 213 } 214 sum() const215 scalar Complexity::sum() const { 216 return _arithmetic + _comparison + _function; 217 } 218 norm() const219 scalar Complexity::norm() const { 220 return std::sqrt(Complexity(*this).multiply(*this).sum()); 221 } 222 toString() const223 std::string Complexity::toString() const { 224 std::vector<std::string> result; 225 result.push_back("a=" + Op::str(_arithmetic)); 226 result.push_back("c=" + Op::str(_comparison)); 227 result.push_back("f=" + Op::str(_function)); 228 return "C[" + Op::join(result, ", ") + "]"; 229 } 230 compute(const Engine * engine) const231 Complexity Complexity::compute(const Engine* engine) const { 232 return engine->complexity(); 233 } 234 compute(const InputVariable * inputVariable) const235 Complexity Complexity::compute(const InputVariable* inputVariable) const { 236 return inputVariable->complexity(); 237 } 238 compute(const OutputVariable * outputVariable) const239 Complexity Complexity::compute(const OutputVariable* outputVariable) const { 240 return outputVariable->complexity(); 241 } 242 compute(const RuleBlock * ruleBlock) const243 Complexity Complexity::compute(const RuleBlock* ruleBlock) const { 244 return ruleBlock->complexity(); 245 } 246 compute(const std::vector<InputVariable * > & inputVariables) const247 Complexity Complexity::compute(const std::vector<InputVariable*>& inputVariables) const { 248 Complexity result; 249 for (std::size_t i = 0; i < inputVariables.size(); ++i) { 250 result += inputVariables.at(i)->complexity(); 251 } 252 return result; 253 } 254 compute(const std::vector<OutputVariable * > & outputVariables,bool complexityOfDefuzzification) const255 Complexity Complexity::compute(const std::vector<OutputVariable*>& outputVariables, 256 bool complexityOfDefuzzification) const { 257 Complexity result; 258 for (std::size_t i = 0; i < outputVariables.size(); ++i) { 259 if (complexityOfDefuzzification) 260 result += outputVariables.at(i)->complexityOfDefuzzification(); 261 else 262 result += outputVariables.at(i)->complexity(); 263 } 264 return result; 265 } 266 compute(const std::vector<Variable * > & variables) const267 Complexity Complexity::compute(const std::vector<Variable*>& variables) const { 268 Complexity result; 269 for (std::size_t i = 0; i < variables.size(); ++i) { 270 result += variables.at(i)->complexity(); 271 } 272 return result; 273 } 274 compute(const std::vector<RuleBlock * > & ruleBlocks) const275 Complexity Complexity::compute(const std::vector<RuleBlock*>& ruleBlocks) const { 276 Complexity result; 277 for (std::size_t i = 0; i < ruleBlocks.size(); ++i) { 278 result += ruleBlocks.at(i)->complexity(); 279 } 280 return result; 281 } 282 283 } 284