Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I had to first rewrite your code before I could understand it:</p> <pre><code>def OW60(sign=1): r1 = random.randint (1, 30) r2 = random.randint (1, 30) val = sign * (r1 + r2) islow = (r1&lt;=5) + (r2&lt;=5) ishigh = (r1&gt;=26) + (r2&gt;=26) if islow == 2 or ishigh == 2: return val + OW60(1) elif islow == 1 and ishigh == 1: return val + OW60(-1) else: return val </code></pre> <p>Maybe you might find this less readable; I don't know. (Do check if it is equivalent to what you had in mind.) Also, regarding the way you use "result" in your code -- do you know of Python's <a href="http://www.diveintopython.org/getting_to_know_python/dictionaries.html" rel="nofollow noreferrer">dict</a>s?</p> <p>Anyway, matters of programming style aside: Suppose F(x) is the <a href="http://en.wikipedia.org/wiki/Cumulative_distribution_function" rel="nofollow noreferrer">CDF</a> of OW60(1), i.e. </p> <pre><code>F(x) = the probability that OW60(1) returns a value ≤ x. </code></pre> <p>Similarly let </p> <pre><code>G(x) = the probability that OW60(-1) returns a value ≤ x. </code></pre> <p>Then you can calculate F(x) from the definition, by summing over all (30&times;30) possible values of the result of the first throw. For instance, if the first throw is (2,3) then you'll roll again, so this term contributes (1/30)(1/30)(5+F(x-5)) to the expression for F(x). So you'll get some obscenely long expression like</p> <pre><code>F(x) = (1/900)(2+F(x-2) + 3+F(x-3) + ... + 59+F(x-59) + 60+F(x-60)) </code></pre> <p>which is a sum over 900 terms, one for each pair (a,b) in [30]&times;[30]. The pairs (a,b) with both ≤ 5 or both ≥26 have a term a+b+F(x-a-b), the pairs with one ≤5 and one ≥26 have a term a+b+G(x-a-b), and the rest have a term like (a+b), because you don't throw again.</p> <p>Similarly you have </p> <pre><code>G(x) = (1/900)(-2+F(x-2) + (-3)+F(x-3) + ... + (-59)+F(x-59) + (-60)+F(x-60)) </code></pre> <p>Of course, you can collect coefficients; the only F terms that occur are from F(x-60) to F(x-52) and from F(x-10) to F(x-2) (for a,b≥26 or both≤5), and the only G terms that occur are from G(x-35) to G(x-27) (for one of a,b≥26 and the other ≤5), so there are fewer terms than 30 terms. In any case, defining the vector V(x) as </p> <pre><code>V(x) = [F(x-60) G(x-60) ... F(x-2) G(x-2) F(x-1) G(x-1) F(x) G(x)] </code></pre> <p>(say), you have (from those expressions for F and G) a relation of the form </p> <pre><code>V(x) = A*V(x-1) + B </code></pre> <p>for an appropriate matrix A and an appropriate vector B (which you can calculate), so starting from initial values of the form V(x) = [0 0] for x sufficiently small, you can find F(x) and G(x) for x in the range you want to arbitrarily close precision. (And your f(x), the probability of throwing x, is just F(x)-F(x-1), so that comes out as well.)</p> <p>There might be a better way. All said and done, though, why are you doing this? Whatever kind of distribution you want, there are nice and simple probability distributions, with the appropriate parameters, that have good properties (e.g. small variance, one-sided errors, whatever). There is no reason to make up your own ad-hoc procedure to generate random numbers.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload