Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Math::BigFloat bnok() question

by azheid (Sexton)
on Aug 27, 2015 at 18:15 UTC ( [id://1140241]=perlquestion: print w/replies, xml ) Need Help??

azheid has asked for the wisdom of the Perl Monks concerning the following question:

I have an issue that I think is probably a simple one. I do not know how to use Math::BigFloat::bnok(). I get the following error message "Can't call method "Math::BigInt::bnok" without a package or object reference at hexamer_rarity_codonusage.pl line 67."

Despite reading the Math::BigFloat page and extensive googling, the solution seems beyond my ability to comprehend. Please help. I will post the files that this code uses if necessary, just ask.

#!/usr/bin/perl use Getopt::Long; use Math::BigFloat; use Math::BigInt; my $codon_fname="codons.txt"; my $n_amer_fname="codon_pair.txt"; my $codon_usage_fname=""; my $mfactor=100; my $codon_usage_per=100; GetOptions( "c=s" => \$codon_usage_fname, ) or die ("Error in command line arguments\n"); open(CODON,'<',$codon_fname)||die "No $codon_fname file available\n"; my %codon_counts; while (my $line=<CODON>){ chomp $line; $codon_counts{$line}= 0 ; } close CODON; open(NAMER,'<',$n_amer_fname)||die "No $n_amer_fname file available\n" +; my @namer; while (my $line=<NAMER>){ chomp $line; push @namer, $line; } close NAMER; my %cd_lookup; open(CLT,'<',$codon_usage_fname)||die "Cannot find codon score lookup +table file $codon_usage_fname\n"; while(my $line=<CLT>){ chomp $line; my @array=split(/\t/,$line); $cd_lookup{$array[0]}=$array[1]; } close CLT; Math::BigFloat->accuracy(40); my $x=Math::BigFloat->new(40); my $y=Math::BigFloat->new(40); my $z=Math::BigFloat->new(40); my $d=Math::BigFloat->new(40); for(my $i=0;$i<@namer;++$i){ my $pvalue=0; my @choose_numerator_array; my %cchash=%codon_counts; for(my $j=0;$j<length($namer[$i])-2;++$j){ ++$cchash{substr($namer[$i],$j,3)}; } foreach my $codon(%cchash){ if($cchash{$codon}){ $x=$cchash{$codon}; $y=$cd_lookup{$codon}*$mfactor; $z=$y->Math::BigInt::bnok($x); push @choose_numerator_array,$z->copy(); } } $x=$choose_numerator_array[0]; for(my $j=1;$j<scalar(@choose_numerator_array);++$j){ $y=$choose_numerator_array[$j]; $x=$x*$y; } $y=$codon_usage_per*$mfactor; $z=scalar(@choose_numerator_array); $d=$y*$z; $x=$x/$d; print $namer[$i],"\t",$x,"\n"; }

If any future perl users want the answer to how I solved this problem, below is the functional code

#!/usr/bin/perl use Getopt::Long; use Math::BigFloat; use Math::BigInt; my $codon_fname="codons.txt"; my $n_amer_fname="codon_pair.txt"; my $codon_usage_fname=""; my $mfactor=100; my $codon_usage_per=100; GetOptions( "c=s" => \$codon_usage_fname, ) or die ("Error in command line arguments\n"); open(CODON,'<',$codon_fname)||die "No $codon_fname file available\n"; my %codon_counts; while (my $line=<CODON>){ chomp $line; $codon_counts{$line}= 0 ; } close CODON; open(NAMER,'<',$n_amer_fname)||die "No $n_amer_fname file available\n" +; my @namer; while (my $line=<NAMER>){ chomp $line; push @namer, $line; } close NAMER; my %cd_lookup; open(CLT,'<',$codon_usage_fname)||die "Cannot find codon score lookup +table file $codon_usage_fname\n"; while(my $line=<CLT>){ chomp $line; my @array=split(/\t/,$line); $cd_lookup{$array[0]}=$array[1]; } close CLT; use bignum; my $x,$y,$z,$a,$b,$c; #Math::BigFloat->accuracy(40); #$x=Math::BigInt->new($x); #$y=Math::BigInt->new($y); #$z=Math::BigInt->new($z); #$a=Math::BigFloat->new($a); #$b=Math::BigFloat->new($b); #$c=Math::BigFloat->new($c); for(my $i=0;$i<@namer;++$i){ my @choose_numerator_array; my %cchash=%codon_counts; my $count=0; for(my $j=0;$j<length($namer[$i])-2;++$j){ ++$cchash{substr($namer[$i],$j,3)}; ++$count; } foreach my $codon(%cchash){ if($cchash{$codon}){ $x=$cchash{$codon}; $y=$cd_lookup{$codon}*$mfactor; $z=binomial($y,$x); push @choose_numerator_array,$z->copy(); } } $b=$choose_numerator_array[0]; for(my $j=1;$j<scalar(@choose_numerator_array);++$j){ $a=$choose_numerator_array[$j]; $b=$b*$a; } $y=$codon_usage_per*$mfactor; $a=&binomial($y,$count); $c=$b/$a; print $namer[$i],"\t",$c,"\n"; } sub binomial { use bigint; my ($r, $n, $k) = (1, @_); for (1 .. $k) { $r *= $n--; $r /= $_ } $r; }

Replies are listed 'Best First'.
Re: Math::BigFloat bnok() question
by BrowserUk (Patriarch) on Aug 27, 2015 at 18:43 UTC

      That is the format I used first. The error message is the same whether I use

      $z = $y->bnok($x);

      or

      $z = $y->Math::BigFloat::bnok($x);

        This likely means that your $x and $y are not Math::BigFloat objects. Maybe you want to convert them to that?

        $x = Math::BigFloat->new( $x ); $y = Math::BigFloat->new( $y );

        But most likely, you have already lost some precision you likely wanted to keep. You should convert your numbers to BigFloats at the earliest possibility.

Re: Math::BigFloat bnok() question
by toolic (Bishop) on Aug 27, 2015 at 19:40 UTC
    I will post the files that this code uses if necessary
    It would be better to make your code independent of external files. Reduce your code to a small example that anyone can run to reproduce your error. What version of perl are you using?

    Tip #2 from the Basic debugging checklist: print

    print "$x\n"; print "$y\n";

      I am using perl 5.10.0. I was hoping the mistake was simple and easy for learned monks to figure out. I will try to make a simple example code.

        I will try to make a simple example code

        Here is a simple demo:
        use strict; use warnings; use Math::BigFloat; my $n = Math::BigFloat->new(7); my $k = 5; print $n->bnok($k), "\n"; # prints "21". my $n2 = 7; print $n2->bnok($k); # line 10
        It outputs:
        21 Can't call method "bnok" without a package or object reference at bnok +.pl line 10.
        No problem with the first bnok call, but the second fails because $n2 is not a Math::BigFloat object - and this supports the assertions already made by others in this thread.
        Apparently, $k doesn't need to be a Math::BigFloat object (though I think you'll find it can be).

        Cheers,
        Rob

        Unless I'm blind, I don't see you using use strict;use warnings; which may provide more enlightenment.

Re: Math::BigFloat bnok() question
by danaj (Friar) on Aug 28, 2015 at 04:36 UTC

    You can see how this is solved on RosettaCode by using (0+$n)->bnok($k) with the bigint pragma. In your case you might want Math::BigInt->new($y)->bnok($x) which will make sure the first argument is a proper object.

    Shameless plug: if you find performance is an issue, use ntheory and its binomial function. It is faster for small integers, and also for large values if you have GMP on your system. It will return results as Math::BigInt if they're large. Worst case it falls back to Math::BigInt's bnok if the result is >64-bit and you don't have the GMP library.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1140241]
Approved by toolic
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-26 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found