Here's a program that I am trying to run for Potts Model. It gives the plot once and then keeps repeating the line <Figure size 432x288 with 0 Axes>. What's the solution to get various plots after certain time steps showing the evolution of the system?
import math
import numpy as np
import matplotlib.pyplot as plt
def largest_primes_under(N):
n = N - 1
while n >= 2:
if all(n % d for d in range(2, int(n ** 0.5 + 1))):
return n
n -= 1
def Neighbors(Lattice,i,j,n=1):
''' Returns an flat array of all neighboring sites in the n-th coordination sphere including the center'''
N, M = Lattice.shape
rows = [(i-1) % N, i, (i+1) % N]
cols = [(j-1) % N, j, (j+1) % M]
return Lattice[rows][:, cols].flatten()
def calc_dE(Lattice, x, y, z):
N, M = Lattice.shape
old_energy = 0
new_energy = 0
for i in [0,1,-1]:
for j in [0,1,-1]:
if i == 0 and j == 0:
continue
if Lattice[x%N,y%M] == Lattice[(x+i)%N,(y+j)%M]:
old_energy += 1
elif z == Lattice[(x+i)%N,(y+j)%M]:
new_energy += 1
return old_energy-new_energy
N, M = 100,100
orientations = 3
MCS = int(10)
a = largest_primes_under(N*M)
L = np.random.randint(1,orientations+1,size=(N,M))
mat = plt.matshow(L,cmap = plt.get_cmap('plasma', orientations+1), vmin = -0.5, vmax = orientations+0.5, interpolation='kaiser')
plt.axis('off')
for t in range(1,MCS+1):
rand = np.random.random_integers(N*M)
for i in range(0,N**2):
index = (a*i + rand) % (N**2)
x = index % N
y = index // N
n = Neighbors(L,x,y)
if len(n)-1 == 0:
continue
else:
z = np.random.choice(n)
dE = calc_dE(L,x,y,z)
if (dE < 0):
L[x%N,y%N] = z
elif np.random.sample() < math.exp(-dE*2.5):
L[x%N,y%N] = z
mat.set_data(L)
plt.draw()
plt.pause(0.1)
mat.set_data(L) is not updating the data
In the for-loop, replace mat.set_data(L) with:
mat = plt.matshow(L, cmap = plt.get_cmap('plasma', orientations+1), vmin = -0.5, vmax = orientations+0.5, interpolation='kaiser')
The plots successfully showed up when I tested the code with the change.
Also np.random.random_integers(N*M) is deprecated in numpy v1.20.1. In the code below, np.random.randint(N*M) is used, but this change isn't related to the question in the OP.
for t in range(1, MCS+1):
rand = np.random.randint(N*M)
for i in range(0, N**2):
index = (a*i + rand) % (N**2)
x = index % N
y = index // N
n = Neighbors(L, x, y)
if len(n)-1 == 0:
continue
else:
z = np.random.choice(n)
dE = calc_dE(L, x, y, z)
if (dE < 0):
L[x%N, y%N] = z
elif np.random.sample() < math.exp(-dE*2.5):
L[x%N, y%N] = z
mat = plt.matshow(L, cmap = plt.get_cmap('plasma', orientations+1), vmin = -0.5, vmax = orientations+0.5, interpolation='kaiser')
# mat.set_data(L)
plt.draw()
plt.pause(0.1)
Alternative
In this case it might be more interesting to animate the progression
Implemented with Animate quadratic grid changes (matshow)
In the following code, save_count=MCS takes the place of the original outer loop for t in range(1, MCS+1), where t was just a throwaway variable.
import matplotlib.animation as animation
def generate_data():
rand = np.random.randint(N*M)
for i in range(0, N**2):
index = (a*i + rand) % (N**2)
x = index % N
y = index // N
n = Neighbors(L, x, y)
if len(n)-1 == 0:
continue
else:
z = np.random.choice(n)
dE = calc_dE(L, x, y, z)
if (dE < 0):
L[x%N, y%N] = z
elif np.random.sample() < math.exp(-dE*2.5):
L[x%N, y%N] = z
return L
def update(data):
mat.set_data(data)
return mat
def data_gen():
while True:
yield generate_data()
N, M = 100, 100
orientations = 3
MCS = 10
a = largest_primes_under(N*M)
L = np.random.randint(1, orientations+1, size=(N, M))
fig, ax = plt.subplots()
mat = ax.matshow(generate_data(), cmap=plt.get_cmap('plasma', orientations+1), vmin=-0.5, vmax=orientations+0.5, interpolation='kaiser')
plt.colorbar(mat)
ani = animation.FuncAnimation(fig, update, data_gen, interval=500, save_count=MCS)
plt.show()
ani.save('animation.gif')
Related
I'm trying to implement Buddhabrot fractal in Python. I read a lot of articles and posts but I think that I missunderstood something (just see the image). Someone can write a pseudocode?
My code is this:
from multiprocessing import Pool
from random import randrange
import matplotlib.pyplot as plt
import numpy as np
from math import ceil
maxiter = 1000
points = 1000
xmin, xmax = -2, 1
ymin, ymax = -2, 1
cores = 4
width, height = 200, 200
maxn = width * height
incrx, incry = abs(xmax - xmin) / width, abs(ymax - ymin) / height
def randomComplexGenerator():
for i in range(points):
n = randrange(maxn)
yield complex(n // height * incrx, n % width * incry)
def buddhabrot(c):
m, z, i = np.zeros((width, height)), c, 0
while i < maxiter and abs(z) < 2:
x, y = ceil(z.real / incrx), ceil(z.imag / incry)
m[x, y] += 1
z = z ** 2 + c
i += 1
return m if i == maxiter else 0
if __name__ == '__main__':
a = np.linspace(xmin, xmax, width)
b = np.linspace(ymin, ymax, height)
with Pool(cores) as p:
ms = p.map(buddhabrot, (c for c in randomComplexGenerator()))
res = 0
for m in ms:
res += m
plt.axis('off')
plt.imshow(res)
plt.show()
The image generated with my code is this (lel):
After days, this is the code that I created, which seems to generate appropriately the fractal. Any performance suggestion is welcome.
from multiprocessing import Pool
from random import randrange
import matplotlib.pyplot as plt
import numpy as np
cores = 4
maxiter = 10000
points = 1000000
width, height = 200, 200
rdom, idom = (-2, 2), (-2, 2)
xdom, ydom = (0, width - 1), (0, height - 1)
def randomComplex():
r = np.interp(randrange(xdom[0], xdom[1]), xdom, rdom)
i = np.interp(randrange(ydom[0], ydom[1]), ydom, idom)
return (r, i)
def complex2pixel(c):
x = int(np.interp(c[0], rdom, xdom))
y = int(np.interp(c[1], idom, ydom))
return (x, y)
def escapedPixels(c):
pixels, z = {}, c
for i in range(maxiter):
z2 = (z[0] * z[0], z[1] * z[1])
if z2[0] + z2[1] > 4: break
p = complex2pixel(z)
try: pixels[p] += 1
except: pixels[p] = 1
z = (z2[0] - z2[1] + c[0], 2 * z[0] * z[1] + c[1])
return pixels if i < maxiter - 1 else {}
if __name__ == '__main__':
with Pool(cores) as p:
ds = p.map(escapedPixels, (randomComplex() for i in range(points)))
m = np.zeros((width, height))
for d in ds:
for p in d:
m[p] += d[p]
plt.axis('off')
plt.imshow(m)
plt.show()
import urllib.request
from math import sqrt, fabs, exp
import matplotlib.pyplot as plot
from sklearn.linear_model import enet_path
from sklearn.metrics import roc_auc_score, roc_curve
import numpy
target_url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/undocumented/connectionist-bench/sonar/sonar.all-data'
data = urllib.request.urlopen(target_url)
xList = []
for line in data:
#split on comma
row = line.strip().split(",".encode(encoding='utf-8'))
xList.append(row)
xNum = []
labels = []
for row in xList:
lastCol = row.pop()
if lastCol == b'M':
labels.append(1.0)
else:
labels.append(0.0)
attrRow = [float(elt) for elt in row]
xNum.append(attrRow)
nrow = len(xNum)
ncol = len(xNum[1])
alpha = 1.0
xMeans = []
xSD = []
for i in range(ncol):
col = [xNum[j][i] for j in range(nrow)]
mean = sum(col)/nrow
xMeans.append(mean)
colDiff = [(xNum[j][i] - mean) for j in range(nrow)]
sumSq = sum([colDiff[i] * colDiff[i] for i in range(nrow)])
stdDev = sqrt(sumSq/nrow)
xSD.append(stdDev)
xNormalized = []
for i in range(nrow):
rowNormalized = [(xNum[i][j] - xMeans[j])/xSD[j] for j in range(ncol)]
xNormalized.append(rowNormalized)
meanLabel = sum(labels)/nrow
sdLabel = sqrt(sum([(labels[i] - meanLabel) * (labels[i] - meanLabel) for i in range (nrow)])/nrow)
labelNormalized = [(labels[i] - meanLabel)/sdLabel for i in range(nrow)]
nxval = 10
for ixval in range(nxval):
idxTest = [a for a in range (nrow) if a%nxval == ixval]
idxTrain = [a for a in range(nrow) if a%nxval != ixval]
xTrain = numpy.array([xNormalized[r] for r in idxTrain])
xTest = numpy.array([xNormalized[r] for r in idxTest])
labelTrain = numpy.array([labelNormalized[r] for r in idxTrain])
labelTest = numpy.array([labelNormalized[r] for r in idxTest])
alphas, coefs, _ = enet_path(xTrain, labelTrain, l1_ratio = 0.8, fit_intercept=False, return_models=False)
if ixval == 0:
pred = numpy.dot(xTest, coefs)
yOut = labelTest
else:
yTemp = numpy.array(yOut)
yOut = numpy.concatenate((yTemp, labelTest), axis = 0)
predTemp = numpy.array(pred)
pred = numpy.concatenate((predTemp, numpy.dot(xTest, coefs)), axis = 0)
misClassRate = []
_,nPred = pred.shape
for iPred in range(1, nPred):
predList = list(pred[:, iPred])
errCnt = 0.0
for irow in range(nrow):
if (predList[irow] < 0.0) and (yOut[irow] >= 0.0):
errCnt += 1.0
elif (predList[irow] >= 0.0) and (yOut[irow] < 0.0):
errCnt += 1.0
misClassRate.append(errCnt/nrow)
minError = min(misClassRate)
idxMin = misClassRate.index(minError)
plotAlphas = numpy.array(alphas[1:len(alphas)])
misClassRate_np = numpy.array(misClassRate)
plot.figure()
plot.plot(plotAlphas, misClassRate_np, label='Misclassification Error Across Folds', linewidth=2)
plot.axvline(plotAlphas[idxMin], linestyle='--', label='CV Estimate of Best alpha')
plot.legend()
plot.semilogx()
ax = plot.gca()
ax.invert_xaxis()
plot.xlabel('alpha')
plot.ylabel('Misclassification Error')
plot.axis('tight')
plot.show()
When I executed the code above, it returns: ValueError: x and y must have same first dimension, but have shapes (99,) and (1,).
It seems the problem is due to unequal length in x and y.
Then I checked both plotAlphas and misClassRate_np, they show the same length. Also, both of them has been changed to array but still fail to fix the problem. Can't figure out what's happening.
I have an improved kmeans algorithm (KPlusPlus) that builds on the class kmeans. Detk is another class inherited from KPlusPlus.
The objective of the KPlusPlus class is to find out the optimal seeding for finding the kmeans centroids (Source)
Detk calculates the gap statistic to find the optimal number of clusters. I have found this code from here
# kmeans class
class KMeans():
def __init__(self, K, X=None, N=0):
self.K = K
if X == None:
if N == 0:
raise Exception("If no data is provided, \
a parameter N (number of points) is needed")
else:
self.N = N
self.X = self._init_board_gauss(N, K)
else:
self.X = X
self.N = len(X)
self.mu = None
self.clusters = None
self.method = None
def _init_board_gauss(self, N, k):
n = float(N)/k
X = []
for i in range(k):
c = (random.uniform(-1,1), random.uniform(-1,1))
s = random.uniform(0.05,0.15)
x = []
while len(x) < n:
a,b = np.array([np.random.normal(c[0],s),np.random.normal(c[1],s)])
# Continue drawing points from the distribution in the range [-1,1]
if abs(a) and abs(b)<1:
x.append([a,b])
X.extend(x)
X = np.array(X)[:N]
return X
def plot_board(self):
X = self.X
fig = plt.figure(figsize=(5,5))
plt.xlim(-1,1)
plt.ylim(-1,1)
if self.mu and self.clusters:
mu = self.mu
clus = self.clusters
K = self.K
for m, clu in clus.items():
cs = cm.spectral(1.*m/self.K)
plt.plot(mu[m][0], mu[m][1], 'o', marker='*', \
markersize=12, color=cs)
plt.plot(zip(*clus[m])[0], zip(*clus[m])[1], '.', \
markersize=8, color=cs, alpha=0.5)
else:
plt.plot(zip(*X)[0], zip(*X)[1], '.', alpha=0.5)
if self.method == '++':
tit = 'K-means++'
else:
tit = 'K-means with random initialization'
pars = 'N=%s, K=%s' % (str(self.N), str(self.K))
plt.title('\n'.join([pars, tit]), fontsize=16)
plt.savefig('kpp_N%s_K%s.png' % (str(self.N), str(self.K)), \
bbox_inches='tight', dpi=200)
def _cluster_points(self):
mu = self.mu
clusters = {}
for x in self.X:
bestmukey = min([(i[0], np.linalg.norm(x-mu[i[0]])) \
for i in enumerate(mu)], key=lambda t:t[1])[0]
try:
clusters[bestmukey].append(x)
except KeyError:
clusters[bestmukey] = [x]
self.clusters = clusters
def _reevaluate_centers(self):
clusters = self.clusters
newmu = []
keys = sorted(self.clusters.keys())
for k in keys:
newmu.append(np.mean(clusters[k], axis = 0))
self.mu = newmu
def _has_converged(self):
K = len(self.oldmu)
return(set([tuple(a) for a in self.mu]) == \
set([tuple(a) for a in self.oldmu])\
and len(set([tuple(a) for a in self.mu])) == K)
def find_centers(self,K, method='random'):
self.method = method
X = self.X
K = self.K
self.oldmu = random.sample(X, K)
if method != '++':
# Initialize to K random centers
self.mu = random.sample(X, K)
while not self._has_converged():
self.oldmu = self.mu
# Assign all points in X to clusters
self._cluster_points()
# Reevaluate centers
self._reevaluate_centers()
The KPlusPlus class inherits from kmeans to find the optimal seeding
class KPlusPlus(KMeans):
def _dist_from_centers(self):
cent = self.mu
X = self.X
D2 = np.array([min([np.linalg.norm(x-c)**2 for c in cent]) for x in X])
self.D2 = D2
def _choose_next_center(self):
self.probs = self.D2/self.D2.sum()
self.cumprobs = self.probs.cumsum()
r = random.random()
ind = np.where(self.cumprobs >= r)[0][0]
return(self.X[ind])
def init_centers(self,K):
self.K = K
self.mu = random.sample(self.X, 1)
while len(self.mu) < self.K:
self._dist_from_centers()
self.mu.append(self._choose_next_center())
def plot_init_centers(self):
X = self.X
fig = plt.figure(figsize=(5,5))
plt.xlim(-1,1)
plt.ylim(-1,1)
plt.plot(zip(*X)[0], zip(*X)[1], '.', alpha=0.5)
plt.plot(zip(*self.mu)[0], zip(*self.mu)[1], 'ro')
plt.savefig('kpp_init_N%s_K%s.png' % (str(self.N),str(self.K)), \
bbox_inches='tight', dpi=200)
The class Detk inherits from KPlusPlus to find the optmal number of clusters based on gap statistic
class DetK(KPlusPlus):
def fK(self, thisk, Skm1=0):
X = self.X
Nd = len(X[0])
a = lambda k, Nd: 1 - 3/(4*Nd) if k == 2 else a(k-1, Nd) + (1-a(k-1, Nd))/6
self.find_centers(thisk, method='++')
mu, clusters = self.mu, self.clusters
Sk = sum([np.linalg.norm(mu[i]-c)**2 \
for i in range(thisk) for c in clusters[i]])
if thisk == 1:
fs = 1
elif Skm1 == 0:
fs = 1
else:
fs = Sk/(a(thisk,Nd)*Skm1)
return fs, Sk
def _bounding_box(self):
X = self.X
xmin, xmax = min(X,key=lambda a:a[0])[0], max(X,key=lambda a:a[0])[0]
ymin, ymax = min(X,key=lambda a:a[1])[1], max(X,key=lambda a:a[1])[1]
return (xmin,xmax), (ymin,ymax)
def gap(self, thisk):
X = self.X
(xmin,xmax), (ymin,ymax) = self._bounding_box()
self.init_centers(thisk)
self.find_centers(thisk, method='++')
mu, clusters = self.mu, self.clusters
Wk = np.log(sum([np.linalg.norm(mu[i]-c)**2/(2*len(c)) \
for i in range(thisk) for c in clusters[i]]))
# Create B reference datasets
B = 10
BWkbs = zeros(B)
for i in range(B):
Xb = []
for n in range(len(X)):
Xb.append([random.uniform(xmin,xmax), \
random.uniform(ymin,ymax)])
Xb = np.array(Xb)
kb = DetK(thisk, X=Xb)
kb.init_centers(thisk)
kb.find_centers(thisk, method='++')
ms, cs = kb.mu, kb.clusters
BWkbs[i] = np.log(sum([np.linalg.norm(ms[j]-c)**2/(2*len(c)) \
for j in range(thisk) for c in cs[j]]))
Wkb = sum(BWkbs)/B
sk = np.sqrt(sum((BWkbs-Wkb)**2)/float(B))*np.sqrt(1+1/B)
return Wk, Wkb, sk
def run(self, maxk, which='both'):
ks = range(1,maxk)
fs = zeros(len(ks))
Wks,Wkbs,sks = zeros(len(ks)+1),zeros(len(ks)+1),zeros(len(ks)+1)
# Special case K=1
self.init_centers(1)
if which == 'f':
fs[0], Sk = self.fK(1)
elif which == 'gap':
Wks[0], Wkbs[0], sks[0] = self.gap(1)
else:
fs[0], Sk = self.fK(1)
Wks[0], Wkbs[0], sks[0] = self.gap(1)
# Rest of Ks
for k in ks[1:]:
self.init_centers(k)
if which == 'f':
fs[k-1], Sk = self.fK(k, Skm1=Sk)
elif which == 'gap':
Wks[k-1], Wkbs[k-1], sks[k-1] = self.gap(k)
else:
fs[k-1], Sk = self.fK(k, Skm1=Sk)
Wks[k-1], Wkbs[k-1], sks[k-1] = self.gap(k)
if which == 'f':
self.fs = fs
elif which == 'gap':
G = []
for i in range(len(ks)):
G.append((Wkbs-Wks)[i] - ((Wkbs-Wks)[i+1]-sks[i+1]))
self.G = np.array(G)
else:
self.fs = fs
G = []
for i in range(len(ks)):
G.append((Wkbs-Wks)[i] - ((Wkbs-Wks)[i+1]-sks[i+1]))
self.G = np.array(G)
When I try to run the following program on a given number of points (locArray)
locArray = np.array(locArrayMaster[counter])
kmeanscluster = DetK(2, X = locArray)
kmeanscluster.run(5)
noClusters[counter] = np.where(kmeanscluster.fs == min(kmeanscluster.fs))[0][0]+ 1
it returns me the following error
File "C:\Users\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 714, in runfile
execfile(filename, namespace)
File "C:\Users\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)
File "C:/Users/Documents/SUMOTraffic/kplusplus.py", line 355, in <module>
kmeanscluster.run(5)
File "C:/Users/Documents/SUMOTraffic/kplusplus.py", line 217, in run
Wks[0], Wkbs[0], sks[0] = self.gap(1)
File "C:/Users/Documents/SUMOTraffic/kplusplus.py", line 200, in gap
for j in range(thisk) for c in cs[j]]))
TypeError: 'NoneType' object has no attribute '__getitem__'
Thanks for any help.
The error is due to the failure of the kmeans algorithm to find the cluster centres when the number of clusters is just 1. Hence the cluster dictionary is not created for this case. So, added an extra line of code in the class DetK which checks if the type of cluster dictionary is 'NoneType' and if it returns TRUE, recalculates the cluster centres again.
class DetK(KPlusPlus):
def fK(self, thisk, Skm1=0):
X = self.X
Nd = len(X[0])
a = lambda k, Nd: 1 - 3/(4*Nd) if k == 2 else a(k-1, Nd) + (1-a(k-1, Nd))/6
self.find_centers(thisk, method='++')
while type(self.clusters) is not dict:
self.find_centers(thisk, method = '++')
mu, clusters = self.mu, self.clusters
Sk = sum([np.linalg.norm(mu[i]-c)**2 \
for i in range(thisk) for c in clusters[i]])
if thisk == 1:
fs = 1
elif Skm1 == 0:
fs = 1
else:
fs = Sk/(a(thisk,Nd)*Skm1)
return fs, Sk
With the code below, I'm attempting to implement the Levy-Khintchine formula (https://en.wikipedia.org/wiki/L%C3%A9vy_process#L.C3.A9vy.E2.80.93Khintchine_representation). In the limit of no jumps, the Levy-Khitchine formula reduces to the multivariate normal distribution. My code uses the (multi-dimensional) trapeziodal integration rule (http://mathfaculty.fullerton.edu/mathews/n2003/SimpsonsRule2DMod.html) to approximate the Fourier transform of the characteristic function as a discrete Fourier transform. For the 1-dimensional case, the code works perfectly. For the 2-D case, I can't find what I'm doing wrong.
Does anyone have example numpy.fftn code that correctly implements multivariate_normal pdf?
class LevyKhintchine:
def __init__(self, mean, cov, jump_measure):
self.mean = mean
self.cov = cov
self.jump_measure = jump_measure
self.factors = mean.shape[0]
def logCF(self, k):
rolled = Roll(k)
out = np.empty(Shape(k))
return (self.jump_measure(k) -
Dot(rolled, self.cov, rolled, out)*0.5 +
np.sum(np.multiply(Roll(k), self.mean), axis=-1)*1j)
def pdf_grid(self, J):
diag = np.diagonal(self.cov)
tmp = np.pi*2/J
dk = np.sqrt(tmp/diag)
dx = np.sqrt(tmp*diag)
k = Grid(np.zeros(self.factors), dk, J)
x0 = self.mean - dx*J*0.5
f = np.exp(self.logCF(k) - Coef(dk, x0, J)*1j)
for n in range(self.factors):
f[ 0] *= 0.5
f[-1] *= 0.5
f = np.rollaxis(f, 0, factors)
pdf = np.fft.fftn(f)
return Grid(x0, dx, J), pdf.real*(np.product(dk)/np.pi)
def Grid(left, width, J):
def Slice(slices, j):
slices.append(slice(left[j], left[j] + width[j]*(J-1), 1j*J))
return slices
slices = reduce(Slice, range(len(left)), [])
return np.mgrid[slices]
def Shape(grid):
return np.asarray(grid).shape[1:]
def Roll(grid):
grid = np.asarray(grid)
try:
rolled = np.rollaxis(grid, 0, len(grid)+1)
except ValueError:
rolled = grid
return rolled
def Dot(x, cov, y, out): #x & y are "rolled"
for j in np.ndindex(out.shape):
out[j] = np.dot(x[j].T, np.dot(cov, y[j]))
return out
def Coef(dks, x0s, J):
factors = len(dks)
coef = np.zeros((J,)*factors)
for n, (dk, x0) in enumerate(zip(dks, x0s)):
shape = np.ones(factors, dtype=int)
shape[n] = J
coef += np.arange(J).reshape(shape)*(dk*x0)
return coef
Here's the tests:
from scipy.stats import multivariate_normal
J = 64
factors = 1
mean = np.full((factors,), -1)
cov = np.identity(factors)
rv = LevyKhintchine(mean, cov, lambda k: 0)
rv0 = multivariate_normal(mean, cov)
x, pdf = rv.pdf_grid(J)
plt.plot(x[0], pdf, x[0], rv0.pdf(Roll(x)))
factors = 2
mean = np.full((factors,), 5)
cov = np.identity(factors)
rv = LevyKhintchine(mean, cov, lambda k: 0)
x, pdf = rv.pdf_grid(J)
rv0 = multivariate_normal(mean, cov)
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.contourf(x[0], x[1], pdf)
fig3 = plt.figure()
ax3 = fig3.add_subplot(111)
ax3.contourf(x[0], x[1], rv0.pdf(Roll(x)))
I figured it out: in 1-d I can get away with integrating over only positive wave numbers k, in higher dimensions I cannot.
Here's the corrected code:
class LevyKhintchine:
def __init__(self, mean, cov, jump_measure):
self.mean = mean
self.cov = cov
self.jump_measure = jump_measure
self.factors = mean.shape[0]
def logCF(self, k):
rolled = Roll(k)
out = np.empty(Shape(k))
return (self.jump_measure(k) -
Dot(rolled, self.cov, rolled, out)*0.5 +
np.sum(np.multiply(Roll(k), self.mean), axis=-1)*1j)
def pdf_grid(self, J):
diag = np.diagonal(self.cov)
tmp = np.pi*2/J
dk = np.sqrt(tmp/diag)
dx = np.sqrt(tmp*diag)
k0 = -0.5*dk*J
x0 = -0.5*dx*J + self.mean
k = Grid(k0, dk, J)
x = Grid(x0, dx, J)
f = np.exp(-1j*Coef(dk, x0, J) + self.logCF(k))
for n in range(self.factors):
f[ 0] *= 0.5
f[-1] *= 0.5
f = np.rollaxis(f, 0, factors)
c = ((0.5/np.pi)**self.factors*np.product(dk)*np.exp(-1j*np.dot(k0, x0)))
pdf = np.fft.fftn(f)*np.exp(-1j*Coef(k0, dx, J))*c
return x, pdf.real
def Grid(left, width, J):
def Slice(slices, j):
slices.append(slice(left[j], left[j] + width[j]*(J-1), 1j*J))
return slices
slices = reduce(Slice, range(len(left)), [])
return np.mgrid[slices]
def Shape(grid):
return np.asarray(grid).shape[1:]
def Roll(grid):
grid = np.asarray(grid)
try:
rolled = np.rollaxis(grid, 0, len(grid)+1)
except ValueError:
rolled = grid
return rolled
def Dot(x, cov, y, out): #x & y are "rolled"
for j in np.ndindex(out.shape):
out[j] = np.dot(x[j].T, np.dot(cov, y[j]))
return out
def Coef(dks, x0s, J):
factors = len(dks)
coef = np.zeros((J,)*factors)
for n, (dk, x0) in enumerate(zip(dks, x0s)):
shape = np.ones(factors, dtype=int)
shape[n] = J
coef += np.arange(J).reshape(shape)*(dk*x0)
return coef
Here's the tests:
from scipy.stats import multivariate_normal
J = 32
for factors in range(1, 4):
mean = np.full((factors,), -1)
cov = np.identity(factors)
rv = LevyKhintchine(mean, cov, lambda k: 0)
rv0 = multivariate_normal(mean, cov)
x, pdf = rv.pdf_grid(J)
pdf0 = rv0.pdf(Roll(x))
print np.allclose(pdf, pdf0)
True
True
True
import math
import pylab as plt
import numpy
from numpy import sqrt
from scipy.integrate import quad
import random
numpy.seterr(divide='ignore', invalid='ignore')
def integrand (x):
return sqrt(1-x**2)
q1area, err = quad(integrand,0,1)
print "This program estimates the convergence of Pi to a ratio of one."
while True:
print "Please choose from one of the five following options:"
print " 1. 10^1\n 2. 10^2\n 3. 10^3\n"
choice = int(raw_input())
options = {1,2,3}
if choice == 1:
plt.xlim([0,15])
plt.ylim([-5,5])
x = numpy.linspace(0,15,500)
y = numpy.sqrt(1-x**2)
z = 1+x*0
xcord = []
ycord = []
under = []
above = []
pratiolist = []
yvalues = []
xvalues = range(1,11)
for i in range(10):
xcord.append(random.random())
ycord.append(random.random())
for j in ycord:
if (j <= q1area):
under.append(1)
else:
above.append(1)
punder = len(under)
if punder == 0:
punder = punder + 1
pabove = len(above)
if pabove == 0:
pabove = pabove + 1
pratio = punder / float(pabove)
pratiolist.append(pratio)
for k in pratiolist:
rtpi = k / float(math.pi)
yvalues.append(rtpi)
plt.scatter(xvalues,yvalues,c='b')
plt.plot(x,z,'g')
plt.show()
if choice == 2:
plt.xlim([0,110])
plt.ylim([-5,5])
x = numpy.linspace(0,110,500)
y = numpy.sqrt(1-x**2)
z = 1+x*0
xcord = []
ycord = []
under = []
above = []
pratiolist = []
yvalues = []
xvalues = range(1,101)
for i in range(100):
xcord.append(random.random())
ycord.append(random.random())
for j in ycord:
if (j <= q1area):
under.append(1)
else:
above.append(1)
punder = len(under)
if punder == 0:
punder = punder + 1
pabove = len(above)
if pabove == 0:
pabove = pabove + 1
pratio = punder / float(pabove)
pratiolist.append(pratio)
for k in pratiolist:
rtpi = k / float(math.pi)
yvalues.append(rtpi)
plt.scatter(xvalues,yvalues,c='b')
plt.plot(x,z,'g')
plt.show()
if choice == 3:
plt.xlim([0,1100])
plt.ylim([-5,5])
x = numpy.linspace(0,1100,500)
y = numpy.sqrt(1-x**2)
z = 1+x*0
xcord = []
ycord = []
under = []
above = []
pratiolist = []
yvalues = []
xvalues = range(1,1001)
for i in range(1000):
xcord.append(random.random())
ycord.append(random.random())
for j in ycord:
if (j <= q1area):
under.append(1)
else:
above.append(1)
punder = len(under)
if punder == 0:
punder = punder + 1
pabove = len(above)
if pabove == 0:
pabove = pabove + 1
pratio = punder / float(pabove)
pratiolist.append(pratio)
for k in pratiolist:
rtpi = k / float(math.pi)
yvalues.append(rtpi)
plt.scatter(xvalues,yvalues,c='b')
plt.plot(x,z,'g')
plt.show()
while choice not in options:
print "Not a valid choice!\n"
break
#plt.scatter(xvalues,yvalues,c='b')
#plt.plot(x,z,'g')
#plt.show()
The only way I can get the graphs to show is if I place break statements at the end of every if choice == 1,2,3, etc. and then place:
plt.scatter(xvalues,yvalues,c='b')
plt.plot(x,z,'g')
plt.show()
At the bottom of my code. This is inconvenient, I would like my to loop endlessly allowing choice between 1,2,3 without having to rerun the program. Why does Python's graphs crash when they are in whiles?
UPDATE
By using plt.draw(), I was able to get the graph to at least show but it still is not responding.
If by not responding you mean it doesn't show the prompt again this is because plt.show() will cause the program to stop until the window is closed. You can replace the plt.show()'s with plt.draw(), but to actually have windows come up you need to be in interactive mode. This is accomplished by calling plt.ion() sometime before any of the draw calls (I put it before the while True:). I've tested it an this should accomplish the behavior you're looking for.
Edit: Since you aren't redrawing the same data, calling draw() will append the data to the specific plot (i.e. typing 1 in over and over will keep adding points). I don't know what type of behavior you're looking for but you may want to call plt.clf before each scatter call if you want to clear the figure.