Actual source code: matlab_ls_test.c

  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";

 11: #include <petsctao.h>
 12: #include <petscmatlab.h>

 14: typedef struct {
 15:   PetscMatlabEngine mengine;

 17:   double delta; /* Initial trust region radius */

 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;

 25: static PetscErrorCode EvaluateResidual(Tao tao, Vec X, Vec F, void *ptr)
 26: {
 27:   AppCtx *user = (AppCtx *)ptr;

 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: }

 38: static PetscErrorCode EvaluateJacobian(Tao tao, Vec X, Mat J, Mat JPre, void *ptr)
 39: {
 40:   AppCtx *user = (AppCtx *)ptr;

 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: }

 51: static PetscErrorCode TaoPounders(AppCtx *user)
 52: {
 53:   Tao  tao;
 54:   Vec  X, F;
 55:   Mat  J;
 56:   char buf[1024];

 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));

 65:   /* Create the TAO objects and set the type */
 66:   PetscCall(TaoCreate(PETSC_COMM_SELF, &tao));

 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));

 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));

 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));

 84:   /* Solve the problem */
 85:   PetscCall(TaoSetType(tao, TAOPOUNDERS));
 86:   PetscCall(TaoSetMaximumFunctionEvaluations(tao, user->nfmax));
 87:   PetscCall(TaoSetFromOptions(tao));
 88:   PetscCall(TaoSolve(tao));

 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: }

 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;

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:   }

122:   PetscCall(PetscMatlabEngineCreate(PETSC_COMM_SELF, NULL, &user.mengine));
123:   PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingInitialize"));

125:   if (testall) {
126:     i0   = 1;
127:     imax = 53;
128:   } else {
129:     i0   = (int)prob_id;
130:     imax = (int)prob_id;
131:   }

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;

147:     /* Ignore return code for now -- do not stop testing on inf or nan errors */
148:     PetscCall(TaoPounders(&user));

150:     PetscCall(PetscMatlabEngineEvaluate(user.mengine, "ProblemFinalize"));
151:   }

153:   PetscCall(PetscMatlabEngineEvaluate(user.mengine, "TestingFinalize"));
154:   PetscCall(PetscMatlabEngineDestroy(&user.mengine));
155:   PetscCall(PetscFinalize());
156:   return 0;
157: }

159: /*TEST

161:    build:
162:       requires: matlab

164:    test:
165:       localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m
166:       args: -tao_monitor_short -prob_id 5

168: TEST*/