AI-Fuzzy

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

	- fixed warning messages due to not checking "exists" for hash 
	  values in Set.pm (union,intersection).  Thanks to Richard Jelinek
	  for pointing this out, and a problem in the code in the docs.
	
0.04 Fri Dec  6 13:49:55 EST 2002
        - replaced current AI::Fuzzy::Label with a new AI::Fuzzy::Axis (a container for label objects)
          and changed AI::Fuzzy::Label to be concerned only about label data.  This
          will allow us to add new AI::Fuzzy::Label{Spline, Trapezoid, etc.} subclasses
          of labels to the now independent Axis class.  Axis will defer to the Label
          itself to decide applicability, >,<,>=,<=, and the like.
        - changed test.pl to work with the new setup
        - added functions: greaterthan, greaterequal, lessthan, lessequal, and between
          to AI::Fuzzy::Label
        - added overriding of >,>=,<,<=, and <=> in AI::Fuzzy::Label.

0.03 Wed Oct  9 18:07:34 EDT 2002
	- added functions: support, core, height, is_normal, is_subnormal
	  to AI::Fuzzy::Set

0.02 Wed Oct  9 16:41:29 EDT 2002
	- ownership transfering to Tom Scanlan <tscanlan@openreach.com>

Fuzzy.pm  view on Meta::CPAN

  $c = $a->intersection($b);
  print "a intersection b is: " . $c->as_string . "\n"; 

__END__

=head1 DESCRIPTION

AI::Fuzzy really consists of three modules - AI::Fuzzy::Axis, AI::Fuzzy::Label, and
AI::Fuzzy::Set.  

A fuzzy set is simply a mathematical set to which members can
I<partially> belong. For example, a particular shade of gray may
partially belong to the set of dark colors, whereas black would have
full membership, and lemon yellow would have almost no membership.

A fuzzy axis holds fuzzy labels and can be used to classify values
by examining the degree to which they belong to several labels, and 
selecting the most appropriate.  For example, it can decide whether 
to call water at 60 degrees Farenheight "cold", "cool", or "warm". 

A fuzzy label classifies a particular range of the Axis. In the above example 
the label is one of "cold", "cool", or "warm". A fuzzy label defines how
much a crisp value belongs to the classifier such as "cold", "warm", or "cool". 

Fuzzy.pm  view on Meta::CPAN

   
    # $x will be .86
    $x = B<membership> $fs_tall_people, "Max";

    # get list of members, sorted from least membership to greatest:
    @shortest_first = B<members> $fs_tall_people;

    $fs = B<new> AI::Fuzzy::Set( x1 => .3, x2 => .5, x3 => .8, x4 => 0, x5 => 1);

    B<complement>, B<union>, B<intersection>
    Thesie are the fuzzy set version of the typical functions.
   
    B<equal>
    Returns true if the sets have the same elements and those elements
    are all equal.

   B<as_string>
   Prints the set as tuples:
	$b = new AI::Fuzzy::Set( x5 => .3, x6 => .5, x7 => .8, x8 => 0, x9 => 1);
	print "b is: " . $b->as_string . "\n"; 
    prints:
	b is: x8/0, x5/0.3, x6/0.5, x7/0.8, x9/1

=head2 Fuzzy Labels

A Fuzzy::Label label has four attributes: the text of the label (it
can be any scalar, really), and three numbers: low, mid, high if you
imagine a cartesian plane (remember graph paper in algebra?)  of all

README  view on Meta::CPAN

  
      $c = $a->intersection($b);
      print "a intersection b is: " . $c->as_string . "\n"; 

    __END__

DESCRIPTION
    AI::Fuzzy really consists of two modules - AI::Fuzzy::Label and
    AI::Fuzzy::Set.

    A fuzzy set is simply a mathematical set to which members can
    *partially* belong. For example, a particular shade of gray may
    partially belong to the set of dark colors, whereas black would have
    full membership, and lemon yellow would have almost no membership.

    A fuzzy labeler classifies a particular crisp value by examining the
    degree to which it belongs to several sets, and selecting the most
    appropriate. For example, it can decide whether to call water at 60
    degrees Farenheight "cold", "cool", or "warm". A fuzzy label might be
    one of these labels, or a fuzzy set describing to what degree each of
    the labels describes the particular value in question.

  Fuzzy Sets

    AI::Fuzzy:Set has these methods:

        $fs = B<new> AI::Fuzzy::Set;

        # here, "Bob" is unquestionably tall.. the others less so.
        $fs_tall_people = B<new> AI::Fuzzy::Set( Lester=>.34, Bob=>1.00, Max=>.86 );
   
        # $x will be .86
        $x = B<membership> $fs_tall_people, "Max";

        # get list of members, sorted from least membership to greatest:
        @shortest_first = B<members> $fs_tall_people;

        $fs = B<new> AI::Fuzzy::Set( x1 => .3, x2 => .5, x3 => .8, x4 => 0, x5 => 1);

        B<complement>, B<union>, B<intersection>
        Thesie are the fuzzy set version of the typical functions.
   
        B<equal>
        Returns true if the sets have the same elements and those elements
        are all equal.

       B<as_string>
       Prints the set as tuples:
            $b = new AI::Fuzzy::Set( x5 => .3, x6 => .5, x7 => .8, x8 => 0, x9 => 1);
            print "b is: " . $b->as_string . "\n"; 
        prints:
            b is: x8/0, x5/0.3, x6/0.5, x7/0.8, x9/1

  Fuzzy Labels

    A Fuzzy::Label label has four attributes: the text of the label (it can
    be any scalar, really), and three numbers: low, mid, high if you imagine
    a cartesian plane (remember graph paper in algebra?) of all possible

