Beispiel #1
0
class Adjective(object):
    """Describes a ... of a variable.
    
    @ivar set: fuzzy set
    @type set: L{fuzzy.set.Set.Set}
    @ivar COM: norm (if None the class default _COM is used.)
    @type COM: L{fuzzy.norm.Norm.Norm}
    @ivar membership: set or calculated membership
    @type membership: float
    @cvar _COM: class default is instance variable is None
    @type _COM: L{fuzzy.norm.Norm.Norm}
    """

    # default if not set in instance
    _COM = Max()

    def __init__(self, set=Set(), COM=None):
        """Initialize adjective.
        
        @param set: fuzzy set
        @type set: L{fuzzy.set.Set.Set}
        @param COM: norm (if None the class default _COM is used.)
        @type COM: L{fuzzy.norm.Norm.Norm}
        """
        self.set = set
        self.membership = None
        self.COM = COM

    def setMembershipForValue(self, value):
        """Get membership for an input value from the fuzzy set."""
        self.membership = self.set(value)

    def getMembership(self):
        """Return membership set in this adjective."""
        if self.membership is None:
            return 0.0
        else:
            return self.membership

    def setMembership(self, value):
        """Set membership of this adjective as result 
           of a rule calculation, 
           if already set use COM norm to merge
           old and new value."""

        if self.membership is None:
            self.membership = value
        else:
            self.membership = (self.COM or self._COM)(
                self.membership,  # consider already set value
                value)

    def reset(self):
        """Reset membership to unknown value (None)."""
        self.membership = None

    def getName(self, system):
        """Find own name in given system.
        Returns a tuple (var_name,adj_name) of None."""
        return system.findAdjectiveName(self)
