File Coverage

blib/lib/Algorithm/Bitonic/Sort.pm
Criterion Covered Total %
statement 68 72 94.4
branch 15 18 83.3
condition 7 10 70.0
subroutine 9 9 100.0
pod 1 1 100.0
total 100 110 90.9


line stmt bran cond sub pod time code
1             package Algorithm::Bitonic::Sort;
2              
3 2     2   24521 use utf8;
  2         12  
  2         8  
4 2     2   53 use feature 'say';
  2         2  
  2         142  
5 2     2   439 use common::sense;
  2         11  
  2         7  
6 2     2   89 use constant DEBUG => $ENV{ALGORITHM_BITONIC_SORT_DEBUG};
  2         2  
  2         277  
7              
8             if (DEBUG) {
9             require Data::Dumper::Simple;
10             }
11              
12             our (@ISA, @EXPORT);
13             BEGIN {
14 2     2   8 require Exporter;
15 2         12 @ISA = qw(Exporter);
16 2         1465 @EXPORT = qw(bitonic_sort); # symbols to export on request
17             }
18              
19             # "A supercomputer is a device for turning compute-bound problems into I/O-bound problems."
20              
21             =encoding utf8
22              
23             =head1 NAME
24              
25             Algorithm::Bitonic::Sort - Sorting numbers with Bitonic Sort
26              
27             =head1 VERSION
28              
29             Version 0.06
30              
31             =cut
32              
33             our $VERSION = '0.06';
34              
35              
36             =head1 SYNOPSIS
37              
38             Use L with the following style.
39              
40             use Algorithm::Bitonic::Sort;
41            
42             my @sample = (1,4,8,4,4365,2,67,33,345);
43             my @result_inc = bitonic_sort( 1 ,@sample); # incremental
44             my @result_dec = bitonic_sort( 0 ,@sample); # decremental
45              
46             =head1 DESCRIPTION
47              
48             Bitonic mergesort is a parallel algorithm for sorting. It is also used as a construction method for building a sorting network.
49             This is an Perl 5 implementation of Ken Batcher's Bitonic mergesort.
50              
51             =head1 Limitation
52              
53             This is a enhanced version of Bitonic Sort which removed the limitation of original version.
54             This module supports any amount of numbers.
55              
56             The original Bitonic can only sort N numbers, which N is a power of 2.
57              
58              
59             =head1 EXPORT
60              
61             bitonic_sort
62              
63              
64             =head1 SUBROUTINES
65              
66             =head2 bitonic_sort
67              
68             The First Parameter works as the ascending/decreasing selector.
69             True (1 or any true value) means ascending (incremental),
70             False (0 or any false value) means decreasing.
71              
72             All other params will be treated as members/items to be sorted.
73              
74              
75             =cut
76              
77             sub bitonic_sort {
78 30     30 1 350 my $up = shift;
79 30         16 say '#### Sort: '.Dumper(@_) if DEBUG;
80            
81 30 100       46 return @_ if int @_ <= 1;
82            
83 14 100       19 my $single_bit = shift @_ if @_ % 2;
84 14   100     21 $single_bit //= 'NA';
85            
86 14         8 say Dumper $single_bit if DEBUG;
87            
88 14         13 my @num = @_;
89 14         31 my @first = bitonic_sort( 1, @num[0..(@num /2 -1)] );
90 14         23 my @second = bitonic_sort( 0, @num[(@num /2)..(@num -1)] );
91            
92 14         17 return _bitonic_merge( $up, $single_bit, @first, @second );
93             }
94              
95             sub _bitonic_merge {
96 82     82   48 my $up = shift;
97 82         42 say '#### Merge: '.Dumper(@_) if DEBUG;
98            
99 82         54 my $single_bit = shift;
100 82         36 say Dumper $single_bit if DEBUG;
101            
102             # assume input @num is bitonic, and sorted list is returned
103 82 100       114 return @_ if int @_ == 1;
104            
105 34 50       42 my $single_bit_2 = shift @_ if @_ % 2;
106 34   100     41 $single_bit_2 //= 'NA';
107            
108 34         27 my @num = @_;
109 34         33 @num = _bitonic_compare( $up, @num );
110            
111 34         54 my @first = _bitonic_merge( $up, 'NA', @num[0..(@num /2 -1)] );
112 34         46 my @second = _bitonic_merge( $up, 'NA', @num[(@num /2)..(@num -1)] );
113            
114 34         30 @num = (@first, @second);
115 34 100       54 @num = _some_sorting_algorithm( $up, $single_bit, @first, @second ) if $single_bit ne 'NA';
116 34 50       39 @num = _some_sorting_algorithm( $up, $single_bit_2, @first, @second ) if $single_bit_2 ne 'NA';
117            
118 34         20 say "#####\n# Merge Result\n#####\n".Dumper(@num) if DEBUG;
119            
120 34         47 return (@num);
121             }
122              
123             sub _bitonic_compare {
124 34     34   23 my $up = shift;
125 34         16 say '#### Compare: '.Dumper(@_) if DEBUG;
126 34         27 my @num = @_;
127            
128 34         30 my $dist = int @num /2;
129             #~
130 34         34 for my $i (0..$dist-1) {
131 48         20 say "i=$i, dist=$dist, $num[$i] > $num[$i+$dist]) == $up" if DEBUG;
132 48 100       64 if ( ($num[$i] > $num[$i+$dist]) == $up ) {
133 26         21 say "Swapping....." if DEBUG;
134 26         31 ($num[$i], $num[$i+$dist]) = ($num[$i+$dist], $num[$i]); #swap
135             }
136             }
137             #~ for my $i (0..(int @$first)) {
138             #~ if ( ($first->[$i] > $second->[$i]) == $up ) {
139             #~ ($first->[$i], $second->[$i]) = ($second->[$i], $first->[$i]); #swap
140             #~ }
141             #~ }
142            
143 34         19 say 'Compared result:'.Dumper(@num) if DEBUG;
144 34         60 return @num;
145             #~ return ($first, $second);
146             }
147              
148              
149             sub _some_sorting_algorithm {
150 2     2   3 my $up = shift;
151 2         1 my $single_bit = shift;
152 2         14 my @num = @_;
153 2         2 my @num_new;
154            
155 2         1 say "_SOME_SORTING_ALGORITHM: INPUT: ".Dumper(@num) if DEBUG;
156            
157 2         5 while (my $curr = shift @num) {
158 9         2 say "_SOME_SORTING_ALGORITHM: for: ".Dumper($curr, $single_bit, @num) if DEBUG;
159 9 100 66     27 if ($up and $single_bit < $curr) {
    50 33        
160 1         2 push @num_new, $single_bit;
161 1         1 push @num_new, $curr;
162 1         1 say "Return earlier, up is ".($up or '0').':'.Dumper(@num_new, @num) if DEBUG;
163 1         4 return (@num_new, @num);
164             } elsif ($single_bit > $curr and not $up) {
165 0         0 push @num_new, $single_bit;
166 0         0 push @num_new, $curr;
167 0         0 say "Return earlier, up is ".($up or '0').':'.Dumper(@num_new, @num) if DEBUG;
168 0         0 return (@num_new, @num)
169             } else {
170 8         14 push @num_new, $curr;
171             }
172             }
173            
174 1         1 push @num_new, $single_bit;
175 1         1 say "Return normal, ".Dumper(@num_new, @num) if DEBUG;
176 1         3 return @num_new;
177             }
178              
179             =head1 AUTHOR
180              
181             BlueT - Matthew Lien - 練喆明, C<< >>
182              
183              
184             =head1 INSTALLATION
185              
186             To install this module, run the following commands:
187              
188             perl Makefile.PL
189             make
190             make test
191             make install
192              
193             Or install with cpanm
194              
195             cpanm Algorithm::Bitonic::Sort
196              
197              
198             =head1 BUGS
199              
200             Please report any bugs or feature requests to CPAN ( C, L ) or GitHub (L).
201             I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
202              
203              
204              
205              
206             =head1 SUPPORT
207              
208             You can find documentation for this module with the perldoc command.
209              
210             perldoc Algorithm::Bitonic::Sort
211              
212              
213             You can also look for information at:
214              
215             =over 4
216              
217             =item * RT: CPAN's request tracker (report bugs here)
218              
219             L
220              
221             =item * AnnoCPAN: Annotated CPAN documentation
222              
223             L
224              
225             =item * CPAN Ratings
226              
227             L
228              
229             =item * Search CPAN
230              
231             L
232              
233             =item * Launchpad
234              
235             L
236              
237             =item * GitHub
238              
239             L
240              
241             =back
242              
243              
244             =head1 ACKNOWLEDGEMENTS
245              
246             =head1 SEE ALSO
247              
248             =over 4
249              
250             =item * Batcher's web page at Kent State University
251              
252             L
253              
254             =item * Bitonic sorter on Wikipedia
255              
256             L
257              
258             =back
259              
260             =head1 LICENSE AND COPYRIGHT
261              
262             Copyright 2012-2017 BlueT - Matthew Lien - 練喆明.
263              
264             This program is free software; you can redistribute it and/or modify it
265             under the terms of either: the GNU General Public License as published
266             by the Free Software Foundation; or the Artistic License.
267              
268             See http://dev.perl.org/licenses/ for more information.
269              
270              
271             =cut
272              
273             1; # End of Algorithm::Bitonic::Sort