lib/AI/Fuzzy/Set.pm  view on Meta::CPAN


    # accepts a hash of member weights..
    # ( $members{$member}=$weight )

    %{$self->{members}} = @_;
    bless $self, $class;
}

sub membership {
    # naturally, it returns a fuzzy value - the degree
    # to wich $item is a member of the set! :)

    my $self = shift;
    my $item = shift;

    if (defined(${$self->{members}}{$item})) {
	return ${$self->{members}}{$item};
    } else {
	return 0;
    }
}

sub members {
    # returns list of members, sorted from least membership to greatest
    my $self = shift;

    my %l = %{$self->{members}};
    return sort { $l{$a} <=> $l{$b} } keys %l;
}

sub equal {
    # returns true if the argument set is equal to this one
    my $self = shift;
    my $otherset = shift;

    my (%us, %them);
    %us = %{$self->{members}} if (exists $self->{members});
    %them = %{$otherset->{members}} if (exists $otherset->{members});

    # for all keys in us and them
    foreach my $key (keys (%us), keys (%them)) {
	# not equal if either set is missing a key
	return 0 unless (exists ($us{$key}) && exists ($them{$key}) );

	# not equal if the membership of the keys isn't equal
	return 0 unless (float_equal($us{$key},$them{$key}, 10));
    }

    # otherwise they are equal
    return 1;
}

sub union {
    # returns a set that is the union of us and the argument set
    my $self = shift;
    my $otherset = shift;

    my (%us, %them, %new);
    %us = %{$self->{members}} if (exists $self->{members});
    %them = %{$otherset->{members}} if (exists $otherset->{members});

    # for all keys in us and them
    foreach my $key (keys (%us), keys (%them)) {
	if (not exists $us{$key} and exists $them{$key}) {
	    $new{$key} = $them{$key};
	    next;
	}
	if (not exists $them{$key} and exists $us{$key}) {
	    $new{$key} = $us{$key};
	    next;

lib/AI/Fuzzy/Set.pm  view on Meta::CPAN

	    $new{$key} = $us{$key};
	} else {
	    $new{$key} = $them{$key};
	}
    }

    return new AI::Fuzzy::Set(%new);
}

sub intersection {
    # returns a set that is the intersection of us and the argument set
    my $self = shift;
    my $otherset = shift;

    my (%us, %them, %new);
    %us = %{$self->{members}} if (exists $self->{members});
    %them = %{$otherset->{members}} if (exists $otherset->{members});

    # for all keys in us and them
    foreach my $key (keys (%us), keys (%them)) {
	if (not exists $us{$key} or not exists $them{$key}) {
	    $new{$key} = 0;
	    next;
	}
	if ($us{$key} <= $them{$key}) {
	    $new{$key} = $us{$key};
	} else {
	    $new{$key} = $them{$key};
	}
    }

    return new AI::Fuzzy::Set(%new);
}

sub complement {
    # returns a set that is the complement of us
    # requires that the set contain values from 0 to 1
    my $self = shift;

    my (%new);

    foreach my $member ($self->members) {
	my $comp = 1 - $self->membership($member); 
	return undef if ($comp < 0 || $comp >1);

	$new{$member} = $comp;
    }

    return new AI::Fuzzy::Set(%new);
}

sub support {
    # returns the support set.
    # defined as the set of all elements in our set with a non-zero membership.
    my $self = shift;

    my (%support);
    foreach my $member ($self->members) {
	$support{$member}++ if ($self->membership($member) != 0);
    }

    return new AI::Fuzzy::Set(%support);
}

sub core { 
    # returns the core set.
    # defined as the set of all elements in our set with full membership
    my $self = shift;

    my (%core);
    foreach my $member ($self->members) {
	$core{$member}++ if ($self->membership($member) == 1);
    }

    return new AI::Fuzzy::Set(%core);
}

sub height { 
    # returns the height of the set
    # defined as the maximal membership value in our set
    my $self = shift;

    my ($max) = 0;
    foreach my $member ($self->members) {
	$max = $self->membership($member) if ($self->membership($member) > $max);
    }

    return $max;
}

sub is_normal {
    # Logical return
    # normal is defined as a set with a height of 1
    my $self = shift;

    return 1 if ($self->height == 1);
    return 0;
}

sub is_subnormal {
    # Logical return
    # normal is defined as a set with a height less than 1
    my $self = shift;

    return 1 if ($self->height < 1);
    return 0;
}

sub as_string {
    my $self = shift;

    my @members;



( run in 0.536 second using v1.01-cache-2.11-cpan-49f99fa48dc )