Beispiel #2
0
def _createSystem():
    import fuzzy.System
    system = fuzzy.System.System(
        description=
        """This fuzzy system is to control the inverted pendulum into an upright position as well as
at the position X=0.

It also is used to demonstrate some features of pyfuzzy.
This is the reason, it uses different fuzzy norm in normally
symmetrical rules.""")

    from fuzzy.norm.AlgebraicProduct import AlgebraicProduct
    from fuzzy.norm.AlgebraicSum import AlgebraicSum
    from fuzzy.fuzzify.Plain import Plain
    from fuzzy.defuzzify.COG import COG
    # set defuzzification method and default norms
    INF = AlgebraicProduct()
    ACC = AlgebraicSum()
    COM = AlgebraicSum()
    CER = AlgebraicProduct()
    COG = COG(INF=INF, ACC=ACC, failsafe=0., segment_size=0.5)

    from fuzzy.InputVariable import InputVariable
    from fuzzy.OutputVariable import OutputVariable
    from fuzzy.Adjective import Adjective
    from fuzzy.set.Polygon import Polygon

    angle = InputVariable(fuzzify=Plain(),
                          description='angle',
                          min=0.,
                          max=360.,
                          unit='degrees')
    system.variables['Phi'] = angle
    angle.adjectives['up_more_right'] = Adjective(
        Polygon([(0., 0.), (30., 1.), (60., 0.)]))
    angle.adjectives['up_right'] = Adjective(
        Polygon([(30., 0.), (60., 1.), (90., 0.)]))
    angle.adjectives['up'] = Adjective(
        Polygon([(60., 0.), (90., 1.), (120., 0.)]))
    angle.adjectives['up_left'] = Adjective(
        Polygon([(90., 0.), (120., 1.), (150., 0.)]))
    angle.adjectives['up_more_left'] = Adjective(
        Polygon([(120., 0.), (150., 1.), (180., 0.)]))
    angle.adjectives['down_more_left'] = Adjective(
        Polygon([(180., 0.), (210., 1.), (240., 0.)]))
    angle.adjectives['down_left'] = Adjective(
        Polygon([(210., 0.), (240., 1.), (270., 0.)]))
    angle.adjectives['down'] = Adjective(
        Polygon([(240., 0.), (270., 1.), (300., 0.)]))
    angle.adjectives['down_right'] = Adjective(
        Polygon([(270., 0.), (300., 1.), (330., 0.)]))
    angle.adjectives['down_more_right'] = Adjective(
        Polygon([(300., 0.), (330., 1.), (360., 0.)]))

    angle_velocity = InputVariable(fuzzify=Plain(),
                                   description='angle velocity',
                                   min=-600.,
                                   max=600.,
                                   unit='degrees per second')
    system.variables['dPhi_dT'] = angle_velocity
    angle_velocity.adjectives['cw_fast'] = Adjective(
        Polygon([(-600., 1.), (-300., 0.)]))
    angle_velocity.adjectives['cw_slow'] = Adjective(
        Polygon([(-600., 0.), (-300., 1.), (0., 0.)]))
    angle_velocity.adjectives['stop'] = Adjective(
        Polygon([(-300., 0.), (0., 1.), (300., 0.)]))
    angle_velocity.adjectives['ccw_slow'] = Adjective(
        Polygon([(0., 0.), (300., 1.), (600., 0.)]))
    angle_velocity.adjectives['ccw_fast'] = Adjective(
        Polygon([(300., 0.), (600., 1.)]))

    position = InputVariable(fuzzify=Plain(),
                             description='position',
                             min=-20.,
                             max=20.,
                             unit='meter')
    system.variables['X'] = position
    position.adjectives['left_far'] = Adjective(
        Polygon([(-20., 1.), (-10., 0.)]))
    position.adjectives['left_near'] = Adjective(
        Polygon([(-20., 0.), (-5., 1.), (0., 0.)]))
    position.adjectives['stop'] = Adjective(
        Polygon([(-5., 0.), (0., 1.), (5., 0.)]))
    position.adjectives['right_near'] = Adjective(
        Polygon([(0., 0.), (5., 1.), (20., 0.)]))
    position.adjectives['right_far'] = Adjective(
        Polygon([(10., 0.), (20., 1.)]))

    velocity = InputVariable(fuzzify=Plain(),
                             description='velocity',
                             min=-10.,
                             max=10.,
                             unit='meter per second')
    system.variables['dX_dT'] = velocity
    velocity.adjectives['left_fast'] = Adjective(
        Polygon([(-10., 1.), (-5., 0.)]))
    velocity.adjectives['left_slow'] = Adjective(
        Polygon([(-10., 0.), (-2., 1.), (0., 0.)]))
    velocity.adjectives['stop'] = Adjective(
        Polygon([(-2., 0.), (0., 1.), (2., 0.)]))
    velocity.adjectives['right_slow'] = Adjective(
        Polygon([(0., 0.), (2., 1.), (10., 0.)]))
    velocity.adjectives['right_fast'] = Adjective(
        Polygon([(5., 0.), (10., 1.)]))

    acceleration = OutputVariable(defuzzify=COG,
                                  description='acceleration',
                                  min=-50.,
                                  max=50.,
                                  unit='meter per second^2')
    system.variables['a'] = acceleration
    acceleration.adjectives['left_fast'] = a_left_fast = Adjective(Polygon([
        (-50., 0.), (-20., 1.), (-10., 0.)
    ]),
                                                                   COM=COM)
    acceleration.adjectives['left_slow'] = a_left_slow = Adjective(Polygon([
        (-20., 0.), (-10., 1.), (0., 0.)
    ]),
                                                                   COM=COM)
    acceleration.adjectives['stop'] = a_stop = Adjective(Polygon([(-10., 0.),
                                                                  (0., 1.),
                                                                  (10., 0.)]),
                                                         COM=COM)
    acceleration.adjectives['right_slow'] = a_right_slow = Adjective(Polygon([
        (0., 0.), (10., 1.), (20., 0.)
    ]),
                                                                     COM=COM)
    acceleration.adjectives['right_fast'] = a_right_fast = Adjective(Polygon([
        (10., 0.), (20., 1.), (50., 0.)
    ]),
                                                                     COM=COM)

    from fuzzy.Rule import Rule
    from fuzzy.norm.Max import Max
    #from fuzzy.norm.Min import Min
    #from fuzzy.norm.BoundedDifference import BoundedDifference
    #from fuzzy.norm.DrasticSum import DrasticSum
    from fuzzy.norm.EinsteinSum import EinsteinSum
    from fuzzy.norm.DombiUnion import DombiUnion
    from fuzzy.operator.Compound import Compound
    from fuzzy.operator.Input import Input
    from fuzzy.operator.Not import Not

    system.rules['stop'] = Rule(
        adjective=a_stop,
        # it gets its value from here
        operator=Compound(
            Max(),
            Compound(AlgebraicProduct(),
                     Input(system.variables["Phi"].adjectives["up"]),
                     Input(system.variables["dPhi_dT"].adjectives["stop"])),
            Compound(AlgebraicProduct(),
                     Input(system.variables["Phi"].adjectives["up_right"]),
                     Input(
                         system.variables["dPhi_dT"].adjectives["ccw_slow"])),
            Compound(AlgebraicProduct(),
                     Input(system.variables["Phi"].adjectives["up_left"]),
                     Input(
                         system.variables["dPhi_dT"].adjectives["cw_slow"]))),
        CER=CER)

    system.rules['tilts right'] = Rule(
        adjective=a_right_slow,
        # it gets its value from here
        operator=Compound(
            AlgebraicProduct(),
            Not(
                Compound(
                    AlgebraicProduct(),
                    Compound(
                        AlgebraicSum(),
                        Input(system.variables["X"].adjectives["left_near"]),
                        Input(system.variables["X"].adjectives["left_far"])),
                    Compound(
                        EinsteinSum(),
                        Input(
                            system.variables["dX_dT"].adjectives["left_slow"]),
                        Input(system.variables["dX_dT"].adjectives["left_fast"]
                              ))), ),
            Input(system.variables["Phi"].adjectives["up_right"])),
        CER=CER)

    system.rules['tilts left'] = Rule(
        adjective=a_left_slow,
        # it gets its value from here
        operator=Compound(
            AlgebraicProduct(),
            Not(
                Compound(
                    AlgebraicProduct(),
                    Compound(
                        AlgebraicSum(),
                        Input(system.variables["X"].adjectives["right_near"]),
                        Input(system.variables["X"].adjectives["right_far"])),
                    Compound(
                        DombiUnion(0.25),
                        Input(system.variables["dX_dT"].
                              adjectives["right_slow"]),
                        Input(system.variables["dX_dT"].
                              adjectives["right_fast"]))), ),
            Input(system.variables["Phi"].adjectives["up_left"])),
        CER=CER)

    system.rules['far right'] = Rule(
        adjective=a_right_fast,
        # it gets its value from here
        operator=Input(system.variables["Phi"].adjectives["up_more_right"]),
        CER=CER)

    system.rules['far left'] = Rule(
        adjective=a_left_fast,
        # it gets its value from here
        operator=Input(system.variables["Phi"].adjectives["up_more_left"]),
        CER=CER)

    system.rules['accelerate cw if down'] = Rule(
        adjective=a_right_slow,
        # it gets its value from here
        operator=Compound(
            AlgebraicProduct(),
            Input(system.variables["Phi"].adjectives["down"]),
            Compound(
                AlgebraicProduct(),
                Input(system.variables["dPhi_dT"].adjectives["cw_slow"]),
                Input(system.variables["dPhi_dT"].adjectives["cw_slow"]),
            )),
        CER=CER)

    system.rules['accelerate ccw if down'] = Rule(
        adjective=a_left_slow,
        # it gets its value from here
        operator=Compound(
            AlgebraicProduct(),
            Input(system.variables["Phi"].adjectives["down"]),
            Compound(
                AlgebraicProduct(),
                Input(system.variables["dPhi_dT"].adjectives["ccw_slow"]),
                Input(system.variables["dPhi_dT"].adjectives["ccw_slow"]),
            )),
        CER=CER)

    return system
