1 static char help[] = "TAO/Pounders MATLAB Testing on the More'-Wild Benchmark Problems\n\
2 The interface calls:\n\
3 TestingInitialize.m to initialize the problem set\n\
4 ProblemInitialize.m to initialize each instance\n\
5 ProblemFinalize.m to store the performance data for the instance solved\n\
6 TestingFinalize.m to store the entire set of performance data\n\
7 \n\
8 TestingPlot.m is called outside of TAO/Pounders to produce a performance profile\n\
9 of the results compared to the MATLAB fminsearch algorithm.\n";
10
11 #include <petsctao.h>
12 #include <petscmatlab.h>
13
14 typedef struct {
15 PetscMatlabEngine mengine;
16
17 double delta; /* Initial trust region radius */
18
19 int n; /* Number of inputs */
20 int m; /* Number of outputs */
21 int nfmax; /* Maximum function evaluations */
22 int npmax; /* Maximum interpolation points */
23 } AppCtx;
24
EvaluateResidual(Tao tao,Vec X,Vec F,void * ptr)25 static PetscErrorCode EvaluateResidual(Tao tao, Vec X, Vec F, void *ptr)
26 {
27 AppCtx *user = (AppCtx *)ptr;
28
29 PetscFunctionBegin;
30 PetscCall(PetscObjectSetName((PetscObject)X, "X"));
31 PetscCall(PetscMatlabEnginePut(user->mengine, (PetscObject)X));
32 PetscCall(PetscMatlabEngineEvaluate(user->mengine, "F = func(X);"));
33 PetscCall(PetscObjectSetName((PetscObject)F, "F"));
34 PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)F));
35 PetscFunctionReturn(PETSC_SUCCESS);
36 }
37
EvaluateJacobian(Tao tao,Vec X,Mat J,Mat JPre,void * ptr)38 static PetscErrorCode EvaluateJacobian(Tao tao, Vec X, Mat J, Mat JPre, void *ptr)
39 {
40 AppCtx *user = (AppCtx *)ptr;
41
42 PetscFunctionBegin;
43 PetscCall(PetscObjectSetName((PetscObject)X, "X"));
44 PetscCall(PetscMatlabEnginePut(user->mengine, (PetscObject)X));
45 PetscCall(PetscMatlabEngineEvaluate(user->mengine, "J = jac(X);"));
46 PetscCall(PetscObjectSetName((PetscObject)J, "J"));
47 PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)J));
48 PetscFunctionReturn(PETSC_SUCCESS);
49 }
50
TaoPounders(AppCtx * user)51 static PetscErrorCode TaoPounders(AppCtx *user)
52 {
53 Tao tao;
54 Vec X, F;
55 Mat J;
56 char buf[1024];
57
58 PetscFunctionBegin;
59 /* Set the values for the algorithm options we want to use */
60 PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%d", user->npmax));
61 PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_npmax", buf));
62 PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%5.4e", user->delta));
63 PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_delta", buf));
64
65 /* Create the TAO objects and set the type */
66 PetscCall(TaoCreate(PETSC_COMM_SELF, &tao));
67
68 /* Create starting point and initialize */
69 PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->n, &X));
70 PetscCall(PetscObjectSetName((PetscObject)X, "X0"));
71 PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)X));
72 PetscCall(TaoSetSolution(tao, X));
73
74 /* Create residuals vector and set residual function */
75 PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->m, &F));
76 PetscCall(PetscObjectSetName((PetscObject)F, "F"));
77 PetscCall(TaoSetResidualRoutine(tao, F, EvaluateResidual, (void *)user));
78
79 /* Create Jacobian matrix and set residual Jacobian routine */
80 PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, user->m, user->n, user->n, NULL, &J));
81 PetscCall(PetscObjectSetName((PetscObject)J, "J"));
82 PetscCall(TaoSetJacobianResidualRoutine(tao, J, J, EvaluateJacobian, (void *)user));
83
84 /* Solve the problem */
85 PetscCall(TaoSetType(tao, TAOPOUNDERS));
86 PetscCall(TaoSetMaximumFunctionEvaluations(tao, user->nfmax));
87 PetscCall(TaoSetFromOptions(tao));
88 PetscCall(TaoSolve(tao));
89
90 /* Finish the problem */
91 PetscCall(MatDestroy(&J));
92 PetscCall(VecDestroy(&X));
93 PetscCall(VecDestroy(&F));
94 PetscCall(TaoDestroy(&tao));
95 PetscFunctionReturn(PETSC_SUCCESS);
96 }
97
main(int argc,char ** argv)98 int main(int argc, char **argv)
99 {
100 AppCtx user;
101 PetscScalar tmp;
102 PetscInt prob_id = 0;
103 PetscBool flg, testall = PETSC_FALSE;
104 int i, i0, imax;
105
106 PetscFunctionBeginUser;
107 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
108 PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_all", &testall, NULL));
109 PetscCall(PetscOptionsGetInt(NULL, NULL, "-prob_id", &prob_id, &flg));
110 if (!testall) {
111 if (!flg) {
112 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Problem number must be specified with -prob_id");
113 } else if ((prob_id < 1) || (prob_id > 53)) {
114 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Problem number must be between 1 and 53!");
115 } else {
116 PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running problem %d\n", prob_id));
117 }
118 } else {
119 PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running all problems\n"));
120 }
121
122 PetscCall(PetscMatlabEngineCreate(PETSC_COMM_SELF, NULL, &user.mengine));
123 PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingInitialize"));
124
125 if (testall) {
126 i0 = 1;
127 imax = 53;
128 } else {
129 i0 = (int)prob_id;
130 imax = (int)prob_id;
131 }
132
133 for (i = i0; i <= imax; ++i) {
134 PetscCall(PetscPrintf(PETSC_COMM_SELF, "%d\n", i));
135 PetscCall(PetscMatlabEngineEvaluate(user.mengine, "np = %d; ProblemInitialize", i));
136 PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "n"));
137 user.n = (int)tmp;
138 PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "m"));
139 user.m = (int)tmp;
140 PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "nfmax"));
141 user.nfmax = (int)tmp;
142 PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "npmax"));
143 user.npmax = (int)tmp;
144 PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "delta"));
145 user.delta = (double)tmp;
146
147 /* Ignore return code for now -- do not stop testing on inf or nan errors */
148 PetscCall(TaoPounders(&user));
149
150 PetscCall(PetscMatlabEngineEvaluate(user.mengine, "ProblemFinalize"));
151 }
152
153 PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingFinalize"));
154 PetscCall(PetscMatlabEngineDestroy(&user.mengine));
155 PetscCall(PetscFinalize());
156 return 0;
157 }
158
159 /*TEST
160
161 build:
162 requires: matlab
163
164 test:
165 localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m
166 args: -tao_monitor_short -prob_id 5
167
168 TEST*/
169