Related
I am trying to implement a pso algorithm from Wikipedia https://en.wikipedia.org/wiki/Particle_swarm_optimization.
My problem is that when I am calling the cost function with a variable (Gbest), and then manually calling the cost function (with the Gbest data) I get a different output (cost) like the image bellow:
Code fault
I am new to python so thank you for any suggestions.
Here is the complete code:
import matplotlib.pyplot as plt
import numpy as np
from control.matlab import *
A = np.array([[0,0,1],[0,1,0],[1,2,-2]])
B = np.array( [[0],[1],[0]])
C = np.array([[0, 1,0]])
D = np.zeros([C.shape[0],B.shape[1]])
sys = ss(A,B,C,D)
sys_tf = tf(sys)
s = tf('s')
def cost(kp,ki):
global sys_tf, G, y, t, r
G = kp + ki/s
C = feedback(sys_tf*G, 1)
y, t = step(C, linspace(0,100))
r = np.ones(len(t))
return np.sum(y-r)**2
part = 100
ite = 10000
dim = 2
w = 0.001
wdamp = 0.99
phip = 0.9
phig = 0.1
blo, bup = -10,10
x = np.zeros([dim, part])
v = np.zeros([dim, part])
pbest = np.zeros([dim, part])
gbest = np.array([1000000,1000000])
for i in range(part):
for k in range(dim):
x[k][i] = pbest[k][i] = np.random.uniform(blo, bup)
v[k][i] = np.random.uniform(-np.abs(bup - blo), np.abs(bup - blo))
if cost(pbest[0][i], pbest[1][i]) < cost(gbest[0], gbest[1]):
gbest = np.array([pbest[0][i], pbest[1][i]])
for it in range(ite):
for i in range(part):
for k in range(dim):
rp = np.random.uniform(0,1)
rg = np.random.uniform(0,1)
v[k,:] = w*v[k,:] + phip*rp*(pbest[k,:] - x[k,:]) + phig*rg*(gbest[k] - x[k,:])
x[k,:] = x[k,:] + v[k,:]
w = w*wdamp
if cost(x[0][i], x[1][i]) < cost(pbest[0][i], pbest[1][i]):
pbest[:,i] = x[:,i]
if cost(pbest[0][i], pbest[1][i]) < cost(gbest[0], gbest[1]):
gbest = np.array([pbest[0][i], pbest[1][i]])
plt.plot(t, y, 'ro')
plt.plot(t, r, 'x')
plt.pause(0.005)
plt.title(gbest)
print([gbest, cost(gbest[0], gbest[1])])
I'm trying to import these on Jupyter, however I got an error when I run these code that say ModuleNotFoundError: No module named 'anna_phog'. I have another python file named as 'anna_phog'. How do I fix this?
below is 'anna_phog_demo.py' where I got the error
from anna_phog import anna_phog
import imageio
import matplotlib.pyplot as plt
image_path = "image_0058.jpg"
S = 8
angle = 360
Level = 3
roi = [1,225,1,300]
save=True
Image = imageio.imread(image_path)
p = anna_phog(Image, bin, angle, Level, roi)
print("P: \n{}".format(p))
print(len(p), type(p))
And below is the 'anna_phog.py' code
import numpy as np
import imageio
import cv2
import matplotlib.pyplot as plt
def anna_phog(Img, bin, angle, L, roi):
if Img.shape[2] == 3:
G = cv2.cvtColor(Img, cv2.COLOR_BGR2GRAY)
else:
G = Img
if np.sum(G) > 100:
# apply automatic Canny edge detection using the computed median
sigma = 0.33
v = np.median(G)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
E = cv2.Canny(G,lower,upper) #high and low treshold
GradientX, GradientY = np.gradient(G)
GradientYY = np.gradient(GradientY, axis=1)
Gr = np.sqrt(np.square(GradientX)+np.square(GradientY))
index = GradientX == 0
GradientX[index] = 1e-5 #maybe another value
YX = GradientY*GradientX
if angle == 180: A = ((np.arctan(YX)+(np.pi/2))*180)/np.pi
if angle == 360: A = ((np.arctan2(GradientY,GradientX)+np.pi)*180)/np.pi
bh, bv = anna_BinMatrix(A,E,Gr,angle,bin)
else:
bh = np.zeros(Img.shape)
bv = np.zeros(Img.shape)
bh_roi = bh[roi[0]:roi[1], roi[2]:roi[3]]
bv_roi = bv[roi[0]:roi[1], roi[2]:roi[3]]
p = anna_PhogDescriptor(bh_roi,bv_roi,L,bin)
return p
def anna_BinMatrix(A,E,G,angle,bin):
n, contorns = cv2.connectedComponents(E, connectivity=8)
X = E.shape[1]
Y = E.shape[0]
bm = np.zeros(shape=(Y,X))
bv = np.zeros(shape=(Y,X))
nAngle = angle/bin
for i in range(n):
posY, posX = np.where(contorns==i)
for j in range(posY.shape[0]):
pos_x = posX[j]
pos_y = posY[j]
b = np.ceil(A[pos_y,pos_x]/nAngle)
if b==0: bin=1
if G[pos_y,pos_x]>0:
bm[pos_y,pos_x] = b
bv[pos_y,pos_x] = G[pos_y,pos_x]
return (bm, bv)
def anna_PhogDescriptor(bh,bv,L,bin):
p = np.array([])
#level 0
for b in range(bin):
ind = bh==b
p = np.append(p, np.sum(bv[ind]))
#higher levels
for l in range(1, L+1):
x = int(np.trunc(bh.shape[1]/(2**l)))
y = int(np.trunc(bh.shape[0]/(2**l)))
for xx in range(0, bh.shape[1]-x+1, x):
for yy in range(0, bh.shape[0]-y+1, y):
print(l)
bh_cella = bh[yy:yy+y, xx:xx+x]
bv_cella = bv[yy:yy+y, xx:xx+x]
for b in range(bin):
ind = bh_cella==b
p = np.append(p, np.sum(bv_cella[ind], axis=0))
if np.sum(p)!=0:
p = p/np.sum(p)
return p
Below is the screenshot of the folder where I put these file
folder path
This program works for the value of the variable "n" set to 4, as it's the case in the following code:
from __future__ import division
from numpy import zeros
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import linalg
import math
def getA(kappa):
matrix = zeros((n, n), float)
for i in range(n):
for j in range(n):
matrix[i][j] = 2*math.cos((2*math.pi/n)*(abs(j-i))*kappa)
return matrix
def getF(csi, a):
csiInv = linalg.inv(csi)
valueF = np.dot(csiInv, a)
valueF = np.dot(valueF, csiInv)
valueF = np.dot(valueF, a)
traceF = valueF.trace()
return 0.5 * traceF
def getG(csi, f, a):
csiInv = linalg.inv(csi)
valueG = np.dot(csiInv, a)
valueG = np.dot(valueG, csiInv)
valueG = valueG / (2 * f)
return valueG
def getE(g, k):
#m = 10 ^ -6
#kinv = linalg.inv(k + np.eye(k.shape[1])*m)
kinv = linalg.inv(k)
#kinv = linalg.pinv(k)
ktrans = k.transpose()
#ktransinv = linalg.pinv(ktrans)
#ktransinv = linalg.inv(ktrans + np.eye(ktrans.shape[1])*m)
ktransinv = linalg.inv(ktrans)
e = np.dot(ktransinv,g)
e = np.dot(e, kinv)
return e
def getW(k, a, e):
ktrans = k.transpose()
w = np.dot(k, a)
w = np.dot(w, ktrans)
w = np.dot(w, e)
valuew = w.trace()
return valuew
def getV(csi, e, e2, k):
v = np.dot(csi, k)
v = np.dot(v, e)
v = np.dot(v, k)
v = np.dot(v, csi)
v = np.dot(v, k)
v = np.dot(v, e2)
v = np.dot(v, k)
traceV = v.trace()
return traceV
handle_2 = open("test.txt", "w")
n = 4
power_spectrum_k = np.zeros(n, float)
for i in range(n):
power = math.exp(-(2*math.pi*i/n)*(2*math.pi*i/n))
power_spectrum_k[i] = power
# ora posso chiamare l'anti-trasformata
inverse_transform = np.fft.ifft(power_spectrum_k)
print 'inverse_transform:', inverse_transform
CSI = zeros((n, n))
for i in range(n):
for j in range(n):
CSI[i][j] = inverse_transform[abs(i-j)]
betaArray = zeros(n, float)
WabArray = zeros((6, n), float)
correlation = zeros((6, 6), float)
list = [1, 2, 3, 4, 5, 6]
K = zeros((n, n), float)
for i in range(n):
for j in range(i+1):
i_shifted = i + 2
j_shifted = j + 1
print "###############################"
print i_shifted
print j
component1 = ((3.0*70.0*70.0*0.3)/(2.0*300000.0*300000.0))
component2 = ((j_shifted*(i_shifted-j_shifted))/(i_shifted))
component3 = (1.0+(70.0/300000.0)*j_shifted)
print component1
print component2
print component3
K[i][j] = component1*component2*component3
#print 'DetK:', np.linalg.det(K)
print 'K:\n', K
counter = 0
for alpha in list:
counter2 = 0
Aa = getA(alpha)
Faa = getF(CSI, Aa)
Ga = getG(CSI, Faa, Aa)
Ea = getE(Ga, K)
#print 'Ea:', Ea
V_alphaalpha = getV(CSI, Ea, Ea, K)
for beta in xrange(n):
Ab = getA(beta + 1)
#print "Calling getW with K=", K, "\n Ab=", Ab, "\nEa=", Ea
W_ab = getW(K, Ab, Ea)
#print "\nGot W_ab=", W_ab
betaArray[beta] = beta + 1
WabArray[counter][beta] = W_ab
output_string = " {0} {1} \n".format(str(beta + 1), str(W_ab))
handle_2.write(output_string)
Fbb = getF(CSI, Ab)
Gb = getG(CSI, Fbb, Ab)
Eb = getE(Gb, K)
#print "Beta array"
#print betaArray
#print "Wab array"
#print WabArray
for gamma in list:
Ac = getA(gamma)
Fcc = getF(CSI, Ac)
Gc = getG(CSI, Fcc, Ac)
Ec = getE(Gc, K)
V_alphagamma = getV(CSI, Ea, Ec, K)
V_gammagamma = getV(CSI, Ec, Ec, K)
C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
correlation[counter][counter2] = C_alphagamma
counter2 = counter2 + 1
counter = counter + 1
print 'correlation:\n', correlation
WabArray_all = []
betaArray_all = []
for b in range(0, len(WabArray), 1):
for n in betaArray:
betaArray_all.append(n)
for n in WabArray[b]:
WabArray_all.append(n)
Now, as soon as I get n = 5 and any other value bigger than 4, I receive the error:
line 148, in <module>
C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
ValueError: math domain error
which I interpret as a math error due to the fact that I performing the square root of a negative value. Nevertheless, I cannot understand where exactly is the error, in the sense that I cannot understand why changing from 4 to, say, 5 makes the difference. Has anyone any idea of what is going wrong?
math.sqrt is unable to calculate the negative square root
>>> math.sqrt(-1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
If this is valid complex math, import sqrt from cmath instead:
>>> cmath.sqrt(-1)
1j
It is hard to say where the problem is without understanding the algorythm. You will have to do more investigations. IMHO, you should ty to dump the values to better understand the problem but only when thing goes wrong to avoid too much output. Something like :
try:
C_alphagamma = V_alphagamma/(math.sqrt(V_alphaalpha * V_gammagamma))
except ValueError as e:
print alpha, Aa, Faa, Ga, Ea, V_alphaalpha
print gamma, Ac, Fcc, Gc, Ec, V_alphagamma, V_gammagamma
raise e
This is only an idea and other values might be more pertinent
I've set up numpy.seterr as follows:
np.seterr(invalid='raise', over ='raise', under='raise')
And I'm getting the following error:
c = beta[j,i] + oneminusbeta[j,i]
FloatingPointError: overflow encountered in double_scalars
I've checked what beta[j,i] and oneminusbeta[j,i] are at the point of crash, and these are their values:
beta: -131.340389182
oneminusbeta: 0.0
Please note, this line of addition (beta[j,i] + oneminusbeta[j,i]) has run for thousands of lines in a loop (that performs image classification) before crashing here at this point.
How can I deal with this? Is it necessary to change the type of the numpy arrays?
This is how I've initialized them:
beta = np.empty([m,n])
oneminusbeta = np.empty([m,n])
Is it possible to cast the individual values before adding them up? Rather than changing the entire array declarations? Or is this even a serious issue? Would it be safe to simply turn off the numpy.seterr configuration and let the calculations go ahead without raising the error?
Edit
Someone suggested below, and I suspected as well, that the values being added shouldn't cause an overflow. Then how can I find out where the overflow is really happening?
This is my code:
epthreshold = 709
enthreshold = -708
f.write("weights["+str(i)+", " + str(j)+"] = math.exp(beta: " +str(beta[j,i])+ " + oneminusbeta: " + str(oneminusbeta[j,i])+")\n" )
c = beta[j,i] + oneminusbeta[j,i]
weights[i,j] = math.exp(np.clip(c, enthreshold, epthreshold))
And when I check my log file, this is the line I get:
weights[5550, 13] = math.exp(beta: -131.340389182 + oneminusbeta: 0.0)
Edit 2
Here's the rest of my code, where variables n,m and H have already been initialized to integer values:
import numba
import numpy as np
import statsmodels.api as sm
weights = np.empty([n,m])
for curr_n in range(n):
for curr_m in range(m):
weights[curr_n,curr_m] = 1.0/(n)
beta = np.empty([m,n])
oneminusbeta = np.empty([m,n])
for curr_class in range(m):
for curr_sample in range(n):
beta[curr_class,curr_sample] = 1./m
epthreshold = 709 # positive exponential threshold
enthreshold = -708
for h in range(H):
print "Boosting round %d ... " % h
z = np.empty([n,m])
for j in range(m): # computing working responses and weights, Step 2(a)(i)
for i in range(no_samples):
i_class = y[i] #get the correct class for the current sample
if h == 0:
z[i,j] = (int(j==i_class) - beta[j,i])/((beta[j,i])*(1. - beta[j,i]))
weights[i,j] = beta[j,i]*(1. - beta[j,i])
else:
if j == i_class:
z[i,j] = math.exp(np.clip(-beta[j,i],enthreshold, epthreshold))
else:
z[i,j] = -math.exp(np.clip(oneminusbeta[j,i], enthreshold, epthreshold))
f.write("weights["+str(i)+", " + str(j)+"] = math.exp(beta: " +str(beta[j,i])+ " + oneminusbeta: " + str(oneminusbeta[j,i])+")\n" )
c = beta[j,i] + oneminusbeta[j,i]
weights[i,j] = math.exp(np.clip(c, enthreshold, epthreshold))
g_h = np.zeros([1,1])
j = 0
# Calculating regression coefficients per class
# building the parameters per j class
for y1_w in zip(z.T, weights.T):
y1, w = y1_w
temp_g = sm.WLS(y1, X, w).fit() # Step 2(a)(ii)
if np.allclose(g_h,0):
g_h = temp_g.params
else:
g_h = np.c_[g_h, temp_g.params]
j = j + 1
if np.allclose(g,0):
g = g_h
else:
g = g + g_h # Step(2)(a)(iii)
# now set g(x), function coefficients according to new formula, step (2)(b)
sum_g = g.sum(axis=1)
for j in range(m):
diff = (g[:,j] - ((1./m) * sum_g))
g[:,j] = ((m-1.)/m) * diff
g_per_round[h,:,j] = g[:,j]
#Now computing beta, Step 2(c)...."
Q = 0.
e = 0.
for j in range(m):
# Calculating beta and oneminusbeta for class j
aj = 0.0
for i in range(no_samples):
i_class = y[i]
X1 = X[i].reshape(1, no_features)
g1 = g[:,j].reshape(no_features, 1)
gc = g[:,i_class].reshape(no_features, 1)
dot = 1. + float(np.dot(X1, g1)) - float(np.dot(X1,gc))
aj = dot
sum_e = 0.
a_q = []
a_q.append(0.)
for j2 in range(m): # calculating sum of e's except for all j except where j=i_class
if j2 != i_class: # g based on j2, not necessarily g1?
g2 = g[:,j2].reshape(no_features, 1)
dot1 = 1. + float(np.dot(X1, g2)) - float(np.dot(X1,gc))
e2 = math.exp(np.clip(dot1,enthreshold, epthreshold))
sum_e = sum_e + e2
a_q.append(dot1)
if (int(j==i_class) == 1):
a_q_arr = np.array(a_q)
alpha = np.array(a_q_arr[1:])
Q = mylogsumexp(f,a_q_arr, 1, 0)
sumalpha = mylogsumexp(f,alpha, 1, 0)
beta[j,i] = -Q
oneminusbeta[j,i] = sumalpha - Q
else:
alpha = a_q
alpha = np.array(alpha[1:])
a_q_arr = np.array(a_q)
Q = mylogsumexp(f,a_q_arr, 0, aj)
sumalpha = log(math.exp(np.clip(Q, enthreshold, epthreshold)) - math.exp(np.clip(aj, enthreshold, epthreshold)))
beta[j,i] = aj - Q
oneminusbeta[j,i] = sumalpha - Q
and the function mylogsumexp is:
def mylogsumexp(f, a, is_class, maxaj, axis=None, b=None):
np.seterr(over="raise", under="raise", invalid="raise")
threshold = -sys.float_info.max
maxthreshold = sys.float_info.max
epthreshold = 709 # positive exponential threshold
enthreshold = -708
a = asarray(a)
if axis is None:
a = a.ravel()
else:
a = rollaxis(a, axis)
if is_class == 1:
a_max = a.max(axis=0)
else:
a_max = maxaj
#bnone = " none "
if b is not None:
a_max = maxaj
b = asarray(b)
if axis is None:
b = b.ravel()
else:
b = rollaxis(b, axis)
a = np.clip(a - a_max, enthreshold, epthreshold)
midout = np.sum(np.exp(a), axis=0)
midout = 1.0 + np.clip(midout - math.exp(a_max), threshold, maxthreshold)
out = np.log(midout)
else:
a = np.clip(a - a_max, enthreshold, epthreshold)
out = np.log(np.sum(np.exp(a)))
out += a_max
if out == float("inf"):
out = maxthreshold
if out == float("-inf"):
out = threshold
return out
I have completed a code in Python for my summer internship.
Here is the code:
from numpy import loadtxt, abs, mean, float64
def Sum_radii(particle1, particle2): #Sum of radii - to be compared with distance
summ = particle1.radius+particle2.radius
return summ
def PBCdist(particle1, particle2): #PBC conditions to compute distance for any two particles
dx = abs(particle1.x-particle2.x)
dy = abs(particle1.y-particle2.y)
#dz = abs(particle1.z-particle2.z)
if dx > 0.5:
dx = 1.0-dx
else:
dx = dx
if dy > 0.5:
dy = 1.0-dy
else:
dy = dy
#if dz > 0.5:
# dz = 1.0-dz
#else:
# dz = dz
DX = dx**2
DY = dy**2
#DZ = dz**2
dist = DX+DY
distance = dist**0.5
return distance
def Final_step(my_particles):
for particle1 in my_particles:
if len(particle1.neighbours) <=2 :
for k in range(len(particle1.neighbours)):
n = particle1.neighbours[k]
my_particles[n].neighbours.remove(particle1.n)
for particle1 in my_particles:
if len(particle1.neighbours) <=2 :
my_particles.remove(particle1)
return my_particles
def Recursion(my_particles):
l1 = len(my_particles)
my_particles = Final_step(my_particles)
l2 = len(my_particles)
if (l1!=l2):
Recursion(my_particles)
else:
return my_particles
f = open("contacts.txt", "w")
for i in range(len(my_particles)):
list = []
list.append(my_particles[i].n,my_particles[i].neighbours)
print list
print >>f, list
f.close()
def mean_contacts(my_particles):
for k in range(len(my_particles)):
contact_number.append(len(my_particles[k].neighbours))
print ("%.20f" % mean(contact_number))
#Read data and define the class Particle
class Particle():
def __init__(self, (x,y), n, radius, neighbours):
self.n = n
self.x = x
self.y = y
#self.z = z
self.radius = radius
self.neighbours = neighbours
number = loadtxt("Final.dat", usecols=(0,), unpack=True, dtype = int)
c1,c2,r = loadtxt("Final.dat", usecols=(1,2,4), unpack=True, dtype=float64)
number_of_particles = len(number)
my_particles = []
overlap = []
contact_number = []
for i in range(number_of_particles):
n = number[i]
x = c1[i]
y = c2[i]
#z = c3[i]
radius = r[i]
neighbours = []
particle = Particle((x,y), n, radius, neighbours)
my_particles.append(particle)
for particle1 in my_particles:
for particle2 in my_particles:
distance = PBCdist(particle1, particle2)
sum_of_radii = Sum_radii(particle1, particle2)
if (distance < sum_of_radii) and (distance>0):
olap = sum_of_radii - distance
overlap.append(olap)
particle1.neighbours.append(particle2.n)
#Recursion(my_particles)
Final_step(my_particles)
mean_contacts(my_particles)
As you can see, I have not tried the Recursion function, just to make thing more straightforward.
Now, the file im a reading is formatted in the following way:
0 0.70138224747245225821 0.28586219648439409324 0 0.0037570717610070714435
1 0.94878397047547669008 0.17267104541971631249 0 0.0038326670080525947204
2 0.59078448810638095612 0.29243415714920478754 0 0.0037315418643608781225
3 0.38696755396911874936 0.15180438637928708734 0 0.004051606114197996676 2
4 0.71585843878867627676 0.47742962311059283786 0 0.0043035198430089825067
For 16383 rows of data. when I try to run the code after something like 4 mins i get the following error message:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/monitor.py", line 575, in run
already_pickled=True)
File "/usr/lib/python2.7/dist-packages/spyderlib/utils/bsdsocket.py", line 24, in write_packet
sock.send(struct.pack("l", len(sent_data)) + sent_data)
error: [Errno 32] Broken pipe
I tried it with a 128-row data file and things work perfectly within 1 second.
I was wondering what that message means in the first place and how, if possible, to fix it.
I am running on a Ubuntu12.04, 4 GB ram, 64 bit desktop.
This seems like a known issue in Spyder 2.1.10 , according to Issue 1474 (Issue 1106) .
The fix seems to be available in Spyder 2.2.