xref: /petsc/src/tao/leastsquares/tutorials/matlab/matlab_ls_test.c (revision d9acb416d05abeed0a33bde3a81aeb2ea0364f6a)
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 
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 
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 
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 
60   /* Set the values for the algorithm options we want to use */
61   PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%d", user->npmax));
62   PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_npmax", buf));
63   PetscCall(PetscSNPrintf(buf, PETSC_STATIC_ARRAY_LENGTH(buf), "%5.4e", user->delta));
64   PetscCall(PetscOptionsSetValue(NULL, "-tao_pounders_delta", buf));
65 
66   /* Create the TAO objects and set the type */
67   PetscCall(TaoCreate(PETSC_COMM_SELF, &tao));
68 
69   /* Create starting point and initialize */
70   PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->n, &X));
71   PetscCall(PetscObjectSetName((PetscObject)X, "X0"));
72   PetscCall(PetscMatlabEngineGet(user->mengine, (PetscObject)X));
73   PetscCall(TaoSetSolution(tao, X));
74 
75   /* Create residuals vector and set residual function */
76   PetscCall(VecCreateSeq(PETSC_COMM_SELF, user->m, &F));
77   PetscCall(PetscObjectSetName((PetscObject)F, "F"));
78   PetscCall(TaoSetResidualRoutine(tao, F, EvaluateResidual, (void *)user));
79 
80   /* Create Jacobian matrix and set residual Jacobian routine */
81   PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, user->m, user->n, user->n, NULL, &J));
82   PetscCall(PetscObjectSetName((PetscObject)J, "J"));
83   PetscCall(TaoSetJacobianResidualRoutine(tao, J, J, EvaluateJacobian, (void *)user));
84 
85   /* Solve the problem */
86   PetscCall(TaoSetType(tao, TAOPOUNDERS));
87   PetscCall(TaoSetMaximumFunctionEvaluations(tao, user->nfmax));
88   PetscCall(TaoSetFromOptions(tao));
89   PetscCall(TaoSolve(tao));
90 
91   /* Finish the problem */
92   PetscCall(MatDestroy(&J));
93   PetscCall(VecDestroy(&X));
94   PetscCall(VecDestroy(&F));
95   PetscCall(TaoDestroy(&tao));
96   PetscFunctionReturn(PETSC_SUCCESS);
97 }
98 
99 int main(int argc, char **argv)
100 {
101   AppCtx      user;
102   PetscScalar tmp;
103   PetscInt    prob_id = 0;
104   PetscBool   flg, testall = PETSC_FALSE;
105   int         i, i0, imax;
106 
107   PetscFunctionBeginUser;
108   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
109   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_all", &testall, NULL));
110   PetscCall(PetscOptionsGetInt(NULL, NULL, "-prob_id", &prob_id, &flg));
111   if (!testall) {
112     if (!flg) {
113       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Problem number must be specified with -prob_id");
114     } else if ((prob_id < 1) || (prob_id > 53)) {
115       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Problem number must be between 1 and 53!");
116     } else {
117       PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running problem %d\n", prob_id));
118     }
119   } else {
120     PetscCall(PetscPrintf(PETSC_COMM_SELF, "Running all problems\n"));
121   }
122 
123   PetscCall(PetscMatlabEngineCreate(PETSC_COMM_SELF, NULL, &user.mengine));
124   PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingInitialize"));
125 
126   if (testall) {
127     i0   = 1;
128     imax = 53;
129   } else {
130     i0   = (int)prob_id;
131     imax = (int)prob_id;
132   }
133 
134   for (i = i0; i <= imax; ++i) {
135     PetscCall(PetscPrintf(PETSC_COMM_SELF, "%d\n", i));
136     PetscCall(PetscMatlabEngineEvaluate(user.mengine, "np = %d; ProblemInitialize", i));
137     PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "n"));
138     user.n = (int)tmp;
139     PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "m"));
140     user.m = (int)tmp;
141     PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "nfmax"));
142     user.nfmax = (int)tmp;
143     PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "npmax"));
144     user.npmax = (int)tmp;
145     PetscCall(PetscMatlabEngineGetArray(user.mengine, 1, 1, &tmp, "delta"));
146     user.delta = (double)tmp;
147 
148     /* Ignore return code for now -- do not stop testing on inf or nan errors */
149     PetscCall(TaoPounders(&user));
150 
151     PetscCall(PetscMatlabEngineEvaluate(user.mengine, "ProblemFinalize"));
152   }
153 
154   PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingFinalize"));
155   PetscCall(PetscMatlabEngineDestroy(&user.mengine));
156   PetscCall(PetscFinalize());
157   return 0;
158 }
159 
160 /*TEST
161 
162    build:
163       requires: matlab
164 
165    test:
166       localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m
167       args: -tao_monitor_short -prob_id 5
168 
169 TEST*/
170