File: rosenbrock.py

package info (click to toggle)
petsc4py 3.23.1-1exp2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 3,448 kB
  • sloc: python: 12,503; ansic: 1,697; makefile: 343; f90: 313; sh: 14
file content (136 lines) | stat: -rw-r--r-- 3,631 bytes parent folder | download | duplicates (3)
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)