Python Forum

Full Version: Changing Function by Changing or without Changing its Parameters
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am new to python and in learning stages. I wanted to implement Particle Swarm Optimization(PSO) algorithm which I did by taking help from on-line materials and python tutorials. In PSO, a simple calculus problem is optimized i-e 100 * ((y - (x2))2) + ((1 - (x2))2). This problem is defined in a fitness function. i-e
def fitness(x, y):
    return 100 * ((y - (x**2))**2) + ((1 - (x**2))**2)
Now, I want to replace this simple calculus problem by simple first order Ordinary Differential Equation(ODE) by without changing existing function parameters (x,y) and want to return the value of dy_dx,y0 and t for further process.
# Define a function which calculates the derivative
def dy_dx(y, x):
    return x - y
t = np.linspace(0,5,100)
y0 = 1.0  # the initial condition
ys = odeint(dy_dx, y0, t)
In python odeint function is used for ODE which requires three essential parameters i-e func/model, y0( Initial condition on y (can be a vector) and t(A sequence of time points for which to solve for y).

I don't want to change its parameters because it will be difficult for me to make changes in algorithm. Furthermore, by not changing the parameters I think it might not work but I am not clear about it so For simplicity I pasted the full code below and my question is open to anyone if wants to modify the code with further parameters.

import numpy as np
import random as rand
import matplotlib.pyplot as plt

def main():
    #Variables
    n = 40
    num_variables = 2


    a = np.empty((num_variables, n))
    v = np.empty((num_variables, n))
    Pbest = np.empty((num_variables, n))
    Gbest = np.empty((1, 2))
    r = np.empty((n))

    
    for i in range(0, num_variables):
        for j in range(0, n):
            Pbest[i][j] = rand.randint(-20, 20)
            a[i][j] = Pbest[i][j]
            v[i][j] = 0
    
   
    for i in range(0, n):
        r[i] = fitness(a[0][i], a[1][i])

    #Sort elements of Pbest
    Ordenamiento_Burbuja(Pbest, r, n)

    Gbest[0][0] = Pbest[0][0]
    Gbest[0][1] = Pbest[1][0]

    generation = 0

    plt.ion()
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.grid(True)
    
    while(generation < 1000):
        for i in range(n):
            #Get Pbest
            if(fitness(a[0][i], a[1][i]) < fitness(Pbest[0][i], Pbest[1][i])):
                Pbest[0][i] = a[0][i]
                Pbest[1][i] = a[1][i]
            #Get Gbest
            if(fitness(Pbest[0][i], Pbest[1][i]) < fitness(Gbest[0][0], Gbest[0][1])):
                Gbest[0][0] = Pbest[0][i]
                Gbest[0][1] = Pbest[1][i]
            #Calculate PBest
            Vector_Velocidad(n, a, Pbest, Gbest, v)
        generation = generation + 1
        print 'Generacion: ' + str(generation) + ' - - - Gbest: ' +str(Gbest)

        line1 = ax.plot(a[0], a[1], 'r+')
        line2 = ax.plot(Gbest[0][0], Gbest[0][1], 'g*')

        ax.set_xlim(-10, 10)
        ax.set_ylim(-10, 10)
        
        fig.canvas.draw()

        ax.clear()
        ax.grid(True)

    print 'Gbest: '
    print Gbest

def Vector_Velocidad(n, a, Pbest, Gbest, v):
    for i in range(n):
        #Velocidad en X
        v[0][i] = 0.7 * v[0][i] + (Pbest[0][i] - a[0][i]) * rand.random() * 1.47 + (Gbest[0][0] - a[0][i]) * rand.random() * 1.47
        a[0][i] = a[0][i] + v[0][i]
        #Velocity 
        v[1][i] = 0.7 * v[1][i] + (Pbest[1][i] - a[1][i]) * rand.random() * 1.47 + (Gbest[0][1] - a[1][i]) * rand.random() * 1.47
        a[1][i] = a[1][i] + v[1][i]

def fitness(x, y):
        return 100 * ((y - (x**2))**2) + ((1 - (x**2))**2)
        

def Ordenamiento_Burbuja(Pbest, r, n):
   
    for i in range(1, n):
        for j in range(0, n - 1):
            if r[j] > r[j + 1]:
               
                tempRes = r[j]
                r[j] = r[j + 1]
                r[j + 1] = tempRes

                
                tempX = Pbest[0][j]
                Pbest[0][j] = Pbest[0][j + 1]
                Pbest[0][j + 1] = tempX

                tempY = Pbest[1][j]
                Pbest[1][j] = Pbest[1][j + 1]
                Pbest[1][j + 1] = tempY

if '__main__' == main():
    main()
What is the relation between the ODE and the fitness function that appears in your code? They look like completely different things. How could the ODE play a role in your code?
ys = odeint(lambda y, x: fitness(x,y), y0, t)
(Jan-08-2018, 09:23 PM)Gribouillis Wrote: [ -> ]What is the relation between the ODE and the fitness function that appears in your code? They look like completely different things. How could the ODE play a role in your code?

There is no relation of ODE in the fitness function. Actually I want to replace the calculus problem with ODE function and that calculus problem
[b]return 100 * ((y - (x**2))**2) + ((1 - (x**2))**2)[/b]
is defined in fitness function. We can change the name of fitness function as well. But I don't know how to return ODE parameters.
(Jan-08-2018, 10:17 PM)Windspar Wrote: [ -> ]
ys = odeint(lambda y, x: fitness(x,y), y0, t)

Can you please explain. Here it is returning three values so how I am going to fix it in upper code where fitness is declared.
Maybe you can give an example. What you are trying to do.
def odevalues():
	xy_value = []
	values = []
	def dy_dx(y, x):
		xy_value.append((x, y))
		values.append(x - y)
		return x - y

	t = np.linspace(0,5,100)
	y0 = 1.0  # the initial condition
	ys = odeint(dy_dx, y0, t)
	return xy_value, values, y0, t

ode = odevalues()
for xy in ode[0]:
	print(xy)

for v in ode[1]:
	print(v)

for d in ode[2:]:
	print(d)