Beispiel #3
0
class Base(object):
    """Abstract base class for defuzzification
       which results in a numeric value.
       
        @ivar INF: inference norm, used with set of adjective and given value for it
        @type INF: L{fuzzy.norm.Norm.Norm}
        @ivar ACC: norm for accumulation of set of adjectives
        @type ACC: L{fuzzy.norm.Norm.Norm}
        @cvar _INF: default value when INF is None
        @type _INF: L{fuzzy.norm.Norm.Norm}
        @cvar _ACC: default value when ACC is None
        @type _ACC: L{fuzzy.norm.Norm.Norm}
        @ivar activated_sets: results of activation of adjectives of variable.
        @type activated_sets: {string:L{fuzzy.set.Polygon.Polygon}}
        @ivar accumulated_set: result of accumulation of activated sets
        @type accumulated_set: L{fuzzy.set.Polygon.Polygon}
       """

    # default values if instance values are not set
    _INF = Min()
    _ACC = Max()

    def __init__(self, INF=None, ACC=None):
        """
        @param INF: inference norm, used with set of adjective and given value for it
        @type INF: L{fuzzy.norm.Norm.Norm}
        @param ACC: norm for accumulation of set of adjectives
        @type ACC: L{fuzzy.norm.Norm.Norm}
        """
        self.ACC = ACC  # accumulation
        self.INF = INF  # inference
        self.activated_sets = {}
        self.accumulated_set = None

    def getValue(self, variable):
        """Defuzzyfication."""
        raise DefuzzificationException("don't use the abstract base class")

