AI-NeuralNet-SOM

 view release on metacpan or  search on metacpan

lib/AI/NeuralNet/SOM/Hexa.pm  view on Meta::CPAN

use warnings;

use AI::NeuralNet::SOM;
use Data::Dumper;
use base qw(AI::NeuralNet::SOM);

use AI::NeuralNet::SOM::Utils;

=pod

=head1 NAME

AI::NeuralNet::SOM::Hexa - Perl extension for Kohonen Maps (hexagonal topology)

=head1 SYNOPSIS

  use AI::NeuralNet::SOM::Hexa;
  my $nn = new AI::NeuralNet::SOM::Hexa (output_dim => 6,
                                         input_dim  => 3);
  # ... see also base class AI::NeuralNet::SOM

=head1 INTERFACE

=head2 Constructor

The constructor takes the following arguments (additionally to those in the base class):

=over

=item C<output_dim> : (mandatory, no default)

A positive, non-zero number specifying the diameter of the hexagonal. C<1> creates one with a single
hexagon, C<2> one with 4, C<3> one with 9. The number plays the role of a diameter.

=back

Example:

    my $nn = new AI::NeuralNet::SOM::Hexa (output_dim => 6,
                                           input_dim  => 3);

=cut

sub new {
    my $class = shift;
    my %options = @_;
    my $self = bless { %options }, $class;

    if ($self->{output_dim} > 0) {
	$self->{_D} = $self->{output_dim};
    } else {
	die "output dimension must be positive integer";
    }
    if ($self->{input_dim} > 0) {
	$self->{_Z} = $self->{input_dim};
    } else {
	die "input dimension must be positive integer";
    }

    $self->{_R}      = $self->{_D} / 2;
    $self->{_Sigma0} = $options{sigma0}        || $self->{_R};                                  # impact distance, start value
    $self->{_L0}     = $options{learning_rate} || 0.1;                                       # learning rate, start value

    return $self;
}

=pod

=head2 Methods

=over

=item I<radius>

Returns the radius (half the diameter).

=cut

sub radius {
    my $self = shift;
    return $self->{_R};
}

=pod

=item I<diameter>

Returns the diameter (= dimension) of the hexagon.

=cut

sub diameter {
    my $self = shift;
    return $self->{_D};
}

=pod

=cut

sub initialize {
    my $self = shift;
    my @data = @_;

    our $i = 0;
    my $get_from_stream = sub {
	$i = 0 if $i > $#data;
	return [ @{ $data[$i++] } ];  # cloning !
    } if @data;
    $get_from_stream ||= sub {
	return [ map { rand( 1 ) - 0.5 } 1..$self->{_Z} ];
    };

    for my $x (0 .. $self->{_D}-1) {
	for my $y (0 .. $self->{_D}-1) {
	    $self->{map}->[$x]->[$y] = &$get_from_stream;
	}
    }
}

sub bmu {
    my $self = shift;



( run in 0.974 second using v1.01-cache-2.11-cpan-39bf76dae61 )