File Coverage

blib/lib/Math/Symbolic/AuxFunctions.pm
Criterion Covered Total %
statement 26 26 100.0
branch n/a
condition n/a
subroutine 14 14 100.0
pod 8 8 100.0
total 48 48 100.0


line stmt bran cond sub pod time code
1              
2             =encoding utf8
3              
4             =head1 NAME
5              
6             Math::Symbolic::AuxFunctions - Auxiliary functions for Math::Symbolic hierarchy
7              
8             =head1 SYNOPSIS
9              
10             use Math::Symbolic::AuxFunctions;
11            
12             Math::Symbolic::AuxFunctions::acos($x);
13             # etc
14              
15             =head1 DESCRIPTION
16              
17             This module contains implementations of some auxiliary functions that are
18             used within the Math::Symbolic hierarchy of modules. In particular, this
19             module holds all trigonometric functions used for numeric evaluation of
20             trees by Math::Symbolic::Operator.
21              
22             =head2 EXPORT
23              
24             None. On purpose. If I wished this module would pollute others' namespaces,
25             I'd have put the functions right where they're used.
26              
27             =cut
28              
29             package Math::Symbolic::AuxFunctions;
30              
31 23     23   648 use 5.006;
  23         109  
  23         1040  
32 23     23   134 use strict;
  23         43  
  23         922  
33 23     23   123 use warnings;
  23         41  
  23         750  
34              
35 23     23   147 use Carp;
  23         38  
  23         2168  
36              
37 23     23   195 use Math::Symbolic::ExportConstants qw/:all/;
  23         53  
  23         7501  
38 23     23   29671 use Memoize;
  23         70335  
  23         11905  
39              
40             our $VERSION = '0.612';
41              
42             =head1 TRIGONOMETRIC FUNCTIONS
43              
44             =head2 tan
45              
46             Computes the tangent sin(x) / cos(x).
47              
48             =cut
49              
50 20     20 1 70 sub tan { sin( $_[0] ) / cos( $_[0] ) }
51              
52             =head2 cot
53              
54             Computes the cotangent cos(x) / sin(x).
55              
56             =cut
57              
58 20     20 1 68 sub cot { cos( $_[0] ) / sin( $_[0] ) }
59              
60             =head2 asin
61              
62             Computes the arc sine asin(z) = -i log(iz + sqrt(1-z*z)).
63             Above formula is for complex numbers.
64              
65             =cut
66              
67 20     20 1 74 sub asin { atan2( $_[0], sqrt( 1 - $_[0] * $_[0] ) ) }
68              
69             =head2 acos
70              
71             Computes the arc cosine acos(z) = -i log(z + sqrt(z*z-1)).
72             Above formula is for complex numbers.
73              
74             =cut
75              
76 20     20 1 77 sub acos { atan2( sqrt( 1 - $_[0] * $_[0] ), $_[0] ) }
77              
78             =head2 atan
79              
80             Computes the arc tangent atan(z) = i/2 log((i+z) / (i-z)).
81             Above formula is for complex numbers.
82              
83             =cut
84              
85 20     20 1 63 sub atan { atan2( $_[0], 1 ) }
86              
87             =head2 acot
88              
89             Computes the arc cotangent ( atan( 1 / x ) ).
90              
91             =cut
92              
93 20     20 1 66 sub acot { atan2( 1 / $_[0], 1 ) }
94              
95             =head2 asinh
96              
97             Computes the arc hyperbolic sine asinh(z) = log(z + sqrt(z*z+1))
98              
99             =cut
100              
101 20     20 1 70 sub asinh { log( $_[0] + sqrt( $_[0] * $_[0] + 1 ) ) }
102              
103             =head2 acosh
104              
105             Computes the arc hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)).
106              
107             =cut
108              
109 20     20 1 69 sub acosh { log( $_[0] + sqrt( $_[0] * $_[0] - 1 ) ) }
110              
111             =head1 OTHER FUNCTIONS
112              
113             =cut
114              
115             =head2 binomial_coeff
116              
117             Calculates the binomial coefficient n over k of its first two
118             arguments (n, k).
119              
120             Code taken from Orwant et al, "Mastering Algorithms with Perl"
121              
122             =cut
123              
124             memoize('binomial_coeff');
125              
126             sub binomial_coeff {
127             my ( $n, $k ) = @_;
128             my ( $res, $j ) = ( 1, 1 );
129              
130             return 0 if $k > $n || $k < 0;
131             $k = ( $n - $k ) if ( $n - $k ) < $k;
132              
133             while ( $j <= $k ) {
134             $res *= $n--;
135             $res /= $j++;
136             }
137             return $res;
138             }
139              
140             =head2 bell_number
141              
142             The Bell numbers are defined as follows:
143              
144             B_0 = 1
145             B_n+1 = sum_k=0_to_n( B_k * binomial_coeff(n, k) )
146              
147             This function uses memoization.
148              
149             =cut
150              
151             memoize('bell_number');
152              
153             sub bell_number {
154             my $n = shift;
155             return undef if $n < 0;
156             return 1 if $n == 0;
157             my $bell = 0;
158             $bell += bell_number($_) * binomial_coeff( $n - 1, $_ ) for 0 .. $n - 1;
159             return $bell;
160             }
161              
162             1;
163             __END__