# helper methods for sub classes

    def accumulate(self, variable, segment_size=None):
        """combining adjective values into one set"""
        self.activated_sets = {}
        temp = None
        for name, adjective in variable.adjectives.items():
            # get precomputed adjective set
            temp2 = norm((self.INF or self._INF), adjective.set,
                         adjective.getMembership(), segment_size)
            self.activated_sets[name] = temp2
            # accumulate all adjectives
            if temp is None:
                temp = temp2
            else:
                temp = merge((self.ACC or self._ACC), temp, temp2,
                             segment_size)
        self.accumulated_set = temp
        return temp

    def value_table(self, set):
        """get a value table of the polygon representation"""
        # get polygon representation
        ig = set.getIntervalGenerator()
        next = ig.nextInterval(None, None)
        while next is not None:
            x = next
            y = set(x)
            yield (x, y)
            # get next point from polygon
            next = ig.nextInterval(next, None)
Beispiel #4
0
class Base(object):
    """Abstract base class for defuzzification
       which results in a numeric value.
       
        @ivar INF: inference norm, used with set of adjective and given value for it
        @type INF: L{fuzzy.norm.Norm.Norm}
        @ivar ACC: norm for accumulation of set of adjectives
        @type ACC: L{fuzzy.norm.Norm.Norm}
        @cvar _INF: default value when INF is None
        @type _INF: L{fuzzy.norm.Norm.Norm}
        @cvar _ACC: default value when ACC is None
        @type _ACC: L{fuzzy.norm.Norm.Norm}
        @ivar activated_sets: results of activation of adjectives of variable.
        @type activated_sets: {string:L{fuzzy.set.Polygon.Polygon}}
        @ivar accumulated_set: result of accumulation of activated sets
        @type accumulated_set: L{fuzzy.set.Polygon.Polygon}
       """

    # default values if instance values are not set 
    _INF = Min()
    _ACC = Max()

    def __init__(self, INF=None, ACC=None):
        """
        @param INF: inference norm, used with set of adjective and given value for it
        @type INF: L{fuzzy.norm.Norm.Norm}
        @param ACC: norm for accumulation of set of adjectives
        @type ACC: L{fuzzy.norm.Norm.Norm}
        """
        self.ACC = ACC # accumulation
        self.INF = INF # inference
        self.activated_sets = {}
        self.accumulated_set = None

    def getValue(self, variable):
        """Defuzzification."""
        raise NotImplementedError("don't use the abstract base class")

# helper methods for sub classes

    def accumulate(self, variable, segment_size=None):
        """combining adjective values into one set"""
        self.activated_sets = {}
        temp = None
        for name, adjective in variable.adjectives.items():
            # get precomputed adjective set
            temp2 = norm((self.INF or self._INF), adjective.set, adjective.getMembership(), segment_size)
            self.activated_sets[name] = temp2
            # accumulate all adjectives
            if temp is None:
                temp = temp2
            else:
                temp = merge((self.ACC or self._ACC), temp, temp2, segment_size)
        self.accumulated_set = temp
        return temp

    def value_table(self, set):
        """get a value table of the polygon representation"""
        # get polygon representation
        return set.getValuesXY()
    
    def __repr__(self):
        """Return representation of instance.
                   
           @return: representation of instance
           @rtype: string
           """
        params = []
        self._repr_params(params)
        return "%s.%s(%s)" % (self.__class__.__module__, self.__class__.__name__, ", ".join(params))

    def _repr_params(self, params):
        """Helper for representation of instance.
        
        Add all own params to given list in params.    
        """
        if self.INF: params.append("INF=%s" % repr(self.INF)) 
        if self.ACC: params.append("ACC=%s" % repr(self.ACC))