math - Highly specific factorial calculations in PHP -
i have been working on php page calculates probabilities of different outcomes while randomly selecting sample group larger group consisted of 2 types of people (+
, -
).
for example, can calculate probability of having 0 (or n
) smokers in group of 1000
people randomly chosen across united states, considering 0.15
of americans smokers (+
).
it works while working populations below 10000
people, when comes bigger populations of 1000000
, echoes 0
probabilities unless precision (number of digits after .
) increased 3000
. in case takes forever.
the code works calculating probability of 0
positives, , doing calculations on probability of 1
positive, , on. while of these probabilities useless.
i have been thinking if can figure out fast way of calculating exact (99.999%
or higher) value of big factorials (like 1000000!
), there wouldn't need starting 0
, , calculation have been started place needed, , low precision reduce time takes.
here code:
<html> <body> <form method="get"> target population: <input type="text" name="tpop"><br><br> selected population: <input type="text" name="selected"><br><br> fraction of positives: <input type="text" name="fop"><br><br> output margin: <input type="text" name="margin"><br><br> precision: <input type="text" name="precision"><br><br> <input type="submit"> </form> </body> </html> <?php set_time_limit(0); if (isset($_get["precision"],$_get["tpop"],$_get["selected"],$_get["fop"],$_get["margin"])&&$_get["precision"]!=''&&$_get["tpop"]!=''&&$_get["selected"]!=''&&$_get["fop"]!=''&&$_get["margin"]!=''&&$_get["tpop"]>=$_get["selected"]&&$_get["fop"]>=0&&$_get["fop"]<=1){ $tpop=$_get["tpop"]; $selected=$_get["selected"]; $fop=$_get["fop"]; $margin=$_get["margin"]; $ioioio=0; $precision=$_get["precision"]; $minor=($selected*$fop)-$margin; $maxor=$minor+(2*$margin); $popopo=bcmul($tpop,$fop); echo '<br><br>min is'.$minor.'max is'.$maxor.'<br><br>'; $mmm=bcsub($tpop,$selected,$precision); $rea=bcsub($mmm,1,$precision); $fops=bcmul($tpop,$fop); $trss=bcsub($tpop,$fops,$precision); $trss=bcsub($trss,$selected,$precision); $trss=bcadd($trss,1,$precision); while($rea>=$trss){ $mmm=bcmul($mmm,$rea,$precision); $rea=bcsub($rea,1,$precision); } $nnn=$tpop; $sfg=bcsub($nnn,1,$precision); $ugt=bcmul($tpop,$fop,$precision); $uyt=bcsub($tpop,$ugt); $uyt=bcadd($uyt,1,$precision); while($sfg>=$uyt){ $nnn=bcmul($nnn,$sfg,$precision); $sfg=bcsub($sfg,1,$precision); } $zero=bcdiv($mmm,$nnn,$precision); echo '0==>'.$zero.'<br><br>'; $a=$selected; $b=($tpop-($tpop*$fop)-$selected+1); $c=1; $d=($tpop*$fop); $i=1; $origzero=$zero; $save=$zero; while($i<=$selected){ if($d<=0){ echo $i.'==>impossible<br><br>'; $a--; $b++; $c++; $d--; $i++; }else{ $zero=bcmul($zero,$a,$precision); $zero=bcmul($zero,$d,$precision); $zero=bcdiv($zero,$b,$precision); $zero=bcdiv($zero,$c,$precision); if($i>=$minor){ if($i<=$maxor){ if($i<=$popopo){ $ioioio=bcadd($ioioio,$zero,$precision); echo 'following value included in p value<br>'; echo $i.'==>'.$zero.'<br><br>'; } } } $save=bcadd($save,$zero,$precision); $a--; $b++; $c++; $d--; $i++; } } echo 'precision==> '.$save.'<br><br>'; $savee = bcsub(1,$save,$precision); echo '1-precision==> '.$savee.'<br><br>'; if($minor<0||$maxor>$selected){ echo 'p value==>margin larger surronding probabilties select smaller margin calculate p value'; } elseif($minor>0){ echo 'p value==>'.$ioioio; } else{ $ioioiop=bcadd($ioioio,$origzero,$precision); echo 'p value(0included)==> '.$ioioiop;} } ?>
dear @shukshin.ivan many response looking : ] example of how works else how might have same question:
$x=950000; $x =2*$x+1; $p=pi(); $x =(log(2.0*$p)+log($x/2.0)*$x-$x-(1.0-7.0/(30.0*$x*$x))/(6.0*$x))/2.0; $x=$x/log(10); $ex=floor($x); $x=pow(10,$x-$ex); $res=$x.'a'; $res=substr($x,0,6).'e'.$ex; echo $res;
you can use stirlings approximation. rather precise on large numbers. meaning factorial can calculated approximate
a set of other algorithms can found here.
Comments
Post a Comment