Workout the first the cumulats C1, C2, C3
Evaluate the first three cumulants for a Gaussian distribution
If y⃗ (x⃗ )=(y1(x1,x2),y2(x1,x2)) is a coordinate transformation, what is the area of a differential element dx1dx2 after it is mapped into the y⃗ plane? Recall that the area of a parallelogram is equal to the length of its base times its height.
Write a uniform random number generator, and transform it by equation (6.78). Numerically evaluate the first three cumulants of its output.
For an order 4 maximal LFSR write down the bit sequence.
from IPython.display import Image
Image("NMM_random_LFSR1.png")
There was a mistake above so here is the second attempt
from IPython.display import Image
Image("NMM_random_LFSR2.png")
This looks a bit better let's check if it actually is that way
### check the handwritten list
prevX = [1, 1, 1, 1]
x = 0
bits = []
while (1):
x = (prevX[0] + prevX[3]) % 2
bits.append([x] + prevX)
prevX.pop()
prevX.insert(0,x)
if prevX == [1, 1, 1, 1]:
break
bits.append(bits[0])
print("Bit sequence of order 4 maximal LFSR")
print(bits)
Solution by hand seems to be ok in comparison with the python version.
If an LFSR has a clock rate of 1 GHz, how long must the register be for the time between repeats to be the age of the universe (∼ 10^10 years)?
from IPython.display import Image
Image("NMM_random_LFSR3.png")
Length of the register should be 89 since 88.027 slightly larger than 88.
Use a Fourier transform to solve the diffusion equation (6.57) (assume that the initial condition is a normalized delta function at the origin).
What is the variance as a function of time?
How is the diffusion coefficient for Brownian motion related to the viscosity of a fluid?
Write a program (including the random number generator) to plot the position as a function of time of a random walker in 1D that at each time step has an equal probability of making a step of ± 1. Plot an ensemble of 10 trajectories, each 1000 points long, and overlay error bars of width 3σ(t) on the plot.
import matplotlib.pyplot as plt
import numpy as np
import itertools
#probability to decide which way to "walk"
p = .50
numTra = 10
numSteps = 1000
xpos = []
pos = 0
# numpy random for reference in the plot
for num in range(1000):
if np.random.uniform(0,1) < p : pos = pos+1
else : pos = pos-1
xpos.append(pos)
# generate next position to walk either +1 or -1 based
# used figures from 6.74)
def rng(x):
return ((8121 * x) + 28411) % 134456
def rngWalk(n, Xn):
c = 0
d = 0
time = [c]
position = [d]
for i in range (1, n+1):
Xn = rng(Xn)
if Xn/134456 < p:
c += 1
d += 1
else:
c += 1
d += -1
time.append(c)
position.append(d)
return [time, position]
# generate next position to walk either +1 or -1 based based on bit LFSR
def walk(n):
a = 0
b = 0
time = [a]
position = [b]
for i in range (1, n+1):
num = lfsr(201, (8,7,6,1))
nX = next(itertools.islice(num,1))
if n < p:
a += 1
b += 1
else:
a += 1
b += -1
time.append(a)
position.append(b)
print(nX)
return [time, position]
def np_walk(n):
a = 0
b = 0
time = [a]
position = [b]
for i in range (1, n+1):
# replace with own Random function
if np.random.uniform(0,1) < p:
a += 1
b += 1
else:
a += 1
b += -1
time.append(a)
position.append(b)
return [time, position]
# attempt to write LFSR with bit operators - not working as of yet
def lfsr(seed, taps):
sr = seed
nbits = 8
while 1:
xor = 1
for t in taps:
if (sr & (1<<(t-1))) != 0:
xor ^= 1
sr = (xor << nbits-1) + (sr >> 1)
yield xor, sr
if sr == seed:
break
nbits = 8
# create 10 Trajectories
trajectories = [[] for _ in range(numTra)]
for i in range(len(trajectories)):
# got to give each trajectory a different starting number hence i is inserted as well
trajectories[i] = rngWalk(numSteps, i)
# direct bit manipulation doesn't work yet
#trajectories[i] = walk(numSteps)
# plot all the fun
# plot "styling"
fig = plt.figure(figsize = (18,8))
ax = fig.subplots_adjust(top=0.8)
ax = fig.add_subplot(111)
ax.set_ylabel('distance')
ax.set_xlabel('time')
ax.axhline(y=0, color='k', alpha=0.2)
lAlpha = 0.7
# plot data
ax.plot(xpos, color = 'k', alpha=0.6, label = "Numpy")
for i in range(len(trajectories)):
ax.plot(trajectories[i][0],trajectories[i][1], alpha=lAlpha, label = i+1)
# Errorbars
error1 = 1.5*np.sqrt(np.arange(0.,1000.))
error3 = 3*np.sqrt(np.arange(0.,1000.))
ax.fill_between(np.arange(0.,1000.), error1, -error1, color= 'grey', alpha = '0.3')
ax.fill_between(np.arange(0.,1000.), error3, -error3, color= 'orange', alpha = '0.1')
# errorbars need more work
# Labels and Legend
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
ax.legend(loc='best', bbox_to_anchor = (1.1,0.45), frameon= False)
plt.show()