In [10]:
from numpy import *
%matplotlib inline 
#notebook
import matplotlib.pyplot as plt

def function_minimizer(E,z0,r0,tol):
    # E function to be minimized
    # z0 is the initial guess at minimizer
    # r0 initial stagger radius
    # tol is the tolerance for error in the result
    
    z = array(z0,dtype=float) #z0.copy()
    ncalls = 0
    nfailsmax = 10
    r = r0 
    Ez = E(z)
    plt.plot(z[0],z[1],'mo')
    
    nfails = 0
    plt.subplot(111,aspect=1)
    while(True):
        ztry = z + 2*r*random.rand(len(z)) - r
        Eztry = E(ztry)
        if Eztry < Ez:
            # replace z by ztry
            plt.plot([z[0],ztry[0]],[z[1],ztry[1]],'b')
            z = ztry
            Ez = Eztry
            plt.plot(z[0],z[1],'bo',alpha=0.9)
            
            #print(i,'success')
            nfails = 0
        else:
            #print(i,'FAIL!')
            plt.plot([z[0],ztry[0]],[z[1],ztry[1]],'r',alpha=0.2)
            plt.plot(ztry[0],ztry[1],'ro',alpha=0.2)
            nfails += 1
            if nfails > nfailsmax:
                r /= 2
                #print(r)
                if r < tol: break
    plt.plot(z[0],z[1],'go')
    print(z,ncalls)
    return z
In [11]:
def myfunc(z):
    return (z[0]-4)**2 + (z[1]-1)**2  # minimum at [4,1]
In [12]:
print(function_minimizer(myfunc,[0,0],1,1e-6 ))
[ 3.99999954  1.00000029] 0
[ 3.99999954  1.00000029]