Search code examples
pythonnumpyfor-loopoptimizationscipy-optimize

Cyclic coordinate Search Optimization, updating new optimum using for loop


In cyclic coordinate search, we look for an optimum inline with each one of the coordinate axes. I have defined the variable x_new as an updated variable for the start point. Inside the loop, the objective function is minimized first in the x1 direction and then the x2 direction.

I am having trouble actually updating x_new. It will not update as currently coded and when printed is output as [0, 0].

import scipy.optimize as opt                                            
import numpy as np                                                      
# Objective Function                                                    
# f(x1,x2) = (x2-x1**2)**4 + (3-x1)**2                                  
# x = [0, 0]                                                            
                                                                        
# Initialize                                                            
x0 = np.array([0, 0])                                                   
iter = 0                                                                
epsilon = 0.0001                                                        
x_new = x0                                                              
                                                                        
for i in range(len(x0)):                                                
    if i == 0:                                                          
        def obj_func(x):                                                
            return (x_new[1] - x ** 2) ** 4 + (3 - x) ** 2              
        x_new[0] = opt.minimize_scalar(obj_func).x                                                                                    
    else:                                                               
        def obj_func(x):                                                
            return (x - x_new[0]**2) ** 4 + (3 - x_new[0]) ** 2         
        x_new[1] = opt.minimize_scalar(obj_func).x                                                                                   
    iter += 1                                                           
                                                                        
                                                                        
print(x_new)                                                            
print(iter)                                                             

This is the output of this code

How can I get x_new to update or am I approaching this all wrong?


Solution

  • The issue was that I didn't define the numpy arrays as floats so it wouldn't update the original assignment of x_new

    import scipy.optimize as opt
    import numpy as np
    
    # Objective Function
    # f(x1,x2) = (x2-x1**2)**4 + (3-x1)**2
    # x = [0, 0]
    
    x_new = np.array([0.0, 0.0])
    x0 = np.array([0.0, 0.0])
    x_hist = np.array([0.0, 0.0])
    f = np.array([9])
    iter = 0
    while iter < 12:
        for i in range(len(x0)):
            if i == 0:
                def obj_func(x):
                    return (x_new[1] - x ** 2) ** 4 + (3 - x) ** 2
                x_new[0] = opt.minimize_scalar(obj_func).x
                f = np.append(f, obj_func(x_new[0]))
                x_hist = np.append(x_hist, x_new[0])
                iter += 1
            else:
                def obj_func(x):
                    return (x - x_new[0] ** 2) ** 4 + (3 - x_new[0]) ** 2
                x_new[1] = opt.minimize_scalar(obj_func).x
                x_hist = np.append(x_hist, x_new[1])
                f = np.append(f, obj_func(x_new[1]))
                iter += 1
    
    print('The optimum value found after', iter, 'iterations is f* = ',
          round((x_new[1] - x_new[0] ** 2) ** 4 + (3 - x_new[0]) ** 2, 5),
          '\nThe optimizers were x* = ', x_new, '\nThe minimum was found using',
          'Cyclic Coordinate Search w/o acceleration')