File Coverage

blib/lib/PDL/GA.pm
Criterion Covered Total %
statement 12 65 18.4
branch 0 40 0.0
condition 0 6 0.0
subroutine 4 14 28.5
pod 10 10 100.0
total 26 135 19.2


line stmt bran cond sub pod time code
1              
2             #
3             # GENERATED WITH PDL::PP! Don't modify!
4             #
5             package PDL::GA;
6              
7             @EXPORT_OK = qw( roulette roulette_nr weightselect weightselect_nr cumuweightselect cumuweightselect_nr ga_make_unique PDL::PP ga_make_unique tobits _tobits PDL::PP _tobits frombits PDL::PP frombits mutate_bool PDL::PP mutate_bool PDL::PP mutate_range PDL::PP mutate_addrange mutate_bits PDL::PP _mutate_bits PDL::PP _xover1 PDL::PP _xover2 xover1 xover2 );
8             %EXPORT_TAGS = (Func=>[@EXPORT_OK]);
9              
10 1     1   194120 use PDL::Core;
  1         4  
  1         6  
11 1     1   269 use PDL::Exporter;
  1         2  
  1         6  
12 1     1   23 use DynaLoader;
  1         7  
  1         57  
13              
14              
15              
16             $PDL::GA::VERSION = 0.08;
17             @ISA = ( 'PDL::Exporter','DynaLoader' );
18             push @PDL::Core::PP, __PACKAGE__;
19             bootstrap PDL::GA $VERSION;
20              
21              
22              
23              
24 1     1   5 use strict;
  1         2  
  1         992  
