Related Articles

# Well Equidistributed Long-period Linear

• Last Updated : 19 Jul, 2019

Well Equidistributed Long-period Linear (WELL) is a pseudorandom number generator algorithm based on the technique of Linear Feedback Shift Register to create Pseudo-Random Numbers. It belongs to the family of Linear Congruential Generators. It is similar to a Mersenne twister in terms of functioning since both of them work using XOR, shifts and an LFSR mechanism. Both require a seed value to start off the process of generation.

Pseudorandom Number Generators refers to a class of algorithms that utilize an initial set of seed values and apply a variety of logical operations or shift operations to produce a seemingly random number. A generator can be defined recursively as follows:

Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning - Basic Level Course

```Xn+1 = (a*(Xn) + c) modulo-m

where X is a sequence of pseudorandom values,
m is the modulus (m>0),
a is the multiplier (0<a<m),
c is the increment ( 0<c<m),
and X0 is the seed ( 0<X0<m)
```

The algorithm is as follows:

```0.  Initialize the necessary seed values
1.  Utilize a state array of a defined length (here it is 32)
2.  Apply the necessary xor, shift and logical and operations to arrive at
the required parameters
3a. Update the current location value and output that value from an array
location multiplied with a scaling constant
3b. newV0 and newV1 are additional pseudorandom numbers that can be supplied
as per requirement
```

WELL algorithm can produce many numbers in a short time and is advantageous for applications that need many numbers. One of the major weakness that WELL suffers from is having a smaller state space. This can be changed by utilizing a larger size of state space with auxiliary space being traded off.

Python code implementation –

```# W stands for size of the digest, R is the size of the state
W = 32;R = 32
# Variables used for jumping to a particular state
M1 = 3;M2 = 24;M3 = 10

# can be changed to scale accordingly
FACT = 1.718

# value based right shift with xor operation
def mat0pos(t, v):
return(v^(v>>t))

# value based negative left shift with xor operation
def mat0neg(t, v):
return(v^(v<<(~t)))

# returns the value itself (identity function)
def identity(v):
return v

state = [None]*R

state_i = 0; z0 = None;z1 = None;z2 = None; newV1 = None; newV0 = None

# used to initialize the state of our digest based on argument provided
def InitWellRNG(arg):
global state
for j in range(0, len(arg)):
state[j]= arg[j]

# function that utilizes seed values and logical operations to
# output random numbers
def WELLRNG():
global state_i
global z0; global z1; global z2; global newV1; global newV0

z0 = state[(state_i + M1) & 0x001f]
z1 = identity(state[state_i]) ^ mat0pos(8, state[(state_i + M1) & 0x001f])
z2 = mat0neg(-19, state[(state_i + M2) & 0x001f]) ^ mat0neg(-14,
state[(state_i + M3) & 0x001f])

# newV1 and newV0 are additional random values that are produced
# and can be returned as per requirement
newV1 = z1 ^ z2;
newV0 = mat0neg(-11, z0) ^ mat0neg(-7, z1) ^ mat0neg(-13, z2)

state_i = (state_i + (W-1)) & 0x001f
return (state[state_i] *FACT)

# executed if this is the main file
if (__name__ == "__main__"):
print("WELL created\n")
# replace seed array with your own array to create different output
# sequence of random numbers
seed = [27, 10, 14, 27, 24, 4, 11, 25, 14, 13, 2, 20, 0, 22, 9, 24, 14, 9,
20, 14, 17, 6, 21, 10, 27, 8, 16, 5, 26, 21, 18, 29]
InitWellRNG(seed)
for i in range(0,5):
print("random number generated is {}".format(WELLRNG()))
```

Output :

```WELL created

random number generated is 49.822
random number generated is 30.924
random number generated is 36.078
random number generated is 44.668
random number generated is 8.59
```
My Personal Notes arrow_drop_up