-
Notifications
You must be signed in to change notification settings - Fork 192
/
powell.py
47 lines (40 loc) · 1.51 KB
/
powell.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
## module powell
''' xMin,nCyc = powell(F,x,h=0.1,tol=1.0e-6)
Powell's method of minimizing user-supplied function F(x).
x = starting point
h = initial search increment used in 'bracket'
xMin = mimimum point
nCyc = number of cycles
'''
from numpy import identity,array,dot,zeros,argmax
from goldSearch import *
from math import sqrt
def powell(F,x,h=0.1,tol=1.0e-6):
def f(s): return F(x + s*v) # F in direction of v
n = len(x) # Number of design variables
df = zeros(n) # Decreases of F stored here
u = identity(n) # Vectors v stored here by rows
for j in range(30): # Allow for 30 cycles:
xOld = x.copy() # Save starting point
fOld = F(xOld)
# First n line searches record decreases of F
for i in range(n):
v = u[i]
a,b = bracket(f,0.0,h)
s,fMin = search(f,a,b)
df[i] = fOld - fMin
fOld = fMin
x = x + s*v
# Last line search in the cycle
v = x - xOld
a,b = bracket(f,0.0,h)
s,fLast = search(f,a,b)
x = x + s*v
# Check for convergence
if sqrt(dot(x-xOld,x-xOld)/n) < tol: return x,j+1
# Identify biggest decrease & update search directions
iMax = argmax(df)
for i in range(iMax,n-1):
u[i] = u[i+1]
u[n-1] = v
print "Powell did not converge"