3 # BioPerl module for Bio::Tools::RandomDistFunctions
5 # Cared for by Jason Stajich <jason-at-bioperl.org>
7 # Copyright Jason Stajich
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
15 Bio::Tools::RandomDistFunctions - A set of routines useful for
16 generating random data in different distributions
20 use Bio::Tools::RandomDistFunctions;
21 my $dist = Bio::Tools::RandomDistFunctions->new();
22 for my $v ( 1..1000 ) {
23 my $birth_dist = $dist->rand_birth_distribution($lambda);
24 # ... do something with the variable
29 Most of the code is based on the C implementation of these routines in
30 Mike Sanderson's r8s's package. See http://ginger.ucdavis.edu/ for
31 information on his software.
33 This code tries to be fast and use available faster BigInt and GMP
34 library methods when those modules are available.
40 User feedback is an integral part of the evolution of this and other
41 Bioperl modules. Send your comments and suggestions preferably to
42 the Bioperl mailing list. Your participation is much appreciated.
44 bioperl-l@bioperl.org - General discussion
45 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
49 Report bugs to the Bioperl bug tracking system to help us keep track
50 of the bugs and their resolution. Bug reports can be submitted via the
53 http://bugzilla.open-bio.org/
55 =head1 AUTHOR - Jason Stajich
57 Email jason-at-bioperl.org
61 Thanks to Mike Sanderson for assistance in the getting this
62 implementation together.
66 The rest of the documentation details each of the object methods.
67 Internal methods are usually preceded with a _
72 # Let the code begin...
75 package Bio
::Tools
::RandomDistFunctions
;
77 use vars
qw(%LOADED @EXPORT_OK); use strict;
79 #use Math::BigFloat lib => 'GMP,Bit::Vector';
80 #use Math::BigInt lib => 'GMP,Bit::Vector';
83 use base qw(Bio::Root::Root);
85 =head2 birth_distribution
87 Title : rand_birth_distribution
88 Usage : my $randvar = $dist->
89 rand_birth_distribution($lambda);
90 Function: Returns a random number from a birth process waiting
91 time with a fixed interval
92 1.0. Times are measured from 0=present,1=root;
93 Returns : floating point number
94 Args : $lambda ( > 0 )
95 References : This is based on code by Mike Sanders in r8s.
96 Ross, Stochastic Processes, p. 145 for the density
100 sub rand_birth_distribution
{
101 my ($self,$lambda) = @_;
103 $self !~ /RandomDistFunctions/ ) {
107 $self->throw("Cannot call birth_distribution without a valid lambda value (>0)");
109 return 1 - (log(rand(1) * (exp($lambda) - 1)+1)/ $lambda);
113 =head2 rand_geometric_distribution
115 Title : rand_geometric_distribution
116 Usage : my $randvar = $dist->rand_geometric_distribution($param);
117 Function: Returns a random geometric variate distributed with
118 paramater $param, according to
119 c.d.f. 1 - ( 1- param) ^ n
121 Args : $param ( 0 > $param < 1 )
126 sub rand_geometric_distribution
{
127 my ($self,$param) = @_;
129 $self !~ /RandomDistFunctions/ ) {
133 $self->throw("Cannot call rand_geometric_distribution without a valid param value (>0)");
138 $den = (-1 * $param) - ( $param * $param ) / 2;
140 $den = log(1 - $param);
142 my $z = log(1 - rand(1)) / $den;
143 return POSIX
::floor
($z) + 1;
144 # MSanderson comments from r8s code
145 # Is this the right truncation of the real-valued expression above?
147 # Checked by reference to the expected mean of the distribution in
149 # EX = 1/param Var = (1-param)/param^2 See Olkin, Gleser, and
150 # Derman, p. 193ff. Probability Models and Applications, 1980.
153 =head2 rand_exponentional_distribution
155 Title : rand_exponentional_distribution
156 Usage : my $var = $dist->rand_exponentional_distribution($param);
157 Function: Returns a random exponential variate distributed with parameter
158 $param, according to c.d.f 1 - e^(-param * x)
159 Returns : floating point number
160 Args : $param ( > 0 )
165 sub rand_exponentional_distribution
{
166 my ($self,$param) = @_;
168 $self !~ /RandomDistFunctions/ ) {
172 $self->throw("Cannot call rand_exponentional_distribution without a valid param value (>0)");
174 return log( 1- rand(1)) / $param;
177 =head2 rand_normal_distribution
179 Title : rand_normal_distribution
180 Usage : my $var = $dist->rand_normal_distribution()
181 Function: Returns a random normal (gaussian) variate distributed
182 Returns : floating point number
188 sub rand_normal_distribution
{
190 my ($rsq,$v1,$v2) = ( 0,0,0);
192 $v1 = 2 * rand(1) - 1;
193 $v2 = 2 * rand(1) - 1;
194 $rsq= $v1**2 + $v2 ** 2;
195 } while( $rsq >= 1 || $rsq == 0);
196 my $fac = sqrt(-2.0 * log($rsq) / $rsq );