Skip to content

Commit

Permalink
added new functionality to set constant variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Simone Spolaor committed Dec 15, 2020
1 parent 8d9768b commit ccf2142
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 11 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
setup(
name = 'simpful',
packages = ['simpful'], # this must be the same as the name above
version = '2.3.6',
version = '2.4.0',
description = 'A user-friendly Python library for fuzzy logic',
author = 'Marco S. Nobile',
author_email = 'm.s.nobile@tue.nl',
Expand Down
71 changes: 61 additions & 10 deletions simpful/simpful.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ class FuzzySystem(object):
Creates a new fuzzy system.
Args:
operators: a list of strings, specifying fuzzy operators to be used instead of defaults.
Currently supported operators: 'AND_PRODUCT'.
operators: a list of strings, specifying fuzzy operators to be used instead of defaults. Currently supported operators: 'AND_PRODUCT'.
show_banner: True/False, toggles display of banner.
sanitize_input: sanitize variables' names to eliminate non-accepted characters (under development).
verbose: True/False, toggles verbose mode.
"""

Expand All @@ -202,7 +202,9 @@ def __init__(self, operators=None, show_banner=True, sanitize_input=False, verbo
self._crispvalues = {}
self._outputfunctions = {}
self._outputfuzzysets = {}
if show_banner: self._banner()

self._constants = []

self._operators = operators

self._detected_type = None
Expand All @@ -211,6 +213,8 @@ def __init__(self, operators=None, show_banner=True, sanitize_input=False, verbo
if sanitize_input and verbose:
print (" * Warning: Simpful rules sanitization is enabled, please pay attention to possible collisions of symbols.")

if show_banner: self._banner()

def _banner(self):
import pkg_resources
vrs = pkg_resources.get_distribution('simpful').version
Expand Down Expand Up @@ -241,6 +245,23 @@ def set_variable(self, name, value, verbose=False):
except ValueError:
raise Exception("ERROR: specified value for "+name+" is not an integer or float: "+value)

def set_constant(self, name, value, verbose=False):
"""
Sets the numerical value of a linguistic variable to a constant value (i.e. ignore fuzzy inference).
Args:
name: name of the linguistic variables to be set to a constant value.
value: numerical value to be set.
verbose: True/False, toggles verbose mode.
"""
if self._sanitize_input: name = self._sanitize(name)
try:
value = float(value)
self._variables[name] = value
self._constants.append(name)
if verbose: print(" * Variable %s set to a constant value %f" % (name, value))
except ValueError:
raise Exception("ERROR: specified value for "+name+" is not an integer or float: "+value)

def add_rules_from_file(self, path, verbose=False):
"""
Expand Down Expand Up @@ -487,15 +508,26 @@ def Sugeno_inference(self, terms=None, ignore_errors=False, verbose=False):
Returns:
a dictionary, containing as keys the variables' names and as values their numerical inferred values.
"""
# default: inference on ALL rules/terms
if self._sanitize and terms is not None:
terms = [self._sanitize(term) for term in terms]

# default: inference on ALL rules/terms
if terms == None:
temp = [rule[1][0] for rule in self._rules]
terms= list(set(temp))

array_rules = array(self._rules, dtype='object')
result = self.mediate(terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors)
if len(self._constants)==0:
result = self.mediate(terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors)
else:
#remove constant variables from list of variables to infer
ncost_terms = [t for t in terms if t not in self._constants]
result = self.mediate(ncost_terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors)
#add values of constant variables
cost_terms = [t for t in terms if t in self._constants]
for name in cost_terms:
result[name] = self._variables[name]

return result


Expand All @@ -512,22 +544,33 @@ def Mamdani_inference(self, terms=None, ignore_errors=False, verbose=False, subd
Returns:
a dictionary, containing as keys the variables' names and as values their numerical inferred values.
"""

# default: inference on ALL rules/terms
if self._sanitize and terms is not None:
terms = [self._sanitize(term) for term in terms]

# default: inference on ALL rules/terms
if terms == None:
temp = [rule[1][0] for rule in self._rules]
terms= list(set(temp))

array_rules = array(self._rules, dtype=object)
result = self.mediate_Mamdani( terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors, verbose=verbose , subdivisions=subdivisions)
if len(self._constants)==0:
result = self.mediate_Mamdani(terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors, verbose=verbose , subdivisions=subdivisions)
else:
#remove constant variables from list of variables to infer
ncost_terms = [t for t in terms if t not in self._constants]
result = self.mediate_Mamdani(ncost_terms, array_rules.T[0], array_rules.T[1], ignore_errors=ignore_errors, verbose=verbose , subdivisions=subdivisions)
#add values of constant variables
cost_terms = [t for t in terms if t in self._constants]
for name in cost_terms:
result[name] = self._variables[name]

return result


def probabilistic_inference(self, terms=None, ignore_errors=False, verbose=False):
raise NotImplementedError()


def inference(self, terms=None, ignore_errors=False, verbose=False, subdivisions=1000):
"""
Performs the fuzzy inference, trying to automatically choose the correct inference engine.
Expand All @@ -551,7 +594,6 @@ def inference(self, terms=None, ignore_errors=False, verbose=False, subdivisions
raise Exception("ERROR: simpful could not detect the model type, please use either Sugeno_inference() or Mamdani_inference() methods.")



def produce_figure(self, outputfile='output.pdf'):
"""
Plots the membership functions of each linguistic variable contained in the fuzzy system.
Expand Down Expand Up @@ -593,7 +635,16 @@ def produce_figure(self, outputfile='output.pdf'):


def aggregate(self, list_variables, function):
# TEST
"""
Performs a fuzzy aggregation of linguistic variables contained in a FuzzySystem object.
Args:
list_variables: list of linguistic variables names in the FuzzySystem object to aggregate.
function: pointer to an aggregation function. The function must accept as an argument a list of membership values.
Returns:
the aggregated membership values.
"""
memberships = []
for variable, fuzzyset in list_variables.items():
value = self._variables[variable]
Expand Down

0 comments on commit ccf2142

Please sign in to comment.