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   196 use strict;
  34         65  
  34         901  
3 34     34   151 use base 'Exporter';
  34         64  
  34         4104  
4              
5             BEGIN {
6 34     34   106 our ( @EXPORT_OK, %EXPORT_TAGS );
7 34         93 @EXPORT_OK = qw(nchoose gcd gcd_divide);
8 34         10859 %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 1258 my ( $n, $j, @nc_matrix ) = @_;
40 1020 50       1413 return 0 if $j > $n;
41 1020 50       1575 if ( @nc_matrix < $j + 1 ) {
42 1020         2211 push @nc_matrix, [] for @nc_matrix .. $j;
43             }
44 1020 50       1183 if ( @{ $nc_matrix[$j] } < $n + 1 ) {
  1020         1559  
45 1020         1072 push @{ $nc_matrix[$j] }, 0 for @{ $nc_matrix[$j] } .. $j - 1;
  1020         1495  
  1527         2178  
46             }
47 1020 50       1089 push @{ $nc_matrix[$j] }, 1 if @{ $nc_matrix[$j] } == $j;
  1020         1220  
  1020         1512  
48 1020         1103 for my $i ( @{ $nc_matrix[$j] } .. $n ) {
  1020         1369  
49 1073         1117 push @{ $nc_matrix[$j] }, $nc_matrix[$j]->[$i-1] * $i / ( $i - $j );
  1073         1877  
50             }
51 1020         2268 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 1337 my ( $n, $j ) = @_;
70 1020         1372 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
131             for any user or developer questions and discussions.
132              
133             =over
134              
135             =item L
136              
137             Also see the manual: L and L.
138              
139             =back
140              
141             =head1 CITATION
142              
143             If you use Bio::Phylo in published research, please cite it:
144              
145             B, B, B, B
146             and B, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
147             I B<12>:63.
148             L
149              
150             =cut
151              
152             1;