1750b007cSBarry Smith static char help[] = "TAO/Pounders MATLAB Testing on the More'-Wild Benchmark Problems\n\
2c4762a1bSJed Brown The interface calls:\n\
3c4762a1bSJed Brown TestingInitialize.m to initialize the problem set\n\
4c4762a1bSJed Brown ProblemInitialize.m to initialize each instance\n\
5c4762a1bSJed Brown ProblemFinalize.m to store the performance data for the instance solved\n\
6c4762a1bSJed Brown TestingFinalize.m to store the entire set of performance data\n\
7c4762a1bSJed Brown \n\
8c4762a1bSJed Brown TestingPlot.m is called outside of TAO/Pounders to produce a performance profile\n\
9750b007cSBarry Smith of the results compared to the MATLAB fminsearch algorithm.\n";
10c4762a1bSJed Brown
11c4762a1bSJed Brown #include <petsctao.h>
12c4762a1bSJed Brown #include <petscmatlab.h>
13c4762a1bSJed Brown
14c4762a1bSJed Brown typedef struct {
15c4762a1bSJed Brown PetscMatlabEngine mengine;
16c4762a1bSJed Brown
17c4762a1bSJed Brown double delta; /* Initial trust region radius */
18c4762a1bSJed Brown
19c4762a1bSJed Brown int n; /* Number of inputs */
20c4762a1bSJed Brown int m; /* Number of outputs */
21c4762a1bSJed Brown int nfmax; /* Maximum function evaluations */
22c4762a1bSJed Brown int npmax; /* Maximum interpolation points */
23c4762a1bSJed Brown } AppCtx;
24c4762a1bSJed Brown
EvaluateResidual(Tao tao,Vec X,Vec F,void * ptr)25d71ae5a4SJacob Faibussowitsch static PetscErrorCode EvaluateResidual(Tao tao, Vec X, Vec F, void *ptr)
26d71ae5a4SJacob Faibussowitsch {
27c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr;
28c4762a1bSJed Brown
29c4762a1bSJed Brown PetscFunctionBegin;
309566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "X"));
319566063dSJacob Faibussowitsch PetscCall(PetscMatlabEnginePut(user->mengine, (PetscObject)X));
329566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user->mengine, "F = func(X);"));
339566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)F, "F"));
349566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)F));
353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
36c4762a1bSJed Brown }
37c4762a1bSJed Brown
EvaluateJacobian(Tao tao,Vec X,Mat J,Mat JPre,void * ptr)38d71ae5a4SJacob Faibussowitsch static PetscErrorCode EvaluateJacobian(Tao tao, Vec X, Mat J, Mat JPre, void *ptr)
39d71ae5a4SJacob Faibussowitsch {
40c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr;
41c4762a1bSJed Brown
42c4762a1bSJed Brown PetscFunctionBegin;
439566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "X"));
449566063dSJacob Faibussowitsch PetscCall(PetscMatlabEnginePut(user->mengine, (PetscObject)X));
459566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user->mengine, "J = jac(X);"));
469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)J, "J"));
479566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)J));
483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
49c4762a1bSJed Brown }
50c4762a1bSJed Brown
TaoPounders(AppCtx * user)51d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoPounders(AppCtx *user)
52d71ae5a4SJacob Faibussowitsch {
53c4762a1bSJed Brown Tao tao;
54c4762a1bSJed Brown Vec X, F;
55c4762a1bSJed Brown Mat J;
56c4762a1bSJed Brown char buf[1024];
57c4762a1bSJed Brown
58c4762a1bSJed Brown PetscFunctionBegin;
59c4762a1bSJed Brown /* Set the values for the algorithm options we want to use */
60a364092eSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%d", user->npmax));
619566063dSJacob Faibussowitsch PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_npmax", buf));
62a364092eSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%5.4e", user->delta));
639566063dSJacob Faibussowitsch PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_delta", buf));
64c4762a1bSJed Brown
65c4762a1bSJed Brown /* Create the TAO objects and set the type */
669566063dSJacob Faibussowitsch PetscCall(TaoCreate(PETSC_COMM_SELF, &tao));
67c4762a1bSJed Brown
68c4762a1bSJed Brown /* Create starting point and initialize */
699566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->n, &X));
709566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, "X0"));
719566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)X));
729566063dSJacob Faibussowitsch PetscCall(TaoSetSolution(tao, X));
73c4762a1bSJed Brown
74c4762a1bSJed Brown /* Create residuals vector and set residual function */
759566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->m, &F));
769566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)F, "F"));
779566063dSJacob Faibussowitsch PetscCall(TaoSetResidualRoutine(tao, F, EvaluateResidual, (void *)user));
78c4762a1bSJed Brown
79c4762a1bSJed Brown /* Create Jacobian matrix and set residual Jacobian routine */
809566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, user->m, user->n, user->n, NULL, &J));
819566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)J, "J"));
829566063dSJacob Faibussowitsch PetscCall(TaoSetJacobianResidualRoutine(tao, J, J, EvaluateJacobian, (void *)user));
83c4762a1bSJed Brown
84c4762a1bSJed Brown /* Solve the problem */
859566063dSJacob Faibussowitsch PetscCall(TaoSetType(tao, TAOPOUNDERS));
869566063dSJacob Faibussowitsch PetscCall(TaoSetMaximumFunctionEvaluations(tao, user->nfmax));
879566063dSJacob Faibussowitsch PetscCall(TaoSetFromOptions(tao));
889566063dSJacob Faibussowitsch PetscCall(TaoSolve(tao));
89c4762a1bSJed Brown
90c4762a1bSJed Brown /* Finish the problem */
919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J));
929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X));
939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&F));
949566063dSJacob Faibussowitsch PetscCall(TaoDestroy(&tao));
953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
96c4762a1bSJed Brown }
97c4762a1bSJed Brown
main(int argc,char ** argv)98d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
99d71ae5a4SJacob Faibussowitsch {
100c4762a1bSJed Brown AppCtx user;
101c4762a1bSJed Brown PetscScalar tmp;
102c4762a1bSJed Brown PetscInt prob_id = 0;
103c4762a1bSJed Brown PetscBool flg, testall = PETSC_FALSE;
104c4762a1bSJed Brown int i, i0, imax;
105c4762a1bSJed Brown
106327415f7SBarry Smith PetscFunctionBeginUser;
107*c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &argv, NULL, help));
1089566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_all", &testall, NULL));
1099566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-prob_id", &prob_id, &flg));
110c4762a1bSJed Brown if (!testall) {
111c4762a1bSJed Brown if (!flg) {
112c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Problem number must be specified with -prob_id");
113c4762a1bSJed Brown } else if ((prob_id < 1) || (prob_id > 53)) {
114c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Problem number must be between 1 and 53!");
115c4762a1bSJed Brown } else {
1169566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running problem %d\n", prob_id));
117c4762a1bSJed Brown }
118c4762a1bSJed Brown } else {
1199566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running all problems\n"));
120c4762a1bSJed Brown }
121c4762a1bSJed Brown
1229566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineCreate(PETSC_COMM_SELF, NULL, &user.mengine));
1239566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingInitialize"));
124c4762a1bSJed Brown
125c4762a1bSJed Brown if (testall) {
126c4762a1bSJed Brown i0 = 1;
127c4762a1bSJed Brown imax = 53;
128c4762a1bSJed Brown } else {
129c4762a1bSJed Brown i0 = (int)prob_id;
130c4762a1bSJed Brown imax = (int)prob_id;
131c4762a1bSJed Brown }
132c4762a1bSJed Brown
133c4762a1bSJed Brown for (i = i0; i <= imax; ++i) {
1349566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "%d\n", i));
1359566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user.mengine, "np = %d; ProblemInitialize", i));
1369566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "n"));
137c4762a1bSJed Brown user.n = (int)tmp;
1389566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "m"));
139c4762a1bSJed Brown user.m = (int)tmp;
1409566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "nfmax"));
141c4762a1bSJed Brown user.nfmax = (int)tmp;
1429566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "npmax"));
143c4762a1bSJed Brown user.npmax = (int)tmp;
1449566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "delta"));
145c4762a1bSJed Brown user.delta = (double)tmp;
146c4762a1bSJed Brown
147c4762a1bSJed Brown /* Ignore return code for now -- do not stop testing on inf or nan errors */
1489566063dSJacob Faibussowitsch PetscCall(TaoPounders(&user));
149c4762a1bSJed Brown
1509566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user.mengine, "ProblemFinalize"));
151c4762a1bSJed Brown }
152c4762a1bSJed Brown
1539566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingFinalize"));
1549566063dSJacob Faibussowitsch PetscCall(PetscMatlabEngineDestroy(&user.mengine));
1559566063dSJacob Faibussowitsch PetscCall(PetscFinalize());
156b122ec5aSJacob Faibussowitsch return 0;
157c4762a1bSJed Brown }
158c4762a1bSJed Brown
159c4762a1bSJed Brown /*TEST
160c4762a1bSJed Brown
161c4762a1bSJed Brown build:
162750b007cSBarry Smith requires: matlab
163c4762a1bSJed Brown
164c4762a1bSJed Brown test:
165c4762a1bSJed Brown localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m
16610978b7dSBarry Smith args: -tao_monitor_short -prob_id 5
167c4762a1bSJed Brown
168c4762a1bSJed Brown TEST*/
169