25              
26             =pod
27              
28             =head1 NAME
29              
30             PDL::GA - Genetic algorithm utilities for PDLs
31              
32             =head1 SYNOPSIS
33              
34             use PDL;
35             use PDL::GA;
36              
37             ##-------------------------------------------------------------
38             ## TODO...
39              
40             =cut
41              
42              
43              
44              
45              
46              
47              
48             =head1 FUNCTIONS
49              
50              
51              
52             =cut
53              
54              
55              
56              
57             *ga_indx = &PDL::indx;
58              
59              
60              
61             =pod
62              
63             =head1 Weighted Selection
64              
65             =cut
66              
67              
68              
69             =pod
70              
71             =head2 roulette
72              
73             =for sig
74              
75             Signature: (weightmap(M); %options)
76             Options:
77             n => $n
78             to => [o]selindices($n)
79              
80             Stochastic (roulette-wheel) selection of $n objects from
81             $M objects, governed by the likelihood distribution $weightmap(), allowing repetitions.
82             Calls PDL::Primitive::vsearch().
83              
84             =cut
85              
86             sub roulette {
87 0     0 1   my ($wmap,%opts) = @_;
88 0           my ($seli);
89 0 0         if (defined($opts{to})) {
    0          
90 0           $seli = $opts{to};
91             } elsif (defined($opts{n})) {
92 0 0         $seli = zeroes(ga_indx(), (($wmap->dims)[1..($wmap->ndims-1)]), $opts{n}) if (!defined($seli));
93             $seli->resize((($wmap->dims)[1..($wmap->ndims-1)]), $opts{n})
94 0 0 0       if ($seli->ndims != $wmap->ndims || $seli->dim(-1) != $opts{n});
95             } else {
96 0           $seli = zeroes(ga_indx(),1);
97             }
98 0           my $wsum = $wmap->sumover->slice(',*1');
99 0           my $selw = PDL->random($seli->dims);
100 0           $selw *= $wsum;
101 0           $selw->vsearch($wmap->cumusumover, $seli);
102 0           return $seli;
103             }
104              
105              
106              
107             =pod
108              
109             =head2 roulette_nr
110              
111             =for sig
112              
113             Signature: (weightmap(M); %options)
114             Options:
115             n => $n
116             to => [o]selindices($n)
117              
118             Stochastic (roulette-wheel) selection of $n objects from
119             $M objects, governed by the likelihood distribution $weightmap(), without repetitions.
120             Wrapper for cumuweighselect_nr.
121              
122             =cut
123              
124             sub roulette_nr {
125 0     0 1   my ($wmap,%opts) = @_;
126 0           my ($seli);
127 0 0         if (defined($opts{to})) {
    0          
128 0           $seli = $opts{to};
129             } elsif (defined($opts{n})) {
130 0 0         $seli = zeroes(ga_indx(), (($wmap->dims)[1..($wmap->ndims-1)]), $opts{n}) if (!defined($seli));
131             $seli->resize((($wmap->dims)[1..($wmap->ndims-1)]), $opts{n})
132 0 0 0       if ($seli->ndims != $wmap->ndims || $seli->dim(-1) != $opts{n});
133             } else {
134 0           $seli = zeroes(ga_indx(),1);
135             }
136 0           my $wsum = $wmap->sumover->slice(',*1');
137 0           my $selw = PDL->random($seli->dims);
138 0           $selw *= $wsum;
139 0           return cumuweightselect_nr($wmap->cumusumover, $selw, $seli);
140             }
141              
142              
143              
144              
145             =pod
146              
147             =head2 weightselect
148              
149             =for sig
150              
151             Signature: (weightmap(M); selweights(S); [o]selindices(S))
152              
153             Stochastically select $S objects from a pool $M objects, allowing repetitions.
154             Likelihood selecting an object $i is given by $weightmap($i). Target
155             selection likelihoods are passed as $selweights(), which should have
156             values in the range [0,sum($weightmap)\(. Selected targets are
157             returned as indices in the range [0,$M\( in the PDL $selindices().
158              
159             See also:
160             roulette(),
161             cumuweightselect(),
162             roulette_nr(),
163             weightselect_nr(),
164             cumuweightselect_nr(),
165             PDL::Primitive::vsearch(),
166             PDL::Ufunc::cumusumover().
167              
168             =cut
169              
170             sub weightselect {
171             #my ($wmap,$selw,$seli) = @_;
172             return
173             #$selw->vsearch($wmap->cumusumover, @_);
174 0     0 1   $_[1]->vsearch($_[0]->cumusumover, @_[2..$#_]);
175             }
176              
177              
178              
179              
180             =pod
181              
182             =head2 weightselect_nr
183              
184             =for sig
185              
186             Signature: (weightmap(M); selweights(S); [o]selindices(S))
187              
188             Like weightselect() without repetition.
189             Wraps cumuweightselect_nr().
190              
191             =cut
192              
193             sub weightselect_nr {
194             #my ($wmap,$selw,$seli) = @_;
195             return
196             #cumuweightselect_nr($wmap->cumusumover,$selw,$seli);
197 0     0 1   cumuweightselect_nr($_[0]->cumusumover, @_[1..$#_]);
198             }
199              
200              
201              
202              
203             =pod
204              
205             =head2 cumuweightselect
206              
207             =for sig
208              
209             Signature: (cumuweightmap(M); selweights(S); indx [o]selindices(S))
210              
211             Stochastically select $S objects from a pool $M objects, allowing repetitions.
212             Cumulative likelihood selecting an object $i is given by $cumweightmap($i). Target
213             selection likelihoods are passed as $selweights(), which should have
214             values in the range [0,$cumuweightmap[-1]\(. Selected targets are
215             returned as indices in the range [0,$M\( in the PDL $selindices().
216             Really just a wrapper for PDL::Primitive::vsearch().
217              
218             See also:
219             roulette(),
220             weightselect(),
221             roulette_nr(),
222             weightselect_nr(),
223             cumuweightselect_nr(),
224             PDL::Primitive::vsearch(),
225             PDL::Ufunc::cumusumover().
226              
227             =cut
228              
229             sub cumuweightselect {
230             #my ($cwmap,$selw,$seli) = splice(@_,0,2);
231             return
232             #$selw->vsearch($cwmap, @_);
233 0     0 1   $_[1]->vsearch($_[0], @_[2..$#_]);
234             }
235              
236              
237              
238              
239             =pod
240              
241             =head2 cumuweightselect_nr
242              
243             =for sig
244              
245             Signature: (cumuweightmap(M); selweights(S); indx [o]selindices(S); indx [t]trynext(M); byte [t]ignore(M))
246              
247             Stochastically select $S objects from a pool $M objects, without repetitions.
248             Really just a wrapper for PDL::Primitive::vesarch() and ga_make_unique().
249              
250             =cut
251              
252             sub cumuweightselect_nr {
253 0     0 1   my ($cwmap,$selw,$seli,$try,$ignore) = @_;
254 0 0         $seli = zeroes(ga_indx(),$selw->dims) if (!defined($seli));
255 0           $selw->vsearch($cwmap, $seli);
256 0 0         $try = 1+PDL->sequence(ga_indx(),$cwmap->dim(0)) if (!defined($try));
257 0 0         $seli->inplace->ga_make_unique($try, (defined($ignore) ? $ignore : qw()));
258 0           return $seli;
259             }
260              
261              
262              
263              
264              
265             =head2 ga_make_unique
266              
267             =for sig
268              
269             Signature: (indx selected(S); int trynext(M); indx [o]unique_selected(S); byte [t]ignore(M))
270              
271              
272             Remove repetitions from a vector of selected items $selected() while retaining vector length.
273             $selected() should have values in the range [0..($M-1)], and it must be the case
274             that $S <= $M.
275             The vector $trynext() is used to (iteratively) map a non-unique item to the "next-best" item,
276             and are implicitly interpreted modulo $M.
277             The temporary $ignore is used to record which items have already appeared.
278             May be run in-place on $selected().
279             Generally, $trynext() should be something like 1+sequence($M).
280              
281              
282             =for bad
283              
284             ga_make_unique processes bad values.
285             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
286              
287              
288             =cut
289              
290              
291              
292              
293              
294              
295             *ga_make_unique = \&PDL::ga_make_unique;
296              
297              
298              
299              
300             =pod
301              
302             =head1 Gene Encoding and Decoding
303              
304             =cut
305              
306              
307              
308              
309             =pod
310              
311             =head2 tobits
312              
313             =for sig
314              
315             Signature: (ints(); [o]bits(B))
316              
317             Extract individual bits from integer type pdls.
318             Output pdl will be created with appropriate dimensions if unspecified.
319             Serious waste of memory, since PDL does not have a 'bit' type.
320              
321             =cut
322              
323             sub tobits {
324 0     0 1   my ($ints,$bits) = @_;
325 0 0         $bits = zeroes($ints->type,8*PDL::howbig($ints->type),$ints->dims) if (!defined($bits));
326 0           _tobits($ints,$bits);
327 0           return $bits;
328             }
329              
330              
331              
332              
333              
334             =head2 _tobits
335              
336             =for sig
337              
338             Signature: (a(); [o]bits(B))
339              
340             (Low-level method)
341              
342             Extract individual bits from integer type pdls.
343             Output pdl $bits() must be specified!
344              
345              
346             =for bad
347              
348             _tobits does not process bad values.
349             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
350              
351              
352             =cut
353              
354              
355              
356              
357              
358              
359             *_tobits = \&PDL::_tobits;
360              
361              
362              
363              
364              
365             =head2 frombits
366              
367             =for sig
368              
369             Signature: (bits(B); [o]a())
370              
371             =for ref
372              
373             Compress expanded bit-pdls to integer types.
374              
375              
376             =for bad
377              
378             frombits does not process bad values.
379             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
380              
381              
382             =cut
383              
384              
385              
386              
387              
388              
389             *frombits = \&PDL::frombits;
390              
391              
392              
393              
394             =pod
395              
396             =head1 Mutation
397              
398             =cut
399              
400              
401              
402              
403              
404             =head2 mutate_bool
405              
406             =for sig
407              
408             Signature: (genes(G); float+ rate(G); [o]mutated(G))
409              
410             =for ref
411              
412             Mutate binary-valued (boolean) genes.
413              
414             =for bad
415              
416             mutate_bool does not process bad values.
417             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
418              
419              
420             =cut
421              
422              
423              
424              
425              
426              
427             *mutate_bool = \&PDL::mutate_bool;
428              
429              
430              
431              
432              
433             =head2 mutate_range
434              
435             =for sig
436              
437             Signature: (genes(G); float+ rate(G); min(G); max(G); [o]mutated(G))
438              
439             =for ref
440              
441             Mutate genes in the range [$min,$max\(.
442              
443             =for bad
444              
445             mutate_range does not process bad values.
446             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
447              
448              
449             =cut
450              
451              
452              
453              
454              
455              
456             *mutate_range = \&PDL::mutate_range;
457              
458              
459              
460              
461              
462             =head2 mutate_addrange
463              
464             =for sig
465              
466             Signature: (genes(G); float+ rate(G); min(G); max(G); [o]mutated(G))
467              
468             =for ref
469              
470             Mutate genes by adding values in the range [$min,$max\(.
471              
472             =for bad
473              
474             mutate_addrange does not process bad values.
475             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
476              
477              
478             =cut
479              
480              
481              
482              
483              
484              
485             *mutate_addrange = \&PDL::mutate_addrange;
486              
487              
488              
489              
490             =pod
491              
492             =head2 mutate_bits
493              
494             =for sig
495              
496             Signature: (genes(G); rate(); [o]mutated(G))
497              
498             Mutate traditional bit-string genes.
499             Calls mutate_bool(), tobits(), frombits().
500              
501             =cut
502              
503             sub mutate_bits {
504             #my ($pop,$rate,$dst) = @_;
505             #return $pop->tobits->inplace->mutate_bool($rate)->frombits(defined($dst) ? $dst : qw());
506 0     0 1   return $_[0]->tobits->inplace->mutate_bool($_[1])->frombits(@_[2..$#_]);
507             }
508              
509              
510              
511              
512              
513             =head2 _mutate_bits
514              
515             =for sig
516              
517             Signature: (genes(G); float+ rate(G); [o]mutated(G))
518              
519             (Low-level method)
520              
521             Mutate traditional bit-string genes.
522             This should be equivalent to mutate_bits(), but appears to involve
523             less overhead (faster for many calls).
524              
525              
526             =for bad
527              
528             _mutate_bits does not process bad values.
529             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
530              
531              
532             =cut
533              
534              
535              
536              
537              
538              
539             *_mutate_bits = \&PDL::_mutate_bits;
540              
541              
542              
543              
544             =pod
545              
546             =head1 Crossover
547              
548             =cut
549              
550              
551              
552              
553              
554             =head2 _xover1
555              
556             =for sig
557              
558             Signature: (mom(G); dad(G); indx xpoint(); [o]kid(G))
559              
560             (Low-level method)
561              
562             Single-point crossover.
563             $kid() is computed by single-point crossover of $mom() (initial subsequence)
564             and $dad() (final subsequence). For symmetric crossover (two offspring per crossing),
565             call this method twice:
566              
567             $kid1 = _xover1($mom, $dad, $points);
568             $kid2 = _xover1($dad, $mom, $points);
569              
570              
571              
572             =for bad
573              
574             _xover1 does not process bad values.
575             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
576              
577              
578             =cut
579              
580              
581              
582              
583              
584              
585             *_xover1 = \&PDL::_xover1;
586              
587              
588              
589              
590              
591             =head2 _xover2
592              
593             =for sig
594              
595             Signature: (mom(G); dad(G); indx xstart(); int xend(); [o]kid(G))
596              
597             (Low-level method)
598              
599             Dual-point crossover.
600             $kid() is computed by dual-point crossover of $mom() (initial and final subsequences)
601             and $dad() (internal subsequence). For symmetric crossover (two offspring per crossing),
602             call this method twice:
603              
604             $kid1 = _xover2($mom, $dad, $points1, $points2);
605             $kid2 = _xover2($dad, $mom, $points1, $points2);
606              
607              
608              
609             =for bad
610              
611             _xover2 does not process bad values.
612             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
613              
614              
615             =cut
616              
617              
618              
619              
620              
621              
622             *_xover2 = \&PDL::_xover2;
623              
624              
625              
626              
627             =pod
628              
629             =head2 xover1
630              
631             =for sig
632              
633             Signature: (mom(G); dad(G); float+ rate(); [o]kid(G))
634              
635             Random single-point crossover.
636             Calls _xover1().
637              
638             =cut
639              
640             sub xover1 {
641 0     0 1   my ($mom, $dad, $rate, $kid) = @_;
642 0           my $xwhich = (PDL->random($mom->dim(1)) < $rate)->which;
643 0 0         if ($xwhich->isempty) {
644 0 0         return ($mom->is_inplace
    0          
645             ? $mom
646             : (defined($kid)
647             ? ($kid .= $mom)
648             : ($kid = pdl($mom))));
649             }
650 0           my $xpoint = PDL->zeroes(ga_indx(),$mom->dim(1)) + $mom->dim(0);
651 0           $xpoint->index($xwhich) .= PDL->random($xwhich->nelem)*($mom->dim(0)-1)+1;
652 0 0         return _xover1($mom,$dad, $xpoint, (defined($kid) ? $kid : qw()));
653             }
654              
655              
656              
657              
658             =pod
659              
660             =head2 xover2
661              
662             =for sig
663              
664             Signature: (mom(G); dad(G); float+ rate(); [o]kid(G))
665              
666             Random dial-point crossover.
667             Calls _xover2().
668              
669             =cut
670              
671             sub xover2 {
672 0     0 1   my ($mom, $dad, $rate, $kid) = @_;
673 0           my $xwhich = (PDL->random($mom->dim(1)) < $rate)->which;
674 0 0         if ($xwhich->isempty) {
675 0 0         return ($mom->is_inplace
    0          
676             ? $mom
677             : (defined($kid)
678             ? ($kid .= $mom)
679             : ($kid = pdl($mom))));
680             }
681 0           my $xpoint1 = PDL->zeroes(ga_indx(),$mom->dim(1)) + $mom->dim(0);
682 0           $xpoint1->index($xwhich) .= PDL->random($xwhich->nelem)*($mom->dim(0)-1)+1;
683 0           my $xpoint2 = pdl($xpoint1);
684 0           $xpoint2->index($xwhich) += 1+PDL->random($xwhich->nelem)*($mom->dim(0)-$xpoint1->index($xwhich));
685 0 0         return _xover2($mom,$dad, $xpoint1, $xpoint2, (defined($kid) ? $kid : qw()));
686             }
687              
688              
689              
690              
691             ##---------------------------------------------------------------------
692             =pod
693              
694             =head1 ACKNOWLEDGEMENTS
695              
696             Perl by Larry Wall.
697              
698             PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others.
699              
700             =cut
701              
702             ##----------------------------------------------------------------------
703             =pod
704              
705             =head1 KNOWN BUGS
706              
707             Probably many.
708              
709             =cut
710              
711              
712             ##---------------------------------------------------------------------
713             =pod
714              
715             =head1 AUTHOR
716              
717             Bryan Jurish Emoocow@cpan.org
718              
719             =head2 Copyright Policy
720              
721             Copyright (C) 2006-2007, Bryan Jurish. All rights reserved.
722              
723             This package is free software, and entirely without warranty.
724             You may redistribute it and/or modify it under the same terms
725             as Perl itself.
726              
727             =head1 SEE ALSO
728              
729             perl(1), PDL(3perl).
730              
731             =cut
732              
733              
734              
735             ;
736              
737              
738              
739             # Exit with OK status
740              
741             1;
742              
743