xref: /petsc/src/tao/leastsquares/tutorials/matlab/matlab_ls_test.c (revision 732aec7a18f2199fb53bb9a2f3aef439a834ce31)
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