xref: /petsc/src/tao/leastsquares/tutorials/matlab/matlab_ls_test.c (revision 503c0ea9b45bcfbcebbb1ea5341243bbc69f0bea)
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(0);
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(0);
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   sprintf(buf,"%d",user->npmax);
62   PetscCall(PetscOptionsSetValue(NULL,"-tao_pounders_npmax",buf));
63   sprintf(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(0);
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   PetscCall(PetscInitialize(&argc,&argv,(char*)0,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_engine
163 
164    test:
165       localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m
166       args: -tao_smonitor -prob_id 5
167 
168 TEST*/
169