File Coverage

blib/lib/Bio/Phylo/Util/Math.pm
Criterion Covered Total %
statement 28 40 70.0
branch 4 14 28.5
condition n/a
subroutine 5 7 71.4
pod 4 4 100.0
total 41 65 63.0


line stmt bran cond sub pod time code
1             package Bio::Phylo::Util::Math;
2 34     34   188 use strict;
  34         57  
  34         853  
3 34     34   143 use base 'Exporter';
  34         53  
  34         3924  
4              
5             BEGIN {
6 34     34   105 our ( @EXPORT_OK, %EXPORT_TAGS );
7 34         86 @EXPORT_OK = qw(nchoose gcd gcd_divide);
8 34         9842 %EXPORT_TAGS = (
9             'all' => [@EXPORT_OK],
10             );
11             }
12              
13             =head1 NAME
14              
15             Bio::Phylo::Util::Math - Utility math functions
16              
17             =head1 EXPORTED FUNCTIONS
18              
19             =over
20              
21             =item nchoose_static
22              
23             Calculation of n choose j. This version saves partial results for use later.
24              
25             Type : Exported function
26             Title : nchoose_static
27             Usage : $c = nchoose_static( $n, $j )
28             Function: Calculation of n choose j.
29             Returns : n-choose
30             Args : $n, $j
31              
32             =cut
33              
34             # Calculation of n choose j
35             # This version saves partial results for use later
36             my @nc_matrix; #stores the values of nchoose(n,j)
37             # -- note: order of indices is reversed
38             sub nchoose_static {
39 1020     1020 1 1261 my ( $n, $j, @nc_matrix ) = @_;
40 1020 50       1372 return 0 if $j > $n;
41 1020 50       1544 if ( @nc_matrix < $j + 1 ) {
42 1020         2229 push @nc_matrix, [] for @nc_matrix .. $j;
43             }
44 1020 50       1172 if ( @{ $nc_matrix[$j] } < $n + 1 ) {
  1020         1558  
45 1020         1077 push @{ $nc_matrix[$j] }, 0 for @{ $nc_matrix[$j] } .. $j - 1;
  1020         1439  
  1527         2147  
46             }
47 1020 50       1079 push @{ $nc_matrix[$j] }, 1 if @{ $nc_matrix[$j] } == $j;
  1020         1269  
  1020         1470  
48 1020         1387 for my $i ( @{ $nc_matrix[$j] } .. $n ) {
  1020         1357  
49 1073         1109 push @{ $nc_matrix[$j] }, $nc_matrix[$j]->[$i-1] * $i / ( $i - $j );
  1073         1835  
50             }
51 1020         2276 return $nc_matrix[$j]->[$n];
52             }
53              
54             =item nchoose
55              
56             Calculation of n choose j. Dynamic version.
57              
58             Type : Exported function
59             Title : nchoose
60             Usage : $c = nchoose( $n, $j )
61             Function: Calculation of n choose j.
62             Returns : n-choose
63             Args : $n, $j
64              
65             =cut
66              
67             # dynamic programming version
68             sub nchoose {
69 1020     1020 1 1345 my ( $n, $j ) = @_;
70 1020         1312 return nchoose_static($n,$j,@nc_matrix);
71             }
72              
73             =item gcd
74              
75             Greatest common denominator - assumes positive integers as input
76              
77             Type : Exported function
78             Title : gcd
79             Usage : $gcd = gcd( $n, $m )
80             Function: Greatest common denominator
81             Returns : $gcd
82             Args : $n, $m
83              
84             =cut
85              
86             # GCD - assumes positive integers as input
87             # (subroutine for compare(t,u,v))
88             sub gcd {
89 0     0 1   my ( $n, $m ) = @_;
90 0 0         return $n if $n == $m;
91 0 0         ( $n, $m ) = ( $m, $n ) if $m > $n;
92 0           my $i = int($n / $m);
93 0           $n = $n - $m * $i;
94 0 0         return $m if $n == 0;
95            
96             # recurse
97 0           return gcd($m,$n);
98             }
99              
100             =item gcd_divide
101              
102             Takes two large integers and attempts to divide them and give
103             the float answer without overflowing
104              
105             Type : Exported function
106             Title : gcd_divide
107             Usage : $gcd = gcd_divide( $n, $m )
108             Function: Greatest common denominator
109             Returns : $gcd
110             Args : $n, $m
111              
112             =cut
113              
114             # Takes two large integers and attempts to divide them and give
115             # the float answer without overflowing
116             # (subroutine for compare(t,u,v))
117             # does this by first taking out the greatest common denominator
118             sub gcd_divide {
119 0     0 1   my ( $n, $m ) = @_;
120 0           my $x = gcd($n,$m);
121 0           $n /= $x;
122 0           $m /= $x;
123 0           return $n/$m;
124             }
125              
126             =back
127              
128             =head1 SEE ALSO
129              
130             There is a mailing list at L<https://groups.google.com/forum/#!forum/bio-phylo>
131             for any user or developer questions and discussions.
132              
133             =over
134              
135             =item L<Bio::Phylo::Manual>
136              
137             Also see the manual: L<Bio::Phylo::Manual> and L<http://rutgervos.blogspot.com>.
138              
139             =back
140              
141             =head1 CITATION
142              
143             If you use Bio::Phylo in published research, please cite it:
144              
145             B<Rutger A Vos>, B<Jason Caravas>, B<Klaas Hartmann>, B<Mark A Jensen>
146             and B<Chase Miller>, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
147             I<BMC Bioinformatics> B<12>:63.
148             L<http://dx.doi.org/10.1186/1471-2105-12-63>
149              
150             =cut
151              
152             1;