1 #include <petsctaolinesearch.h> 2 #include <../src/tao/unconstrained/impls/lmvm/lmvm.h> 3 #include <../src/tao/bound/impls/blmvm/blmvm.h> 4 5 #define BLMVM_STEP_BFGS 0 6 #define BLMVM_STEP_GRAD 1 7 8 #define BLMVM_AS_NONE 0 9 #define BLMVM_AS_BERTSEKAS 1 10 #define BLMVM_AS_SIZE 2 11 12 static const char *BLMVM_AS_TYPE[64] = {"none", "bertsekas"}; 13 14 PETSC_INTERN PetscErrorCode TaoBLMVMEstimateActiveSet(Tao tao, PetscInt asType) 15 { 16 PetscErrorCode ierr; 17 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 18 19 PetscFunctionBegin; 20 if (!tao->bounded) PetscFunctionReturn(0); 21 switch (asType) { 22 case BLMVM_AS_NONE: 23 ierr = ISDestroy(&blmP->inactive_idx);CHKERRQ(ierr); 24 ierr = VecWhichInactive(tao->XL, tao->solution, blmP->unprojected_gradient, tao->XU, PETSC_TRUE, &blmP->inactive_idx);CHKERRQ(ierr); 25 ierr = ISDestroy(&blmP->active_idx);CHKERRQ(ierr); 26 ierr = ISComplementVec(blmP->inactive_idx, tao->solution, &blmP->active_idx);CHKERRQ(ierr); 27 break; 28 29 case BLMVM_AS_BERTSEKAS: 30 /* Use gradient descent to estimate the active set */ 31 ierr = VecCopy(blmP->unprojected_gradient, blmP->W);CHKERRQ(ierr); 32 ierr = VecScale(blmP->W, -1.0);CHKERRQ(ierr); 33 ierr = TaoEstimateActiveBounds(tao->solution, tao->XL, tao->XU, blmP->unprojected_gradient, blmP->W, blmP->work, blmP->as_step, &blmP->as_tol, 34 &blmP->active_lower, &blmP->active_upper, &blmP->active_fixed, &blmP->active_idx, &blmP->inactive_idx);CHKERRQ(ierr); 35 break; 36 37 default: 38 break; 39 } 40 PetscFunctionReturn(0); 41 } 42 43 PETSC_INTERN PetscErrorCode TaoBLMVMBoundStep(Tao tao, PetscInt asType, Vec step) 44 { 45 PetscErrorCode ierr; 46 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 47 48 PetscFunctionBegin; 49 if (!tao->bounded) PetscFunctionReturn(0); 50 switch (asType) { 51 case BLMVM_AS_NONE: 52 ierr = VecISSet(step, blmP->active_idx, 0.0);CHKERRQ(ierr); 53 break; 54 55 case BLMVM_AS_BERTSEKAS: 56 ierr = TaoBoundStep(tao->solution, tao->XL, tao->XU, blmP->active_lower, blmP->active_upper, blmP->active_fixed, 1.0, step);CHKERRQ(ierr); 57 break; 58 59 default: 60 break; 61 } 62 PetscFunctionReturn(0); 63 } 64 65 /*------------------------------------------------------------*/ 66 PETSC_INTERN PetscErrorCode TaoSolve_BLMVM(Tao tao) 67 { 68 PetscErrorCode ierr; 69 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 70 TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 71 PetscReal f, fold, gdx, gnorm, resnorm; 72 PetscReal stepsize = 1.0; 73 PetscInt nDiff, nupdates, stepType = BLMVM_STEP_GRAD; 74 75 PetscFunctionBegin; 76 /* Project initial point onto bounds */ 77 ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 78 ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 79 if (tao->bounded) { 80 ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 81 } 82 83 /* Check convergence criteria */ 84 ierr = TaoComputeObjectiveAndGradient(tao, tao->solution,&f,blmP->unprojected_gradient);CHKERRQ(ierr); 85 ierr = VecBoundGradientProjection(blmP->unprojected_gradient,tao->solution, tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); 86 87 ierr = TaoGradientNorm(tao, blmP->unprojected_gradient,NORM_2,&gnorm);CHKERRQ(ierr); 88 if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 89 90 tao->reason = TAO_CONTINUE_ITERATING; 91 ierr = VecFischer(tao->solution, blmP->unprojected_gradient, tao->XL, tao->XU, blmP->W);CHKERRQ(ierr); 92 ierr = VecNorm(blmP->W, NORM_2, &resnorm);CHKERRQ(ierr); 93 ierr = TaoLogConvergenceHistory(tao,f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 94 ierr = TaoMonitor(tao,tao->niter,f,resnorm,0.0,stepsize);CHKERRQ(ierr); 95 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 96 if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 97 98 /* Set counter for gradient/reset steps */ 99 if (!blmP->recycle) { 100 blmP->bfgs = 0; 101 blmP->grad = 0; 102 ierr = MatLMVMReset(blmP->M, PETSC_FALSE);CHKERRQ(ierr); 103 } 104 105 /* Have not converged; continue with Newton method */ 106 while (tao->reason == TAO_CONTINUE_ITERATING) { 107 /* Estimate active set at the current iterate */ 108 ierr = TaoBLMVMEstimateActiveSet(tao, blmP->as_type);CHKERRQ(ierr); 109 110 /* Compute direction */ 111 if (blmP->H0) { 112 ierr = MatLMVMSetJ0(blmP->M, blmP->H0);CHKERRQ(ierr); 113 stepType = BLMVM_STEP_BFGS; 114 } else if (!blmP->no_scale) { 115 ierr = MatLMVMSetJ0(blmP->M, blmP->Mscale);CHKERRQ(ierr); 116 } 117 ierr = MatLMVMUpdate(blmP->M, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); 118 ierr = VecCopy(blmP->unprojected_gradient, blmP->red_grad);CHKERRQ(ierr); 119 ierr = VecISSet(blmP->red_grad, blmP->active_idx, 0.0);CHKERRQ(ierr); 120 ierr = MatSolve(blmP->M, blmP->red_grad, tao->stepdirection);CHKERRQ(ierr); 121 ierr = VecScale(tao->stepdirection,-1.0);CHKERRQ(ierr); 122 ierr = TaoBLMVMBoundStep(tao, blmP->as_type, tao->stepdirection);CHKERRQ(ierr); 123 ierr = MatLMVMGetUpdateCount(blmP->M, &nupdates);CHKERRQ(ierr); 124 if (nupdates > 0) stepType = BLMVM_STEP_BFGS; 125 126 /* Check for success (descent direction) */ 127 ierr = VecDot(tao->stepdirection, blmP->red_grad, &gdx);CHKERRQ(ierr); 128 if (gdx >= 0 || PetscIsInfOrNanReal(gdx)) { 129 /* Step is not descent or solve was not successful 130 Use steepest descent direction (scaled) */ 131 ierr = MatLMVMReset(blmP->M, PETSC_FALSE);CHKERRQ(ierr); 132 ierr = MatLMVMClearJ0(blmP->M);CHKERRQ(ierr); 133 ierr = MatLMVMUpdate(blmP->M, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); 134 ierr = MatSolve(blmP->M, blmP->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 135 ierr = VecScale(tao->stepdirection,-1.0);CHKERRQ(ierr); 136 ierr = TaoBLMVMBoundStep(tao, blmP->as_type, tao->stepdirection);CHKERRQ(ierr); 137 stepType = BLMVM_STEP_GRAD; 138 } 139 140 /* Perform the linesearch */ 141 fold = f; 142 ierr = VecCopy(tao->solution, blmP->Xold);CHKERRQ(ierr); 143 ierr = VecCopy(blmP->unprojected_gradient, blmP->Gold);CHKERRQ(ierr); 144 ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, blmP->unprojected_gradient, tao->stepdirection, &stepsize, &ls_status);CHKERRQ(ierr); 145 ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 146 147 if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER && stepType != BLMVM_STEP_GRAD) { 148 /* Linesearch failed 149 Reset factors and use scaled (projected) gradient step */ 150 f = fold; 151 ierr = VecCopy(blmP->Xold, tao->solution);CHKERRQ(ierr); 152 ierr = VecCopy(blmP->Gold, blmP->unprojected_gradient);CHKERRQ(ierr); 153 154 ierr = MatLMVMReset(blmP->M, PETSC_FALSE);CHKERRQ(ierr); 155 ierr = MatLMVMClearJ0(blmP->M);CHKERRQ(ierr); 156 ierr = MatLMVMUpdate(blmP->M, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); 157 ierr = MatSolve(blmP->M, blmP->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 158 ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 159 ierr = TaoBLMVMBoundStep(tao, blmP->as_type, tao->stepdirection);CHKERRQ(ierr); 160 stepType = BLMVM_STEP_GRAD; 161 162 ierr = TaoLineSearchApply(tao->linesearch,tao->solution,&f, blmP->unprojected_gradient, tao->stepdirection, &stepsize, &ls_status);CHKERRQ(ierr); 163 ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 164 } 165 166 if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { 167 /* Line search failed on a gradient step, so just mark reason for divergence */ 168 f = fold; 169 ierr = VecCopy(blmP->Xold, tao->solution);CHKERRQ(ierr); 170 ierr = VecCopy(blmP->Gold, blmP->unprojected_gradient);CHKERRQ(ierr); 171 tao->reason = TAO_DIVERGED_LS_FAILURE; 172 } else { 173 /* LS found valid step, so tally the step type and compute projected gradient */ 174 switch (stepType) { 175 case BLMVM_STEP_BFGS: 176 ++blmP->bfgs; 177 break; 178 case BLMVM_STEP_GRAD: 179 ++blmP->grad; 180 break; 181 default: 182 break; 183 } 184 ierr = VecBoundGradientProjection(blmP->unprojected_gradient, tao->solution, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr); 185 ierr = TaoGradientNorm(tao, blmP->unprojected_gradient,NORM_2,&gnorm);CHKERRQ(ierr); 186 if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Not-a-Number"); 187 } 188 189 /* Check for converged */ 190 tao->niter++; 191 ierr = VecFischer(tao->solution, blmP->unprojected_gradient, tao->XL, tao->XU, blmP->W);CHKERRQ(ierr); 192 ierr = VecNorm(blmP->W, NORM_2, &resnorm);CHKERRQ(ierr); 193 ierr = TaoLogConvergenceHistory(tao,f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 194 ierr = TaoMonitor(tao,tao->niter,f,resnorm,0.0,stepsize);CHKERRQ(ierr); 195 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 196 } 197 PetscFunctionReturn(0); 198 } 199 200 PETSC_INTERN PetscErrorCode TaoSetup_BLMVM(Tao tao) 201 { 202 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 203 PetscInt n,N; 204 PetscErrorCode ierr; 205 206 PetscFunctionBegin; 207 /* Existence of tao->solution checked in TaoSetup() */ 208 ierr = VecDuplicate(tao->solution,&blmP->Xold);CHKERRQ(ierr); 209 ierr = VecDuplicate(tao->solution,&blmP->Gold);CHKERRQ(ierr); 210 ierr = VecDuplicate(tao->solution, &blmP->unprojected_gradient);CHKERRQ(ierr); 211 ierr = VecDuplicate(tao->solution, &blmP->W);CHKERRQ(ierr); 212 ierr = VecDuplicate(tao->solution, &blmP->work);CHKERRQ(ierr); 213 ierr = VecDuplicate(tao->solution, &blmP->red_grad);CHKERRQ(ierr); 214 215 if (!tao->stepdirection) { 216 ierr = VecDuplicate(tao->solution, &tao->stepdirection);CHKERRQ(ierr); 217 } 218 if (!tao->gradient) { 219 ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); 220 } 221 /* Create matrix for the limited memory approximation */ 222 ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 223 ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 224 ierr = MatSetSizes(blmP->M, n, n, N, N);CHKERRQ(ierr); 225 ierr = MatLMVMAllocate(blmP->M,tao->solution,blmP->unprojected_gradient);CHKERRQ(ierr); 226 227 /* If the user has set a matrix to solve as the initial H0, set the options prefix here, and set up the KSP */ 228 if (blmP->H0) { 229 ierr = MatLMVMSetJ0(blmP->M, blmP->H0);CHKERRQ(ierr); 230 } else if (!blmP->no_scale) { 231 if (!blmP->Mscale) { 232 ierr = MatCreate(PetscObjectComm((PetscObject)blmP->M), &blmP->Mscale);CHKERRQ(ierr); 233 ierr = MatSetType(blmP->Mscale, MATLMVMDIAGBRDN);CHKERRQ(ierr); 234 ierr = MatSetOptionsPrefix(blmP->Mscale, "tao_blmvm_scale_");CHKERRQ(ierr); 235 ierr = MatSetFromOptions(blmP->Mscale);CHKERRQ(ierr); 236 ierr = MatLMVMAllocate(blmP->Mscale, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); 237 } 238 ierr = MatLMVMSetJ0(blmP->M, blmP->Mscale);CHKERRQ(ierr); 239 } 240 PetscFunctionReturn(0); 241 } 242 243 /* ---------------------------------------------------------- */ 244 PETSC_INTERN PetscErrorCode TaoDestroy_BLMVM(Tao tao) 245 { 246 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 247 PetscErrorCode ierr; 248 249 PetscFunctionBegin; 250 if (tao->setupcalled) { 251 ierr = VecDestroy(&blmP->unprojected_gradient);CHKERRQ(ierr); 252 ierr = VecDestroy(&blmP->Xold);CHKERRQ(ierr); 253 ierr = VecDestroy(&blmP->Gold);CHKERRQ(ierr); 254 ierr = VecDestroy(&blmP->W);CHKERRQ(ierr); 255 ierr = VecDestroy(&blmP->work);CHKERRQ(ierr); 256 ierr = VecDestroy(&blmP->red_grad);CHKERRQ(ierr); 257 } 258 ierr = ISDestroy(&blmP->active_lower);CHKERRQ(ierr); 259 ierr = ISDestroy(&blmP->active_upper);CHKERRQ(ierr); 260 ierr = ISDestroy(&blmP->active_fixed);CHKERRQ(ierr); 261 ierr = ISDestroy(&blmP->active_idx);CHKERRQ(ierr); 262 ierr = ISDestroy(&blmP->inactive_idx);CHKERRQ(ierr); 263 ierr = MatDestroy(&blmP->M);CHKERRQ(ierr); 264 if (blmP->H0) { 265 PetscObjectDereference((PetscObject)blmP->H0); 266 } 267 if (blmP->Mscale) { 268 ierr = MatDestroy(&blmP->Mscale);CHKERRQ(ierr); 269 } 270 ierr = PetscFree(tao->data);CHKERRQ(ierr); 271 PetscFunctionReturn(0); 272 } 273 274 /*------------------------------------------------------------*/ 275 PETSC_INTERN PetscErrorCode TaoSetFromOptions_BLMVM(PetscOptionItems* PetscOptionsObject,Tao tao) 276 { 277 TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; 278 PetscErrorCode ierr; 279 PetscBool is_lmvm, is_spd; 280 281 PetscFunctionBegin; 282 ierr = PetscOptionsHead(PetscOptionsObject,"Limited-memory variable-metric method for bound constrained optimization");CHKERRQ(ierr); 283 ierr = PetscOptionsBool("-tao_blmvm_recycle","enable recycling of the BFGS matrix between subsequent TaoSolve() calls","",blmP->recycle,&blmP->recycle,NULL);CHKERRQ(ierr); 284 ierr = PetscOptionsBool("-tao_blmvm_no_scale","(developer) disable the diagonal Broyden scaling of the BFGS approximation","",blmP->no_scale,&blmP->no_scale,NULL);CHKERRQ(ierr); 285 ierr = PetscOptionsEList("-tao_blmvm_as_type","active set estimation method", "", BLMVM_AS_TYPE, BLMVM_AS_SIZE, BLMVM_AS_TYPE[blmP->as_type], &blmP->as_type,NULL);CHKERRQ(ierr); 286 ierr = PetscOptionsReal("-tao_blmvm_as_tol", "initial tolerance used when estimating actively bounded variables","",blmP->as_tol,&blmP->as_tol,NULL);CHKERRQ(ierr); 287 ierr = PetscOptionsReal("-tao_blmvm_as_step", "step length used when estimating actively bounded variables","",blmP->as_step,&blmP->as_step,NULL);CHKERRQ(ierr); 288 ierr = PetscOptionsTail();CHKERRQ(ierr); 289 ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 290 ierr = MatSetFromOptions(blmP->M);CHKERRQ(ierr); 291 if (!blmP->no_scale) { 292 } 293 ierr = PetscObjectBaseTypeCompare((PetscObject)blmP->M, MATLMVM, &is_lmvm);CHKERRQ(ierr); 294 if (!is_lmvm) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "Matrix must be an LMVM-type"); 295 ierr = MatGetOption(blmP->M, MAT_SPD, &is_spd);CHKERRQ(ierr); 296 if (!is_spd) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix must be symmetric positive-definite"); 297 PetscFunctionReturn(0); 298 } 299 300 /*------------------------------------------------------------*/ 301 PETSC_INTERN PetscErrorCode TaoView_BLMVM(Tao tao, PetscViewer viewer) 302 { 303 TAO_BLMVM *lmP = (TAO_BLMVM *)tao->data; 304 PetscBool isascii; 305 PetscErrorCode ierr; 306 PetscInt recycled_its; 307 308 PetscFunctionBegin; 309 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 310 if (isascii) { 311 ierr = PetscViewerASCIIPrintf(viewer, " Gradient steps: %D\n", lmP->grad);CHKERRQ(ierr); 312 if (lmP->recycle) { 313 ierr = PetscViewerASCIIPrintf(viewer, " Recycle: on\n");CHKERRQ(ierr); 314 recycled_its = lmP->bfgs + lmP->grad; 315 ierr = PetscViewerASCIIPrintf(viewer, " Total recycled iterations: %D\n", recycled_its);CHKERRQ(ierr); 316 } 317 ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 318 ierr = MatView(lmP->M, viewer);CHKERRQ(ierr); 319 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 320 } 321 PetscFunctionReturn(0); 322 } 323 324 PETSC_INTERN PetscErrorCode TaoComputeDual_BLMVM(Tao tao, Vec DXL, Vec DXU) 325 { 326 TAO_BLMVM *blm = (TAO_BLMVM *) tao->data; 327 PetscErrorCode ierr; 328 329 PetscFunctionBegin; 330 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 331 PetscValidHeaderSpecific(DXL,VEC_CLASSID,2); 332 PetscValidHeaderSpecific(DXU,VEC_CLASSID,3); 333 if (!tao->gradient || !blm->unprojected_gradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Dual variables don't exist yet or no longer exist.\n"); 334 335 ierr = VecCopy(tao->gradient,DXL);CHKERRQ(ierr); 336 ierr = VecAXPY(DXL,-1.0,blm->unprojected_gradient);CHKERRQ(ierr); 337 ierr = VecSet(DXU,0.0);CHKERRQ(ierr); 338 ierr = VecPointwiseMax(DXL,DXL,DXU);CHKERRQ(ierr); 339 340 ierr = VecCopy(blm->unprojected_gradient,DXU);CHKERRQ(ierr); 341 ierr = VecAXPY(DXU,-1.0,tao->gradient);CHKERRQ(ierr); 342 ierr = VecAXPY(DXU,1.0,DXL);CHKERRQ(ierr); 343 PetscFunctionReturn(0); 344 } 345 346 /* ---------------------------------------------------------- */ 347 /*MC 348 TAOBLMVM - Bounded limited memory variable metric is a quasi-Newton method 349 for nonlinear minimization with bound constraints. It is an extension 350 of TAOLMVM 351 352 Options Database Keys: 353 . -tao_blmvm_recycle - enable recycling LMVM updates between TaoSolve() calls 354 . -tao_blmvm_no_scale - (developer) disables diagonal Broyden scaling on the LMVM approximation 355 . -tao_blmvm_as_type - (developer) active set estimation method <none,bertsekas> 356 . -tao_blmvm_as_tol - (developer) initial distance tolerance used when estimating the active set 357 . -tao_blmvm_as_step - (developer) trial step length used when estimating the active set 358 359 Level: beginner 360 M*/ 361 PETSC_EXTERN PetscErrorCode TaoCreate_BLMVM(Tao tao) 362 { 363 TAO_BLMVM *blmP; 364 const char *morethuente_type = TAOLINESEARCHMT; 365 PetscErrorCode ierr; 366 367 PetscFunctionBegin; 368 tao->ops->setup = TaoSetup_BLMVM; 369 tao->ops->solve = TaoSolve_BLMVM; 370 tao->ops->view = TaoView_BLMVM; 371 tao->ops->setfromoptions = TaoSetFromOptions_BLMVM; 372 tao->ops->destroy = TaoDestroy_BLMVM; 373 tao->ops->computedual = TaoComputeDual_BLMVM; 374 375 ierr = PetscNewLog(tao,&blmP);CHKERRQ(ierr); 376 blmP->H0 = NULL; 377 blmP->as_step = 0.001; 378 blmP->as_tol = 0.001; 379 blmP->as_type = BLMVM_AS_BERTSEKAS; 380 blmP->recycle = PETSC_FALSE; 381 blmP->no_scale = PETSC_FALSE; 382 383 tao->data = (void*)blmP; 384 385 /* Override default settings (unless already changed) */ 386 if (!tao->max_it_changed) tao->max_it = 2000; 387 if (!tao->max_funcs_changed) tao->max_funcs = 4000; 388 389 ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr); 390 ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 391 ierr = TaoLineSearchSetType(tao->linesearch, morethuente_type);CHKERRQ(ierr); 392 ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 393 ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 394 395 ierr = KSPInitializePackage();CHKERRQ(ierr); 396 ierr = MatCreate(((PetscObject)tao)->comm, &blmP->M);CHKERRQ(ierr); 397 ierr = PetscObjectIncrementTabLevel((PetscObject)blmP->M, (PetscObject)tao, 1);CHKERRQ(ierr); 398 ierr = MatSetType(blmP->M, MATLMVMBFGS);CHKERRQ(ierr); 399 ierr = MatSetOptionsPrefix(blmP->M, "tao_blmvm_");CHKERRQ(ierr); 400 PetscFunctionReturn(0); 401 } 402 403 PETSC_EXTERN PetscErrorCode TaoBLMVMSetH0(Tao tao, Mat H0) 404 { 405 TAO_LMVM *lmP; 406 TAO_BLMVM *blmP; 407 TaoType type; 408 PetscBool is_lmvm, is_blmvm; 409 PetscErrorCode ierr; 410 411 ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 412 ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 413 ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 414 415 if (is_lmvm) { 416 lmP = (TAO_LMVM *)tao->data; 417 ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 418 lmP->H0 = H0; 419 } else if (is_blmvm) { 420 blmP = (TAO_BLMVM *)tao->data; 421 ierr = PetscObjectReference((PetscObject)H0);CHKERRQ(ierr); 422 blmP->H0 = H0; 423 } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 424 PetscFunctionReturn(0); 425 } 426 427 PETSC_EXTERN PetscErrorCode TaoBLMVMGetH0(Tao tao, Mat *H0) 428 { 429 TAO_LMVM *lmP; 430 TAO_BLMVM *blmP; 431 TaoType type; 432 PetscBool is_lmvm, is_blmvm; 433 Mat M; 434 435 PetscErrorCode ierr; 436 437 ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 438 ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 439 ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 440 441 if (is_lmvm) { 442 lmP = (TAO_LMVM *)tao->data; 443 M = lmP->M; 444 } else if (is_blmvm) { 445 blmP = (TAO_BLMVM *)tao->data; 446 M = blmP->M; 447 } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 448 ierr = MatLMVMGetJ0(M, H0);CHKERRQ(ierr); 449 PetscFunctionReturn(0); 450 } 451 452 PETSC_EXTERN PetscErrorCode TaoBLMVMGetH0KSP(Tao tao, KSP *ksp) 453 { 454 TAO_LMVM *lmP; 455 TAO_BLMVM *blmP; 456 TaoType type; 457 PetscBool is_lmvm, is_blmvm; 458 Mat M; 459 PetscErrorCode ierr; 460 461 ierr = TaoGetType(tao, &type);CHKERRQ(ierr); 462 ierr = PetscStrcmp(type, TAOLMVM, &is_lmvm);CHKERRQ(ierr); 463 ierr = PetscStrcmp(type, TAOBLMVM, &is_blmvm);CHKERRQ(ierr); 464 465 if (is_lmvm) { 466 lmP = (TAO_LMVM *)tao->data; 467 M = lmP->M; 468 } else if (is_blmvm) { 469 blmP = (TAO_BLMVM *)tao->data; 470 M = blmP->M; 471 } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "This routine applies to TAO_LMVM and TAO_BLMVM."); 472 ierr = MatLMVMGetJ0KSP(M, ksp);CHKERRQ(ierr); 473 PetscFunctionReturn(0); 474 } 475