M.liza
M.liza

Reputation: 115

Combined linear congruential generator

I am trying to generate 10 pseudorandom number by using "combined linear congruential generator". Necessary steps for "combined linear congruential generator" are as follows:

enter image description here

So for my code for above-mentioned steps are as follows:

import random as rnd

def combined_linear_cong(n = 10):

    R = []

    m1 = 2147483563
    a1 = 40014
    m2 = 2147483399
    a2 = 40692

    Y1 = rnd.randint(1, m1 - 1)
    Y2 = rnd.randint(1, m2 - 1)

    for i in range (1, n):

        Y1 = a1 * Y1 % m1
        Y2 = a2 * Y2 % m2

        X = (Y1 - Y2) % (m1 - 1)

        if (X > 0):
           R[i] = (X / m1)
        elif (X < 0):
           R[i] = (X / m1) + 1
        elif (X == 0):
           R[i] = (m1 - 1) / m1

    return (R)

But my code is not working properly. I am new in Python. It would be really great if someone helps me to fix the code. Or give me some guidance so that I can fix it.

Upvotes: 2

Views: 1484

Answers (1)

Grismar
Grismar

Reputation: 31329

There is a number of problems with the script:

  1. You are assigning values to r[i], but the list is empty at that point; you should initialise it to be able to write values to it like that; (for example) r = [0.0] * n
  2. You are returning r in parentheses, perhaps because you expect a tuple as a result? If so, return tuple(r), otherwise you can leave the parentheses off and just return r
  3. The description suggests that x[i+1] should be (y[i+1,1] - y[i+1,2]) mod m1, but you're doing X = (Y1 - Y2) % (m1 - 1), this may be a mistake, but I don't know the algorithm well enough to be able to tell which is correct.
  4. Not an error, but it makes it harder to find the errors inbetween the warnings: you don't follow Python naming conventions; you should use lower case for variable names and could clean up the spacing a bit.

With all of that addressed, I think this is a correct implementation:

import random as rnd


def combined_linear_cong(n = 10):
    r = [0.0] * n

    m1 = 2147483563
    a1 = 40014
    m2 = 2147483399
    a2 = 40692

    y1 = rnd.randint(1, m1 - 1)
    y2 = rnd.randint(1, m2 - 1)

    for i in range(1, n):

        y1 = a1 * y1 % m1
        y2 = a2 * y2 % m2

        x = (y1 - y2) % m1

        if x > 0:
            r[i] = (x / m1)
        elif x < 0:
            r[i] = (x / m1) + 1
        elif x == 0:
            r[i] = (m1 - 1) / m1

    return r


print(combined_linear_cong())

Note: the elif x == 0: is superfluous, you can just as well write else: since at that point, x cannot be anything but 0.

Upvotes: 1

Related Questions