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

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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."
  • Comment on Re^7: Boolean math: Fill in the blanks.

Replies are listed 'Best First'.
Re^8: Boolean math: Fill in the blanks.
by gone2015 (Deacon) on Oct 12, 2008 at 22:24 UTC

    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 :-(