File Coverage

blib/lib/AI/NeuralNet/Simple.pm
Criterion Covered Total %
statement 60 63 95.2
branch 19 24 79.1
condition 6 12 50.0
subroutine 15 16 93.7
pod 9 12 75.0
total 109 127 85.8


line stmt bran cond sub pod time code
1             package AI::NeuralNet::Simple;
2              
3 3     3   109722 use Log::Agent;
  3         25169  
  3         308  
4              
5 3     3   20 use strict;
  3         6  
  3         86  
6              
7 3     3   13 use vars qw( $REVISION $VERSION @ISA );
  3         9  
  3         2883  
8              
9             $REVISION = '$Id: Simple.pm,v 1.3 2004/01/31 20:34:11 ovid Exp $';
10             $VERSION = '0.11';
11              
12             if ( $] >= 5.006 ) {
13             require XSLoader;
14             XSLoader::load( 'AI::NeuralNet::Simple', $VERSION );
15             }
16             else {
17             require DynaLoader;
18             push @ISA, 'DynaLoader';
19             AI::NeuralNet::Simple->bootstrap($VERSION);
20             }
21              
22 80042     80042 0 385810 sub handle { $_[0]->{handle} }
23              
24             sub new {
25 7     7 1 9927 my ( $class, @args ) = @_;
26 7 100       39 logdie "you must supply three positive integers to new()"
27             unless 3 == @args;
28 6         14 foreach (@args) {
29 16 100 66     165 logdie "arguments to new() must be positive integers"
30             unless defined $_ && /^\d+$/;
31             }
32 5         162 my $seed = rand(1); # Perl invokes srand() on first call to rand()
33 5         89 my $handle = c_new_network(@args);
34 5 50       20 logdie "could not create new network" unless $handle >= 0;
35 5         39 my $self = bless {
36             input => $args[0],
37             hidden => $args[1],
38             output => $args[2],
39             handle => $handle,
40             }, $class;
41 5         22 $self->iterations(10000); # set a reasonable default
42             }
43              
44             sub train {
45 80001     80001 1 253700 my ( $self, $inputref, $outputref ) = @_;
46 80001         125972 return c_train( $self->handle, $inputref, $outputref );
47             }
48              
49             sub train_set {
50 1     1 1 23 my ( $self, $set, $iterations, $mse ) = @_;
51 1   33     4 $iterations ||= $self->iterations;
52 1 50       2 $mse = -1.0 unless defined $mse;
53 1         3 return c_train_set( $self->handle, $set, $iterations, $mse );
54             }
55              
56             sub iterations {
57 5     5 1 10 my ( $self, $iterations ) = @_;
58 5 50       24 if ( defined $iterations ) {
59 5 50 33     48 logdie "iterations() value must be a positive integer."
60             unless $iterations
61             and $iterations =~ /^\d+$/;
62 5         27 $self->{iterations} = $iterations;
63 5         26 return $self;
64             }
65 0         0 $self->{iterations};
66             }
67              
68             sub delta {
69 3     3 1 1076 my ( $self, $delta ) = @_;
70 3 100       12 return c_get_delta( $self->handle ) unless defined $delta;
71 2 50       6 logdie "delta() value must be a positive number" unless $delta > 0.0;
72 2         8 c_set_delta( $self->handle, $delta );
73 2         4 return $self;
74             }
75              
76             sub use_bipolar {
77 3     3 1 10 my ( $self, $bipolar ) = @_;
78 3 100       12 return c_get_use_bipolar( $self->handle ) unless defined $bipolar;
79 2         6 c_set_use_bipolar( $self->handle, $bipolar );
80 2         17 return $self;
81             }
82              
83             sub infer {
84 0     0 1 0 my ( $self, $data ) = @_;
85 0         0 c_infer( $self->handle, $data );
86             }
87              
88             sub winner {
89              
90             # returns index of largest value in inferred answer
91 16     16 1 951 my ( $self, $data ) = @_;
92 16         49 my $arrayref = c_infer( $self->handle, $data );
93              
94 16         22 my $largest = 0;
95 16         56 for ( 0 .. $#$arrayref ) {
96 32 100       108 $largest = $_ if $arrayref->[$_] > $arrayref->[$largest];
97             }
98 16         85 return $largest;
99             }
100              
101             sub learn_rate {
102 12     12 1 4536 my ( $self, $rate ) = @_;
103 12 100       46 return c_get_learn_rate( $self->handle ) unless defined $rate;
104 6 100 66     73 logdie "learn rate must be between 0 and 1, exclusive"
105             unless $rate > 0 && $rate < 1;
106 5         13 c_set_learn_rate( $self->handle, $rate );
107 5         25 return $self;
108             }
109              
110             sub DESTROY {
111 6     6   1633 my $self = shift;
112 6         19 c_destroy_network( $self->handle );
113             }
114              
115             #
116             # Serializing hook for Storable
117             #
118              
119             sub STORABLE_freeze {
120 1     1 0 203 my ( $self, $cloning ) = @_;
121 1         3 my $internal = c_export_network( $self->handle );
122              
123             # This is an excellent example where "we know better" than
124             # the recommended way in Storable's man page...
125             # Behaviour is the same whether we're cloning or not --RAM
126              
127 1         8 my %copy = %$self;
128 1         3 delete $copy{handle};
129              
130 1         118 return ( "", \%copy, $internal );
131             }
132              
133             #
134             # Deserializing hook for Storable
135             #
136             sub STORABLE_thaw {
137 1     1 0 116 my ( $self, $cloning, $x, $copy, $internal ) = @_;
138 1         7 %$self = %$copy;
139 1         20 $self->{handle} = c_import_network($internal);
140             }
141              
142             1;
143              
144             __END__