/* Author: Juan Rada-Vilela, Ph.D. Copyright (C) 2010-2014 FuzzyLite Limited All rights reserved This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. fuzzylite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with fuzzylite. If not, see . fuzzyliteâ„¢ is a trademark of FuzzyLite Limited. */ #include "fl/term/Accumulated.h" #include "fl/imex/FllExporter.h" #include "fl/norm/SNorm.h" #include "fl/norm/s/Maximum.h" #include "fl/term/Activated.h" namespace fl { Accumulated::Accumulated(const std::string& name, scalar minimum, scalar maximum, SNorm* accumulation) : Term(name), _minimum(minimum), _maximum(maximum), _accumulation(accumulation) { } Accumulated::Accumulated(const Accumulated& other) : Term(other) { copyFrom(other); } Accumulated& Accumulated::operator=(const Accumulated& other) { if (this != &other) { clear(); _accumulation.reset(fl::null); Term::operator=(other); copyFrom(other); } return *this; } Accumulated::~Accumulated() { clear(); } void Accumulated::copyFrom(const Accumulated& source) { _minimum = source._minimum; _maximum = source._maximum; if (source._accumulation.get()) _accumulation.reset(source._accumulation->clone()); for (std::size_t i = 0; i < source._terms.size(); ++i) { _terms.push_back(source._terms.at(i)->clone()); } } std::string Accumulated::className() const { return "Accumulated"; } scalar Accumulated::membership(scalar x) const { if (fl::Op::isNaN(x)) return fl::nan; if (not (_terms.empty() or _accumulation.get())) { //Exception for IntegralDefuzzifiers throw fl::Exception("[accumulation error] " "accumulation operator needed to accumulate " + toString(), FL_AT); } scalar mu = 0.0; for (std::size_t i = 0; i < _terms.size(); ++i) { mu = _accumulation->compute(mu, _terms.at(i)->membership(x)); } return mu; } scalar Accumulated::activationDegree(const Term* forTerm) const { scalar result = 0.0; for (std::size_t i = 0; i < _terms.size(); ++i) { Activated* activatedTerm = _terms.at(i); if (activatedTerm->getTerm() == forTerm) { if (_accumulation.get()) result = _accumulation->compute(result, activatedTerm->getDegree()); else result += activatedTerm->getDegree(); //Default for WeightDefuzzifier } } return result; } std::string Accumulated::parameters() const { FllExporter exporter; std::ostringstream ss; ss << exporter.toString(_accumulation.get()); ss << " " << Op::str(_minimum) << " " << Op::str(_maximum) << " "; for (std::size_t i = 0; i < _terms.size(); ++i) { ss << " " << exporter.toString(_terms.at(i)); } return ss.str(); } void Accumulated::configure(const std::string& parameters) { (void) parameters; } Accumulated* Accumulated::clone() const { return new Accumulated(*this); } std::string Accumulated::toString() const { std::vector accumulate; for (std::size_t i = 0; i < _terms.size(); ++i) { accumulate.push_back(_terms.at(i)->toString()); } FllExporter exporter; std::ostringstream ss; ss << _name << ": " << className() << " " << exporter.toString(_accumulation.get()) << "[" << fl::Op::join(accumulate, ",") << "]"; return ss.str(); } void Accumulated::setMinimum(scalar minimum) { this->_minimum = minimum; } scalar Accumulated::getMinimum() const { return this->_minimum; } void Accumulated::setMaximum(scalar maximum) { this->_maximum = maximum; } scalar Accumulated::getMaximum() const { return this->_maximum; } void Accumulated::setRange(scalar minimum, scalar maximum) { setMinimum(minimum); setMaximum(maximum); } scalar Accumulated::range() const { return this->_maximum - this->_minimum; } void Accumulated::setAccumulation(SNorm* accumulation) { this->_accumulation.reset(accumulation); } SNorm* Accumulated::getAccumulation() const { return this->_accumulation.get(); } /** * Operations for std::vector _terms */ void Accumulated::addTerm(const Term* term, scalar degree, const TNorm* activation) { this->_terms.push_back(new Activated(term, degree, activation)); } void Accumulated::addTerm(Activated* term) { this->_terms.push_back(term); } Activated* Accumulated::removeTerm(int index) { Activated* term = this->_terms.at(index); this->_terms.erase(this->_terms.begin() + index); return term; } void Accumulated::clear() { for (std::size_t i = 0; i < _terms.size(); ++i) { delete _terms.at(i); } _terms.clear(); } Activated* Accumulated::getTerm(int index) const { return this->_terms.at(index); } const std::vector& Accumulated::terms() const { return this->_terms; } std::vector& Accumulated::terms() { return this->_terms; } int Accumulated::numberOfTerms() const { return _terms.size(); } bool Accumulated::isEmpty() const { return _terms.empty(); } }