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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
"""
This example demonstrates the use of TAO for Python to solve an
unconstrained minimization problem on a single processor.
We minimize the extended Rosenbrock function::
sum_{i=0}^{n/2-1} ( alpha*(x_{2i+1}-x_{2i}^2)^2 + (1-x_{2i})^2 )
"""
try: range = xrange
except NameError: pass
# the two lines below are only
# needed to build options database
# from command line arguments
import sys, petsc4py
petsc4py.init(sys.argv)
from petsc4py import PETSc
class AppCtx(object):
"""
Extended Rosenbrock function.
"""
def __init__(self, n=2, alpha=99.0):
self.size = int(n)
self.alpha = float(alpha)
def formObjective(self, tao, x):
#print 'AppCtx.formObjective()'
alpha = self.alpha
nn = self.size // 2
ff = 0.0
for i in range(nn):
t1 = x[2*i+1] - x[2*i] * x[2*i]
t2 = 1 - x[2*i];
ff += alpha*t1*t1 + t2*t2;
return ff
def formGradient(self, tao, x, G):
#print 'AppCtx.formGradient()'
alpha = self.alpha
nn = self.size // 2
G.zeroEntries()
for i in range(nn):
t1 = x[2*i+1] - x[2*i] * x[2*i]
t2 = 1 - x[2*i];
G[2*i] = -4*alpha*t1*x[2*i] - 2*t2;
G[2*i+1] = 2*alpha*t1;
def formObjGrad(self, tao, x, G):
#print 'AppCtx.formObjGrad()'
alpha = self.alpha
nn = self.size // 2
ff = 0.0
G.zeroEntries()
for i in range(nn):
t1 = x[2*i+1] - x[2*i] * x[2*i]
t2 = 1 - x[2*i];
ff += alpha*t1*t1 + t2*t2;
G[2*i] = -4*alpha*t1*x[2*i] - 2*t2;
G[2*i+1] = 2*alpha*t1;
return ff
def formHessian(self, tao, x, H, HP):
#print 'AppCtx.formHessian()'
alpha = self.alpha
nn = self.size // 2
idx = [0, 0]
v = [[0.0, 0.0],
[0.0, 0.0]]
H.zeroEntries()
for i in range(nn):
v[1][1] = 2*alpha
v[0][0] = -4*alpha*(x[2*i+1]-3*x[2*i]*x[2*i]) + 2
v[1][0] = v[0][1] = -4.0*alpha*x[2*i];
idx[0] = 2*i
idx[1] = 2*i+1
H[idx,idx] = v
H.assemble()
# access PETSc options database
OptDB = PETSc.Options()
# create user application context
# and configure user parameters
user = AppCtx()
user.size = OptDB.getInt ( 'n', user.size)
user.alpha = OptDB.getReal('alpha', user.alpha)
# create solution vector
x = PETSc.Vec().create(PETSc.COMM_SELF)
x.setSizes(user.size)
x.setFromOptions()
# create Hessian matrix
H = PETSc.Mat().create(PETSc.COMM_SELF)
H.setSizes([user.size, user.size])
H.setFromOptions()
H.setOption(PETSc.Mat.Option.SYMMETRIC, True)
H.setUp()
# pass the following to command line:
# $ ... -methods nm,lmvm,nls,ntr,cg,blmvm,tron
# to try many methods
methods = OptDB.getString('methods', '')
methods = methods.split(',')
for meth in methods:
# create TAO Solver
tao = PETSc.TAO().create(PETSc.COMM_SELF)
if meth: tao.setType(meth)
tao.setFromOptions()
# solve the problem
tao.setObjectiveGradient(user.formObjGrad)
tao.setObjective(user.formObjective)
tao.setGradient(user.formGradient)
tao.setHessian(user.formHessian, H)
#app.getKSP().getPC().setFromOptions()
x.set(0) # zero initial guess
tao.setSolution(x)
tao.solve()
tao.destroy()
## # this is just for testing
## x = app.getSolution()
## G = app.getGradient()
## H, HP = app.getHessian()
## f = tao.computeObjective(x)
## tao.computeGradient(x, G)
## f = tao.computeObjectiveGradient(x, G)
## tao.computeHessian(x, H, HP)
|