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