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 /* 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)); 64 65 /* Create the TAO objects and set the type */ 66 PetscCall(TaoCreate(PETSC_COMM_SELF, &tao)); 67 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)); 73 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)); 78 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)); 83 84 /* Solve the problem */ 85 PetscCall(TaoSetType(tao, TAOPOUNDERS)); 86 PetscCall(TaoSetMaximumFunctionEvaluations(tao, user->nfmax)); 87 PetscCall(TaoSetFromOptions(tao)); 88 PetscCall(TaoSolve(tao)); 89 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 } 97 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; 105 106 PetscFunctionBeginUser; 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 163 164 test: 165 localrunfiles: more_wild_probs TestingInitialize.m TestingFinalize.m ProblemInitialize.m ProblemFinalize.m 166 args: -tao_monitor_short -prob_id 5 167 168 TEST*/ 169