File Coverage

blib/lib/MyBioinfo/NBTest.pm
Criterion Covered Total %
statement 9 108 8.3
branch 0 48 0.0
condition n/a
subroutine 3 7 42.8
pod 0 4 0.0
total 12 167 7.1


line stmt bran cond sub pod time code
1             package MyBioinfo::NBTest;
2              
3 1     1   7 use strict;
  1         3  
  1         41  
4 1     1   6 use Math::CDF;
  1         2  
  1         206  
5 1     1   7 use MyBioinfo::Common;
  1         3  
  1         1693  
6              
7             require Exporter;
8             our @ISA = qw(Exporter);
9              
10             our @EXPORT_OK = qw();
11              
12             our @EXPORT = qw(nb_pval);
13              
14             our $VERSION = '0.50';
15              
16             #r,p parameters of negative binomial distribution
17             sub nb_r_p{
18 0     0 0   my ($m,$v,$ref,$eps)=@_;
19 0           my $r;
20             my $p;
21             # print "v = $v\t m = $m\n";
22 0 0         if($m==0)
23             {
24 0           $r = $eps;
25 0           $p = $eps;
26             }
27             else{
28            
29 0 0         if($v<$m)
30             {
31 0           $v = $m + $eps;
32             }
33 0           $r = $m**2/($v-$m);
34 0           $p = $r/($r + $m);
35             }
36 0           push @{$ref},$r;
  0            
37 0           push @{$ref},$p;
  0            
38             }
39              
40             #density distribution of negative binomial
41             sub dnbinom{
42 0     0 0   my ($x,$r,$p)=@_;
43             #print "$x\t$r\t$p\n";
44            
45 0 0         if($x-1<0)
46             {
47 0 0         if($x==0)
48             {
49 0           return &Math::CDF::pnbinom($x,$r,$p) +1e-08;
50             }
51             else
52             {
53 0           return &Math::CDF::pnbinom($x,$r,$p)-&Math::CDF::pnbinom(0,$r,$p) +1e-08;
54            
55             }
56            
57             }
58             else{
59 0           return &Math::CDF::pnbinom($x,$r,$p)-&Math::CDF::pnbinom($x-1,$r,$p) + 1e-08; #avoid zero case
60             }
61            
62             }
63              
64             #quick computation of pvalues of negative binomial distribution
65             sub nb_join_pval{
66 0     0 0   my($kl,$kr,$kS,$sizeA,$probA,$sizeB,$probB,$probs,$eps) = @_;
67            
68 0           my $lval = dnbinom( $kl, $sizeA, $probA ) * dnbinom( $kS-$kl, $sizeB, $probB );
69 0           my $rval = dnbinom( $kr, $sizeA, $probA ) * dnbinom( $kS-$kr, $sizeB, $probB );
70 0           my $prevlval = $lval;
71 0           my $prevrval = $rval;
72 0           my $total = $lval + $rval;
73 0           my $esttotalperlength = $total/2;
74            
75 0           my $obstotal = 0;
76 0           my $step = 1;
77 0           my $steps = 0;
78 0           my $do_left ;
79            
80 0 0         if( $lval <= $probs )
81 0           { $obstotal += $lval; }
82 0 0         if( $rval <= $probs )
83 0           { $obstotal += $rval; }
84            
85 0           while( $kl < $kr ) {
86 0           $steps ++;
87 0 0         if( abs($prevrval - $rval) / $prevrval > .01 )
88 0           { $do_left = 1;}
89 0 0         else{ if( abs($prevlval - $lval) / $prevlval > .01 )
90 0           { $do_left = 0; }
  0            
91             else
92             {$do_left = $lval > $rval;}
93             }
94            
95 0 0         if( $do_left ) { #left to right
96 0           $prevlval = $lval;
97 0 0         if( $kl + $step > $kr )
98 0           { $step = $kr - $kl;}
99 0           $kl += $step;
100 0           $lval = dnbinom( $kl, $sizeA, $probA) * dnbinom( $kS-$kl, $sizeB, $probB);
101            
102 0 0         if( $step == 1 )
103 0           { $total += $lval; }
104             else
105 0           { $total += min( $lval, $prevlval ) * $step; } #estimate multiple steps
106            
107 0 0         if( $lval <= $probs ) {
108 0 0         if( $step == 1 )
109 0           { $obstotal += $lval;}
110             else {
111 0 0         if( $prevlval <= $probs )
112 0           { $obstotal += max( $lval, $prevlval ) * $step;}
113             else
114 0           { $obstotal += max( $lval, $prevlval ) * $step * abs( ($probs-$lval) / ($prevlval-$lval) );}
115             }
116             }
117 0 0         if( abs( $prevlval - $lval ) / $prevlval < $eps )
118 0           { $step = max( $step + 1, $step * 1.5 );}
119            
120             }
121            
122             else { #right to left
123 0           $prevrval = $rval;
124 0 0         if( $kr - $step < $kl )
125 0           { $step = $kr - $kl;}
126 0           $kr -= $step;
127 0           $rval = dnbinom( $kr, $sizeA, $probA ) * dnbinom( $kS-$kr, $sizeB, $probB);
128 0 0         if( $step == 1 )
129 0           { $total += $rval;}
130             else
131 0           { $total += min($rval, $prevrval ) * $step;}
132 0 0         if( $rval <= $probs ) {
133 0 0         if( $step == 1 )
134 0           { $obstotal += $rval;}
135             else {
136 0 0         if( $prevrval <= $probs )
137 0           { $obstotal += max( $rval, $prevrval ) * $step;}
138             else
139 0           { $obstotal += max( $rval, $prevrval ) * $step * abs($probs-$rval) / ($prevrval-$rval);}
140             }
141             }
142 0 0         if( abs( $prevrval - $rval) / $prevrval < $eps )
143 0           { $step = max( $step + 1, $step * 1.5 );}
144             }
145             }
146            
147 0 0         if($obstotal > $total)
148             {
149 0           return ($total,$total);
150             }
151 0           return ($total, $obstotal);
152             }
153              
154             #p-value of negative binomial distribution
155             sub nb_pval{
156 0     0 0   my ($ka,$kb,$miu1,$var1,$miu2,$var2,$eps) = @_;
157            
158 0           my $ks = $ka+$kb;
159            
160 0           my @rp1 = ();
161 0           nb_r_p($miu1,$var1,\@rp1,$eps);
162 0           my @rp2 = ();
163 0           nb_r_p($miu2,$var2,\@rp2,$eps);
164            
165 0           my $r1 = $rp1[0];
166 0           my $p1 = $rp1[1];
167            
168 0           my $r2 = $rp2[0];
169 0           my $p2 = $rp2[1];
170            
171            
172             # print "$miu1,$var1\n";
173             #print "A = $ka\t$r1\t$p1\n";
174             #print "B = $kb\t$r2\t$p2\n";
175 0           my $kexp = ($ka+$kb) * $miu1/($miu1 + $miu2);
176            
177 0           my $pv1 = dnbinom($ka,$r1,$p1);
178 0           my $pv2 = dnbinom($kb,$r2,$p2);
179 0           my $p = $pv1 * $pv2;
180             #print "$pv1\t$pv2\t$p\n";
181            
182 0           my ($ldenom,$lnume) = nb_join_pval(0,$kexp,$ka+$kb,$r1,$p1,$r2,$p2,$p,$eps);
183            
184 0           my $kl2 = $kexp +1;
185 0 0         if($kexp +1> $ka+$kb)
186             {
187 0           $kl2 = $ka + $kb;
188             }
189 0           my ($denominator,$numerator) = nb_join_pval($kl2,$ka+$kb,$ka+$kb,$r1,$p1,$r2,$p2,$p,$eps);
190 0 0         if($numerator + $lnume==0)
191             {
192            
193 0           return $p/($denominator+$ldenom);
194             }
195 0           return ($numerator+$lnume)/($denominator+$ldenom);
196             }
197              
198             1;
199             __END__