Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^6: Boolean math: Fill in the blanks.

by jdalbec (Deacon)
on Oct 11, 2008 at 13:53 UTC ( [id://716604]=note: print w/replies, xml ) Need Help??


in reply to Re^5: Boolean math: Fill in the blanks.
in thread Boolean math: Fill in the blanks.

I wonder if you're not making this too complicated. If I'm not mistaken,
E(X & R) = E(X)/2 E(X | R) = (E(X)+1)/2
so it should be possible to build the expression from the binary expansion of the desired probability:
#! /usr/bin/perl use strict; use warnings; my $bits = shift; my $den = 2**$bits; foreach my $num (1 .. $den-1) { my $str = sprintf "%0${bits}b", $num; $str =~ s/0*$//; my $len = length $str; $str =~ s/0/R & (/g; $str =~ s/1/R | (/g; $str .= ")" x $len; $str =~ s/ \| \(\)//; $str =~ s/\(R\)/R/; print "E($num/$den) = $str\n"; }
The output has more parentheses than strictly necessary, but odds are there's a CPAN module that can fix that.
E(1/32) = R & (R & (R & (R & R))) E(2/32) = R & (R & (R & R)) E(3/32) = R & (R & (R & (R | R))) E(4/32) = R & (R & R) E(5/32) = R & (R & (R | (R & R))) E(6/32) = R & (R & (R | R)) E(7/32) = R & (R & (R | (R | R))) E(8/32) = R & R E(9/32) = R & (R | (R & (R & R))) E(10/32) = R & (R | (R & R)) E(11/32) = R & (R | (R & (R | R))) E(12/32) = R & (R | R) E(13/32) = R & (R | (R | (R & R))) E(14/32) = R & (R | (R | R)) E(15/32) = R & (R | (R | (R | R))) E(16/32) = R E(17/32) = R | (R & (R & (R & R))) E(18/32) = R | (R & (R & R)) E(19/32) = R | (R & (R & (R | R))) E(20/32) = R | (R & R) E(21/32) = R | (R & (R | (R & R))) E(22/32) = R | (R & (R | R)) E(23/32) = R | (R & (R | (R | R))) E(24/32) = R | R E(25/32) = R | (R | (R & (R & R))) E(26/32) = R | (R | (R & R)) E(27/32) = R | (R | (R & (R | R))) E(28/32) = R | (R | R) E(29/32) = R | (R | (R | (R & R))) E(30/32) = R | (R | (R | R)) E(31/32) = R | (R | (R | (R | R)))

Replies are listed 'Best First'.
Re^7: Boolean math: Fill in the blanks.
by ikegami (Patriarch) on Oct 11, 2008 at 14:57 UTC

    The output has more parentheses than strictly necessary

    Don't add parens within runs of | and runs of &, just around them.

    #!/usr/bin/perl use strict; use warnings; my $bits = shift; my $den = 2**$bits; for my $num (1 .. $den-1) { for ( sprintf "%0${bits}b", $num ) { s/10*$/R/; $_ .= ')' x s/(?<=1)(?=0)|(?<=0)(?=1)/(/g; s/0/R & /g; s/1/R | /g; print "E($num/$den) = $_\n"; } }
    E(1/32) = R & R & R & R & R E(2/32) = R & R & R & R E(3/32) = R & R & R & (R | R) E(4/32) = R & R & R E(5/32) = R & R & (R | (R & R)) E(6/32) = R & R & (R | R) E(7/32) = R & R & (R | R | R) E(8/32) = R & R E(9/32) = R & (R | (R & R & R)) E(10/32) = R & (R | (R & R)) E(11/32) = R & (R | (R & (R | R))) E(12/32) = R & (R | R) E(13/32) = R & (R | R | (R & R)) E(14/32) = R & (R | R | R) E(15/32) = R & (R | R | R | R) E(16/32) = R E(17/32) = R | (R & R & R & R) E(18/32) = R | (R & R & R) E(19/32) = R | (R & R & (R | R)) E(20/32) = R | (R & R) E(21/32) = R | (R & (R | (R & R))) E(22/32) = R | (R & (R | R)) E(23/32) = R | (R & (R | R | R)) E(24/32) = R | R E(25/32) = R | R | (R & R & R) E(26/32) = R | R | (R & R) E(27/32) = R | R | (R & (R | R)) E(28/32) = R | R | R E(29/32) = R | R | R | (R & R) E(30/32) = R | R | R | R E(31/32) = R | R | R | R | R

    More parens can be removed since | and & don't have the same precedence, but I think that would make it hard to read.

    Update: I originally had this longer code:

Re^7: Boolean math: Fill in the blanks.
by pjotrik (Friar) on Oct 11, 2008 at 14:35 UTC
    Looks like you're right. The formulas are a nice application of those given by psini, and the pattern is much better visible here. Elegant solution!
Re^7: Boolean math: Fill in the blanks.
by BrowserUk (Patriarch) on Oct 11, 2008 at 15:36 UTC

    This just gets better and better! I was heading in this direction, but hadn't got there yet++

    The really nice thing about this analysis is that I no longer have to produce the entire sequence for any given depth. Once I have chosen the optimum depth (denominator) and fraction (enumerator) to meet the required ratio, and reduced it to its lowest form, I can just construct a sub to produce my initialisers.

    That works out to be very efficient.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Now that brother jdalbec has shown us the way...

      ...I observe that the values can be calculated directly from the bit pattern -- right shifting trailing zeros off, and then oring/anding new R's for each '1'/'0', shifting right until have shifted at total of 'n' times, where the denominator is 2**n.

      This leads to a minor variation on the theme of constructing a Perl expression to do this. Which takes the bits in reverse order. Taken in this order, the operations want to be executed left to right, so only need to add brackets to cope with the higher precedence of &.

      Taken in the forward order brackets are required to ensure that where there is a mix of operations, those at the back end of the expression are done first. This may, or may not, be obvious. (Though within groups of things ored together the order is irrelevant, and similarly groups of things anded together.)

      I don't know if this is any simpler, but I wrote it and got it working, so here you are...

      FWIW, on my machine (64bit modest Semperon) I benchmarked the code to create values directly from the bit-pattern against an anonymous subroutine built by eval. The subroutine was faster, but only by 75% -- so I guess the running time is dominated by rand. I was using a denominator of 2**33, which mapped a probability of 0.1 to:

        sub { ((((((((R | R) & R & R | R | R) & R & R | R | R) & R & R | R | R)
            & R & R | R | R) & R & R | R | R) & R & R | R | R) & R & R | R | R) & R & R & R }
      
      Easy when you know how :-)

      In passing, I discovered that the built-in rand wasn't up to much on my 32-bit machine :-(

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://716604]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2024-04-16 05:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found