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