174962610SAlp Dener /* 274962610SAlp Dener This file implements a Mehrotra predictor-corrector method for 374962610SAlp Dener bound-constrained quadratic programs. 474962610SAlp Dener 574962610SAlp Dener */ 674962610SAlp Dener 774962610SAlp Dener #include <../src/tao/quadratic/impls/bqpip/bqpipimpl.h> 874962610SAlp Dener #include <petscksp.h> 974962610SAlp Dener 1074962610SAlp Dener static PetscErrorCode QPIPComputeResidual(TAO_BQPIP *qp,Tao tao) 1174962610SAlp Dener { 1274962610SAlp Dener PetscErrorCode ierr; 1374962610SAlp Dener PetscReal dtmp = 1.0 - qp->psteplength; 1474962610SAlp Dener 1574962610SAlp Dener PetscFunctionBegin; 1674962610SAlp Dener /* Compute R3 and R5 */ 1774962610SAlp Dener 1874962610SAlp Dener ierr = VecScale(qp->R3,dtmp);CHKERRQ(ierr); 1974962610SAlp Dener ierr = VecScale(qp->R5,dtmp);CHKERRQ(ierr); 2074962610SAlp Dener qp->pinfeas=dtmp*qp->pinfeas; 2174962610SAlp Dener 2274962610SAlp Dener ierr = VecCopy(qp->S,tao->gradient);CHKERRQ(ierr); 2374962610SAlp Dener ierr = VecAXPY(tao->gradient,-1.0,qp->Z);CHKERRQ(ierr); 2474962610SAlp Dener 2574962610SAlp Dener ierr = MatMult(tao->hessian,tao->solution,qp->RHS);CHKERRQ(ierr); 2674962610SAlp Dener ierr = VecScale(qp->RHS,-1.0);CHKERRQ(ierr); 2774962610SAlp Dener ierr = VecAXPY(qp->RHS,-1.0,qp->C);CHKERRQ(ierr); 2874962610SAlp Dener ierr = VecAXPY(tao->gradient,-1.0,qp->RHS);CHKERRQ(ierr); 2974962610SAlp Dener 3074962610SAlp Dener ierr = VecNorm(tao->gradient,NORM_1,&qp->dinfeas);CHKERRQ(ierr); 3174962610SAlp Dener qp->rnorm=(qp->dinfeas+qp->pinfeas)/(qp->m+qp->n); 3274962610SAlp Dener PetscFunctionReturn(0); 3374962610SAlp Dener } 3474962610SAlp Dener 3574962610SAlp Dener static PetscErrorCode QPIPSetInitialPoint(TAO_BQPIP *qp, Tao tao) 3674962610SAlp Dener { 3774962610SAlp Dener PetscErrorCode ierr; 3874962610SAlp Dener PetscReal two=2.0,p01=1; 3974962610SAlp Dener PetscReal gap1,gap2,fff,mu; 4074962610SAlp Dener 4174962610SAlp Dener PetscFunctionBegin; 4274962610SAlp Dener /* Compute function, Gradient R=Hx+b, and Hessian */ 4374962610SAlp Dener ierr = MatMult(tao->hessian,tao->solution,tao->gradient);CHKERRQ(ierr); 4474962610SAlp Dener ierr = VecCopy(qp->C,qp->Work);CHKERRQ(ierr); 4574962610SAlp Dener ierr = VecAXPY(qp->Work,0.5,tao->gradient);CHKERRQ(ierr); 4674962610SAlp Dener ierr = VecAXPY(tao->gradient,1.0,qp->C);CHKERRQ(ierr); 4774962610SAlp Dener ierr = VecDot(tao->solution,qp->Work,&fff);CHKERRQ(ierr); 4874962610SAlp Dener qp->pobj = fff + qp->d; 4974962610SAlp Dener 5074962610SAlp Dener if (PetscIsInfOrNanReal(qp->pobj)) SETERRQ(PETSC_COMM_SELF,1, "User provided data contains Inf or NaN"); 5174962610SAlp Dener 5274962610SAlp Dener /* Initialize slack vectors */ 5374962610SAlp Dener /* T = XU - X; G = X - XL */ 5474962610SAlp Dener ierr = VecCopy(qp->XU,qp->T);CHKERRQ(ierr); 5574962610SAlp Dener ierr = VecAXPY(qp->T,-1.0,tao->solution);CHKERRQ(ierr); 5674962610SAlp Dener ierr = VecCopy(tao->solution,qp->G);CHKERRQ(ierr); 5774962610SAlp Dener ierr = VecAXPY(qp->G,-1.0,qp->XL);CHKERRQ(ierr); 5874962610SAlp Dener 5974962610SAlp Dener ierr = VecSet(qp->GZwork,p01);CHKERRQ(ierr); 6074962610SAlp Dener ierr = VecSet(qp->TSwork,p01);CHKERRQ(ierr); 6174962610SAlp Dener 6274962610SAlp Dener ierr = VecPointwiseMax(qp->G,qp->G,qp->GZwork);CHKERRQ(ierr); 6374962610SAlp Dener ierr = VecPointwiseMax(qp->T,qp->T,qp->TSwork);CHKERRQ(ierr); 6474962610SAlp Dener 6574962610SAlp Dener /* Initialize Dual Variable Vectors */ 6674962610SAlp Dener ierr = VecCopy(qp->G,qp->Z);CHKERRQ(ierr); 6774962610SAlp Dener ierr = VecReciprocal(qp->Z);CHKERRQ(ierr); 6874962610SAlp Dener 6974962610SAlp Dener ierr = VecCopy(qp->T,qp->S);CHKERRQ(ierr); 7074962610SAlp Dener ierr = VecReciprocal(qp->S);CHKERRQ(ierr); 7174962610SAlp Dener 7274962610SAlp Dener ierr = MatMult(tao->hessian,qp->Work,qp->RHS);CHKERRQ(ierr); 7374962610SAlp Dener ierr = VecAbs(qp->RHS);CHKERRQ(ierr); 7474962610SAlp Dener ierr = VecSet(qp->Work,p01);CHKERRQ(ierr); 7574962610SAlp Dener ierr = VecPointwiseMax(qp->RHS,qp->RHS,qp->Work);CHKERRQ(ierr); 7674962610SAlp Dener 7774962610SAlp Dener ierr = VecPointwiseDivide(qp->RHS,tao->gradient,qp->RHS);CHKERRQ(ierr); 7874962610SAlp Dener ierr = VecNorm(qp->RHS,NORM_1,&gap1);CHKERRQ(ierr); 7974962610SAlp Dener mu = PetscMin(10.0,(gap1+10.0)/qp->m); 8074962610SAlp Dener 8174962610SAlp Dener ierr = VecScale(qp->S,mu);CHKERRQ(ierr); 8274962610SAlp Dener ierr = VecScale(qp->Z,mu);CHKERRQ(ierr); 8374962610SAlp Dener 8474962610SAlp Dener ierr = VecSet(qp->TSwork,p01);CHKERRQ(ierr); 8574962610SAlp Dener ierr = VecSet(qp->GZwork,p01);CHKERRQ(ierr); 8674962610SAlp Dener ierr = VecPointwiseMax(qp->S,qp->S,qp->TSwork);CHKERRQ(ierr); 8774962610SAlp Dener ierr = VecPointwiseMax(qp->Z,qp->Z,qp->GZwork);CHKERRQ(ierr); 8874962610SAlp Dener 8974962610SAlp Dener qp->mu=0;qp->dinfeas=1.0;qp->pinfeas=1.0; 9074962610SAlp Dener while ((qp->dinfeas+qp->pinfeas)/(qp->m+qp->n) >= qp->mu) { 9174962610SAlp Dener ierr = VecScale(qp->G,two);CHKERRQ(ierr); 9274962610SAlp Dener ierr = VecScale(qp->Z,two);CHKERRQ(ierr); 9374962610SAlp Dener ierr = VecScale(qp->S,two);CHKERRQ(ierr); 9474962610SAlp Dener ierr = VecScale(qp->T,two);CHKERRQ(ierr); 9574962610SAlp Dener 9674962610SAlp Dener ierr = QPIPComputeResidual(qp,tao);CHKERRQ(ierr); 9774962610SAlp Dener 9874962610SAlp Dener ierr = VecCopy(tao->solution,qp->R3);CHKERRQ(ierr); 9974962610SAlp Dener ierr = VecAXPY(qp->R3,-1.0,qp->G);CHKERRQ(ierr); 10074962610SAlp Dener ierr = VecAXPY(qp->R3,-1.0,qp->XL);CHKERRQ(ierr); 10174962610SAlp Dener 10274962610SAlp Dener ierr = VecCopy(tao->solution,qp->R5);CHKERRQ(ierr); 10374962610SAlp Dener ierr = VecAXPY(qp->R5,1.0,qp->T);CHKERRQ(ierr); 10474962610SAlp Dener ierr = VecAXPY(qp->R5,-1.0,qp->XU);CHKERRQ(ierr); 10574962610SAlp Dener 10674962610SAlp Dener ierr = VecNorm(qp->R3,NORM_INFINITY,&gap1);CHKERRQ(ierr); 10774962610SAlp Dener ierr = VecNorm(qp->R5,NORM_INFINITY,&gap2);CHKERRQ(ierr); 10874962610SAlp Dener qp->pinfeas=PetscMax(gap1,gap2); 10974962610SAlp Dener 11074962610SAlp Dener /* Compute the duality gap */ 11174962610SAlp Dener ierr = VecDot(qp->G,qp->Z,&gap1);CHKERRQ(ierr); 11274962610SAlp Dener ierr = VecDot(qp->T,qp->S,&gap2);CHKERRQ(ierr); 11374962610SAlp Dener 11474962610SAlp Dener qp->gap = gap1+gap2; 11574962610SAlp Dener qp->dobj = qp->pobj - qp->gap; 11674962610SAlp Dener if (qp->m>0) { 11774962610SAlp Dener qp->mu=qp->gap/(qp->m); 11874962610SAlp Dener } else { 11974962610SAlp Dener qp->mu=0.0; 12074962610SAlp Dener } 12174962610SAlp Dener qp->rgap=qp->gap/(PetscAbsReal(qp->dobj) + PetscAbsReal(qp->pobj) + 1.0); 12274962610SAlp Dener } 12374962610SAlp Dener PetscFunctionReturn(0); 12474962610SAlp Dener } 12574962610SAlp Dener 12674962610SAlp Dener static PetscErrorCode QPIPStepLength(TAO_BQPIP *qp) 12774962610SAlp Dener { 12874962610SAlp Dener PetscReal tstep1,tstep2,tstep3,tstep4,tstep; 12974962610SAlp Dener PetscErrorCode ierr; 13074962610SAlp Dener 13174962610SAlp Dener PetscFunctionBegin; 13274962610SAlp Dener /* Compute stepsize to the boundary */ 13374962610SAlp Dener ierr = VecStepMax(qp->G,qp->DG,&tstep1);CHKERRQ(ierr); 13474962610SAlp Dener ierr = VecStepMax(qp->T,qp->DT,&tstep2);CHKERRQ(ierr); 13574962610SAlp Dener ierr = VecStepMax(qp->S,qp->DS,&tstep3);CHKERRQ(ierr); 13674962610SAlp Dener ierr = VecStepMax(qp->Z,qp->DZ,&tstep4);CHKERRQ(ierr); 13774962610SAlp Dener 13874962610SAlp Dener tstep = PetscMin(tstep1,tstep2); 13974962610SAlp Dener qp->psteplength = PetscMin(0.95*tstep,1.0); 14074962610SAlp Dener 14174962610SAlp Dener tstep = PetscMin(tstep3,tstep4); 14274962610SAlp Dener qp->dsteplength = PetscMin(0.95*tstep,1.0); 14374962610SAlp Dener 14474962610SAlp Dener qp->psteplength = PetscMin(qp->psteplength,qp->dsteplength); 14574962610SAlp Dener qp->dsteplength = qp->psteplength; 14674962610SAlp Dener PetscFunctionReturn(0); 14774962610SAlp Dener } 14874962610SAlp Dener 14974962610SAlp Dener static PetscErrorCode QPIPComputeNormFromCentralPath(TAO_BQPIP *qp,PetscReal *norm) 15074962610SAlp Dener { 15174962610SAlp Dener PetscErrorCode ierr; 15274962610SAlp Dener PetscReal gap[2],mu[2],nmu; 15374962610SAlp Dener 15474962610SAlp Dener PetscFunctionBegin; 15574962610SAlp Dener ierr = VecPointwiseMult(qp->GZwork,qp->G,qp->Z);CHKERRQ(ierr); 15674962610SAlp Dener ierr = VecPointwiseMult(qp->TSwork,qp->T,qp->S);CHKERRQ(ierr); 15774962610SAlp Dener ierr = VecNorm(qp->TSwork,NORM_1,&mu[0]);CHKERRQ(ierr); 15874962610SAlp Dener ierr = VecNorm(qp->GZwork,NORM_1,&mu[1]);CHKERRQ(ierr); 15974962610SAlp Dener 16074962610SAlp Dener nmu=-(mu[0]+mu[1])/qp->m; 16174962610SAlp Dener 16274962610SAlp Dener ierr = VecShift(qp->GZwork,nmu);CHKERRQ(ierr); 16374962610SAlp Dener ierr = VecShift(qp->TSwork,nmu);CHKERRQ(ierr); 16474962610SAlp Dener 16574962610SAlp Dener ierr = VecNorm(qp->GZwork,NORM_2,&gap[0]);CHKERRQ(ierr); 16674962610SAlp Dener ierr = VecNorm(qp->TSwork,NORM_2,&gap[1]);CHKERRQ(ierr); 16774962610SAlp Dener gap[0]*=gap[0]; 16874962610SAlp Dener gap[1]*=gap[1]; 16974962610SAlp Dener 17074962610SAlp Dener qp->pathnorm=PetscSqrtScalar(gap[0]+gap[1]); 17174962610SAlp Dener *norm=qp->pathnorm; 17274962610SAlp Dener PetscFunctionReturn(0); 17374962610SAlp Dener } 17474962610SAlp Dener 17574962610SAlp Dener static PetscErrorCode QPIPComputeStepDirection(TAO_BQPIP *qp,Tao tao) 17674962610SAlp Dener { 17774962610SAlp Dener PetscErrorCode ierr; 17874962610SAlp Dener 17974962610SAlp Dener PetscFunctionBegin; 18074962610SAlp Dener /* Calculate DG */ 18174962610SAlp Dener ierr = VecCopy(tao->stepdirection,qp->DG);CHKERRQ(ierr); 18274962610SAlp Dener ierr = VecAXPY(qp->DG,1.0,qp->R3);CHKERRQ(ierr); 18374962610SAlp Dener 18474962610SAlp Dener /* Calculate DT */ 18574962610SAlp Dener ierr = VecCopy(tao->stepdirection,qp->DT);CHKERRQ(ierr); 18674962610SAlp Dener ierr = VecScale(qp->DT,-1.0);CHKERRQ(ierr); 18774962610SAlp Dener ierr = VecAXPY(qp->DT,-1.0,qp->R5);CHKERRQ(ierr); 18874962610SAlp Dener 18974962610SAlp Dener /* Calculate DZ */ 19074962610SAlp Dener ierr = VecAXPY(qp->DZ,-1.0,qp->Z);CHKERRQ(ierr); 19174962610SAlp Dener ierr = VecPointwiseDivide(qp->GZwork,qp->DG,qp->G);CHKERRQ(ierr); 19274962610SAlp Dener ierr = VecPointwiseMult(qp->GZwork,qp->GZwork,qp->Z);CHKERRQ(ierr); 19374962610SAlp Dener ierr = VecAXPY(qp->DZ,-1.0,qp->GZwork);CHKERRQ(ierr); 19474962610SAlp Dener 19574962610SAlp Dener /* Calculate DS */ 19674962610SAlp Dener ierr = VecAXPY(qp->DS,-1.0,qp->S);CHKERRQ(ierr); 19774962610SAlp Dener ierr = VecPointwiseDivide(qp->TSwork,qp->DT,qp->T);CHKERRQ(ierr); 19874962610SAlp Dener ierr = VecPointwiseMult(qp->TSwork,qp->TSwork,qp->S);CHKERRQ(ierr); 19974962610SAlp Dener ierr = VecAXPY(qp->DS,-1.0,qp->TSwork);CHKERRQ(ierr); 20074962610SAlp Dener PetscFunctionReturn(0); 20174962610SAlp Dener } 20274962610SAlp Dener 20374962610SAlp Dener static PetscErrorCode TaoSetup_BQPIP(Tao tao) 20474962610SAlp Dener { 20574962610SAlp Dener TAO_BQPIP *qp =(TAO_BQPIP*)tao->data; 20674962610SAlp Dener PetscErrorCode ierr; 20774962610SAlp Dener 20874962610SAlp Dener PetscFunctionBegin; 20974962610SAlp Dener /* Set pointers to Data */ 21074962610SAlp Dener ierr = VecGetSize(tao->solution,&qp->n);CHKERRQ(ierr); 21174962610SAlp Dener 21274962610SAlp Dener /* Allocate some arrays */ 21374962610SAlp Dener if (!tao->gradient) { 21474962610SAlp Dener ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); 21574962610SAlp Dener } 21674962610SAlp Dener if (!tao->stepdirection) { 21774962610SAlp Dener ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); 21874962610SAlp Dener } 21974962610SAlp Dener if (!tao->XL) { 22074962610SAlp Dener ierr = VecDuplicate(tao->solution,&tao->XL);CHKERRQ(ierr); 22174962610SAlp Dener ierr = VecSet(tao->XL,PETSC_NINFINITY);CHKERRQ(ierr); 22274962610SAlp Dener } 22374962610SAlp Dener if (!tao->XU) { 22474962610SAlp Dener ierr = VecDuplicate(tao->solution,&tao->XU);CHKERRQ(ierr); 22574962610SAlp Dener ierr = VecSet(tao->XU,PETSC_INFINITY);CHKERRQ(ierr); 22674962610SAlp Dener } 22774962610SAlp Dener 22874962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->Work);CHKERRQ(ierr); 22974962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->XU);CHKERRQ(ierr); 23074962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->XL);CHKERRQ(ierr); 23174962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->HDiag);CHKERRQ(ierr); 23274962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->DiagAxpy);CHKERRQ(ierr); 23374962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->RHS);CHKERRQ(ierr); 23474962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->RHS2);CHKERRQ(ierr); 23574962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->C);CHKERRQ(ierr); 23674962610SAlp Dener 23774962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->G);CHKERRQ(ierr); 23874962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->DG);CHKERRQ(ierr); 23974962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->S);CHKERRQ(ierr); 24074962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->Z);CHKERRQ(ierr); 24174962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->DZ);CHKERRQ(ierr); 24274962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->GZwork);CHKERRQ(ierr); 24374962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->R3);CHKERRQ(ierr); 24474962610SAlp Dener 24574962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->T);CHKERRQ(ierr); 24674962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->DT);CHKERRQ(ierr); 24774962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->DS);CHKERRQ(ierr); 24874962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->TSwork);CHKERRQ(ierr); 24974962610SAlp Dener ierr = VecDuplicate(tao->solution,&qp->R5);CHKERRQ(ierr); 25074962610SAlp Dener qp->m=2*qp->n; 25174962610SAlp Dener PetscFunctionReturn(0); 25274962610SAlp Dener } 25374962610SAlp Dener 25474962610SAlp Dener static PetscErrorCode TaoSolve_BQPIP(Tao tao) 25574962610SAlp Dener { 25674962610SAlp Dener TAO_BQPIP *qp = (TAO_BQPIP*)tao->data; 25774962610SAlp Dener PetscErrorCode ierr; 25874962610SAlp Dener PetscInt its; 25974962610SAlp Dener PetscReal d1,d2,ksptol,sigmamu; 26074962610SAlp Dener PetscReal gnorm,dstep,pstep,step=0; 26174962610SAlp Dener PetscReal gap[4]; 26274962610SAlp Dener PetscBool getdiagop; 26374962610SAlp Dener 26474962610SAlp Dener PetscFunctionBegin; 26574962610SAlp Dener qp->dobj = 0.0; 26674962610SAlp Dener qp->pobj = 1.0; 26774962610SAlp Dener qp->gap = 10.0; 26874962610SAlp Dener qp->rgap = 1.0; 26974962610SAlp Dener qp->mu = 1.0; 27074962610SAlp Dener qp->dinfeas = 1.0; 27174962610SAlp Dener qp->psteplength = 0.0; 27274962610SAlp Dener qp->dsteplength = 0.0; 27374962610SAlp Dener 27474962610SAlp Dener /* TODO 27574962610SAlp Dener - Remove fixed variables and treat them correctly 27674962610SAlp Dener - Use index sets for the infinite versus finite bounds 27774962610SAlp Dener - Update remaining code for fixed and free variables 27874962610SAlp Dener - Fix inexact solves for predictor and corrector 27974962610SAlp Dener */ 28074962610SAlp Dener 28174962610SAlp Dener /* Tighten infinite bounds, things break when we don't do this 28274962610SAlp Dener -- see test_bqpip.c 28374962610SAlp Dener */ 28474962610SAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 28574962610SAlp Dener ierr = VecSet(qp->XU,1.0e20);CHKERRQ(ierr); 28674962610SAlp Dener ierr = VecSet(qp->XL,-1.0e20);CHKERRQ(ierr); 28774962610SAlp Dener ierr = VecPointwiseMax(qp->XL,qp->XL,tao->XL);CHKERRQ(ierr); 28874962610SAlp Dener ierr = VecPointwiseMin(qp->XU,qp->XU,tao->XU);CHKERRQ(ierr); 28974962610SAlp Dener ierr = VecMedian(qp->XL,tao->solution,qp->XU,tao->solution);CHKERRQ(ierr); 29074962610SAlp Dener 29174962610SAlp Dener /* Evaluate gradient and Hessian at zero to get the correct values 29274962610SAlp Dener without contaminating them with numerical artifacts. 29374962610SAlp Dener */ 29474962610SAlp Dener ierr = VecSet(qp->Work,0);CHKERRQ(ierr); 29574962610SAlp Dener ierr = TaoComputeObjectiveAndGradient(tao,qp->Work,&qp->d,qp->C);CHKERRQ(ierr); 29674962610SAlp Dener ierr = TaoComputeHessian(tao,qp->Work,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 29774962610SAlp Dener ierr = MatHasOperation(tao->hessian,MATOP_GET_DIAGONAL,&getdiagop);CHKERRQ(ierr); 29874962610SAlp Dener if (getdiagop) { 29974962610SAlp Dener ierr = MatGetDiagonal(tao->hessian,qp->HDiag);CHKERRQ(ierr); 30074962610SAlp Dener } 30174962610SAlp Dener 30274962610SAlp Dener /* Initialize starting point and residuals */ 30374962610SAlp Dener ierr = QPIPSetInitialPoint(qp,tao);CHKERRQ(ierr); 30474962610SAlp Dener ierr = QPIPComputeResidual(qp,tao);CHKERRQ(ierr); 30574962610SAlp Dener 30674962610SAlp Dener /* Enter main loop */ 30774962610SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 30874962610SAlp Dener while (1) { 30974962610SAlp Dener 31074962610SAlp Dener /* Check Stopping Condition */ 31174962610SAlp Dener gnorm = PetscSqrtScalar(qp->gap + qp->dinfeas); 31274962610SAlp Dener ierr = TaoLogConvergenceHistory(tao,qp->pobj,gnorm,qp->pinfeas,tao->ksp_its);CHKERRQ(ierr); 31374962610SAlp Dener ierr = TaoMonitor(tao,tao->niter,qp->pobj,gnorm,qp->pinfeas,step);CHKERRQ(ierr); 31474962610SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 31574962610SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) break; 316*e1e80dc8SAlp Dener /* Call general purpose update function */ 317*e1e80dc8SAlp Dener if (tao->ops->update) { 318*e1e80dc8SAlp Dener ierr = (*tao->ops->update)(tao, tao->niter);CHKERRQ(ierr); 319*e1e80dc8SAlp Dener } 32074962610SAlp Dener tao->niter++; 32174962610SAlp Dener tao->ksp_its = 0; 32274962610SAlp Dener 32374962610SAlp Dener /* 32474962610SAlp Dener Dual Infeasibility Direction should already be in the right 32574962610SAlp Dener hand side from computing the residuals 32674962610SAlp Dener */ 32774962610SAlp Dener 32874962610SAlp Dener ierr = QPIPComputeNormFromCentralPath(qp,&d1);CHKERRQ(ierr); 32974962610SAlp Dener 33074962610SAlp Dener ierr = VecSet(qp->DZ,0.0);CHKERRQ(ierr); 33174962610SAlp Dener ierr = VecSet(qp->DS,0.0);CHKERRQ(ierr); 33274962610SAlp Dener 33374962610SAlp Dener /* 33474962610SAlp Dener Compute the Primal Infeasiblitiy RHS and the 33574962610SAlp Dener Diagonal Matrix to be added to H and store in Work 33674962610SAlp Dener */ 33774962610SAlp Dener ierr = VecPointwiseDivide(qp->DiagAxpy,qp->Z,qp->G);CHKERRQ(ierr); 33874962610SAlp Dener ierr = VecPointwiseMult(qp->GZwork,qp->DiagAxpy,qp->R3);CHKERRQ(ierr); 33974962610SAlp Dener ierr = VecAXPY(qp->RHS,-1.0,qp->GZwork);CHKERRQ(ierr); 34074962610SAlp Dener 34174962610SAlp Dener ierr = VecPointwiseDivide(qp->TSwork,qp->S,qp->T);CHKERRQ(ierr); 34274962610SAlp Dener ierr = VecAXPY(qp->DiagAxpy,1.0,qp->TSwork);CHKERRQ(ierr); 34374962610SAlp Dener ierr = VecPointwiseMult(qp->TSwork,qp->TSwork,qp->R5);CHKERRQ(ierr); 34474962610SAlp Dener ierr = VecAXPY(qp->RHS,-1.0,qp->TSwork);CHKERRQ(ierr); 34574962610SAlp Dener 34674962610SAlp Dener /* Determine the solving tolerance */ 34774962610SAlp Dener ksptol = qp->mu/10.0; 34874962610SAlp Dener ksptol = PetscMin(ksptol,0.001); 34974962610SAlp Dener ierr = KSPSetTolerances(tao->ksp,ksptol,1e-30,1e30,PetscMax(10,qp->n));CHKERRQ(ierr); 35074962610SAlp Dener 35174962610SAlp Dener /* Shift the diagonals of the Hessian matrix */ 35274962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->DiagAxpy,ADD_VALUES);CHKERRQ(ierr); 35374962610SAlp Dener if (!getdiagop) { 35474962610SAlp Dener ierr = VecCopy(qp->DiagAxpy,qp->HDiag);CHKERRQ(ierr); 35574962610SAlp Dener ierr = VecScale(qp->HDiag,-1.0);CHKERRQ(ierr); 35674962610SAlp Dener } 35774962610SAlp Dener ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 35874962610SAlp Dener ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 35974962610SAlp Dener 36074962610SAlp Dener ierr = KSPSetOperators(tao->ksp,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 36174962610SAlp Dener ierr = KSPSolve(tao->ksp,qp->RHS,tao->stepdirection);CHKERRQ(ierr); 36274962610SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 36374962610SAlp Dener tao->ksp_its += its; 36474962610SAlp Dener tao->ksp_tot_its += its; 36574962610SAlp Dener 36674962610SAlp Dener /* Restore the true diagonal of the Hessian matrix */ 36774962610SAlp Dener if (getdiagop) { 36874962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->HDiag,INSERT_VALUES);CHKERRQ(ierr); 36974962610SAlp Dener } else { 37074962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->HDiag,ADD_VALUES);CHKERRQ(ierr); 37174962610SAlp Dener } 37274962610SAlp Dener ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37374962610SAlp Dener ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37474962610SAlp Dener ierr = QPIPComputeStepDirection(qp,tao);CHKERRQ(ierr); 37574962610SAlp Dener ierr = QPIPStepLength(qp);CHKERRQ(ierr); 37674962610SAlp Dener 37774962610SAlp Dener /* Calculate New Residual R1 in Work vector */ 37874962610SAlp Dener ierr = MatMult(tao->hessian,tao->stepdirection,qp->RHS2);CHKERRQ(ierr); 37974962610SAlp Dener ierr = VecAXPY(qp->RHS2,1.0,qp->DS);CHKERRQ(ierr); 38074962610SAlp Dener ierr = VecAXPY(qp->RHS2,-1.0,qp->DZ);CHKERRQ(ierr); 38174962610SAlp Dener ierr = VecAYPX(qp->RHS2,qp->dsteplength,tao->gradient);CHKERRQ(ierr); 38274962610SAlp Dener 38374962610SAlp Dener ierr = VecNorm(qp->RHS2,NORM_2,&qp->dinfeas);CHKERRQ(ierr); 38474962610SAlp Dener ierr = VecDot(qp->DZ,qp->DG,gap);CHKERRQ(ierr); 38574962610SAlp Dener ierr = VecDot(qp->DS,qp->DT,gap+1);CHKERRQ(ierr); 38674962610SAlp Dener 38774962610SAlp Dener qp->rnorm = (qp->dinfeas+qp->psteplength*qp->pinfeas)/(qp->m+qp->n); 38874962610SAlp Dener pstep = qp->psteplength; 38974962610SAlp Dener step = PetscMin(qp->psteplength,qp->dsteplength); 39074962610SAlp Dener sigmamu = (pstep*pstep*(gap[0]+gap[1]) + (1 - pstep)*qp->gap)/qp->m; 39174962610SAlp Dener 39274962610SAlp Dener if (qp->predcorr && step < 0.9) { 39374962610SAlp Dener if (sigmamu < qp->mu) { 39474962610SAlp Dener sigmamu = sigmamu/qp->mu; 39574962610SAlp Dener sigmamu = sigmamu*sigmamu*sigmamu; 39674962610SAlp Dener } else { 39774962610SAlp Dener sigmamu = 1.0; 39874962610SAlp Dener } 39974962610SAlp Dener sigmamu = sigmamu*qp->mu; 40074962610SAlp Dener 40174962610SAlp Dener /* Compute Corrector Step */ 40274962610SAlp Dener ierr = VecPointwiseMult(qp->DZ,qp->DG,qp->DZ);CHKERRQ(ierr); 40374962610SAlp Dener ierr = VecScale(qp->DZ,-1.0);CHKERRQ(ierr); 40474962610SAlp Dener ierr = VecShift(qp->DZ,sigmamu);CHKERRQ(ierr); 40574962610SAlp Dener ierr = VecPointwiseDivide(qp->DZ,qp->DZ,qp->G);CHKERRQ(ierr); 40674962610SAlp Dener 40774962610SAlp Dener ierr = VecPointwiseMult(qp->DS,qp->DS,qp->DT);CHKERRQ(ierr); 40874962610SAlp Dener ierr = VecScale(qp->DS,-1.0);CHKERRQ(ierr); 40974962610SAlp Dener ierr = VecShift(qp->DS,sigmamu);CHKERRQ(ierr); 41074962610SAlp Dener ierr = VecPointwiseDivide(qp->DS,qp->DS,qp->T);CHKERRQ(ierr); 41174962610SAlp Dener 41274962610SAlp Dener ierr = VecCopy(qp->DZ,qp->RHS2);CHKERRQ(ierr); 41374962610SAlp Dener ierr = VecAXPY(qp->RHS2,-1.0,qp->DS);CHKERRQ(ierr); 41474962610SAlp Dener ierr = VecAXPY(qp->RHS2,1.0,qp->RHS);CHKERRQ(ierr); 41574962610SAlp Dener 41674962610SAlp Dener /* Approximately solve the linear system */ 41774962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->DiagAxpy,ADD_VALUES);CHKERRQ(ierr); 41874962610SAlp Dener if (!getdiagop) { 41974962610SAlp Dener ierr = VecCopy(qp->DiagAxpy,qp->HDiag);CHKERRQ(ierr); 42074962610SAlp Dener ierr = VecScale(qp->HDiag,-1.0);CHKERRQ(ierr); 42174962610SAlp Dener } 42274962610SAlp Dener ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 42374962610SAlp Dener ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 42474962610SAlp Dener 42574962610SAlp Dener /* Solve using the previous tolerances that were set */ 42674962610SAlp Dener ierr = KSPSolve(tao->ksp,qp->RHS2,tao->stepdirection);CHKERRQ(ierr); 42774962610SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 42874962610SAlp Dener tao->ksp_its += its; 42974962610SAlp Dener tao->ksp_tot_its += its; 43074962610SAlp Dener 43174962610SAlp Dener if (getdiagop) { 43274962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->HDiag,INSERT_VALUES);CHKERRQ(ierr); 43374962610SAlp Dener } else { 43474962610SAlp Dener ierr = MatDiagonalSet(tao->hessian,qp->HDiag,ADD_VALUES);CHKERRQ(ierr); 43574962610SAlp Dener } 43674962610SAlp Dener ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43774962610SAlp Dener ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43874962610SAlp Dener ierr = QPIPComputeStepDirection(qp,tao);CHKERRQ(ierr); 43974962610SAlp Dener ierr = QPIPStepLength(qp);CHKERRQ(ierr); 44074962610SAlp Dener } /* End Corrector step */ 44174962610SAlp Dener 44274962610SAlp Dener 44374962610SAlp Dener /* Take the step */ 44474962610SAlp Dener dstep = qp->dsteplength; 44574962610SAlp Dener 44674962610SAlp Dener ierr = VecAXPY(qp->Z,dstep,qp->DZ);CHKERRQ(ierr); 44774962610SAlp Dener ierr = VecAXPY(qp->S,dstep,qp->DS);CHKERRQ(ierr); 44874962610SAlp Dener ierr = VecAXPY(tao->solution,dstep,tao->stepdirection);CHKERRQ(ierr); 44974962610SAlp Dener ierr = VecAXPY(qp->G,dstep,qp->DG);CHKERRQ(ierr); 45074962610SAlp Dener ierr = VecAXPY(qp->T,dstep,qp->DT);CHKERRQ(ierr); 45174962610SAlp Dener 45274962610SAlp Dener /* Compute Residuals */ 45374962610SAlp Dener ierr = QPIPComputeResidual(qp,tao);CHKERRQ(ierr); 45474962610SAlp Dener 45574962610SAlp Dener /* Evaluate quadratic function */ 45674962610SAlp Dener ierr = MatMult(tao->hessian,tao->solution,qp->Work);CHKERRQ(ierr); 45774962610SAlp Dener 45874962610SAlp Dener ierr = VecDot(tao->solution,qp->Work,&d1);CHKERRQ(ierr); 45974962610SAlp Dener ierr = VecDot(tao->solution,qp->C,&d2);CHKERRQ(ierr); 46074962610SAlp Dener ierr = VecDot(qp->G,qp->Z,gap);CHKERRQ(ierr); 46174962610SAlp Dener ierr = VecDot(qp->T,qp->S,gap+1);CHKERRQ(ierr); 46274962610SAlp Dener 46374962610SAlp Dener /* Compute the duality gap */ 46474962610SAlp Dener qp->pobj = d1/2.0 + d2+qp->d; 46574962610SAlp Dener qp->gap = gap[0]+gap[1]; 46674962610SAlp Dener qp->dobj = qp->pobj - qp->gap; 46774962610SAlp Dener if (qp->m > 0) { 46874962610SAlp Dener qp->mu = qp->gap/(qp->m); 46974962610SAlp Dener } 47074962610SAlp Dener qp->rgap = qp->gap/(PetscAbsReal(qp->dobj) + PetscAbsReal(qp->pobj) + 1.0); 47174962610SAlp Dener } /* END MAIN LOOP */ 47274962610SAlp Dener PetscFunctionReturn(0); 47374962610SAlp Dener } 47474962610SAlp Dener 47574962610SAlp Dener static PetscErrorCode TaoView_BQPIP(Tao tao,PetscViewer viewer) 47674962610SAlp Dener { 47774962610SAlp Dener PetscFunctionBegin; 47874962610SAlp Dener PetscFunctionReturn(0); 47974962610SAlp Dener } 48074962610SAlp Dener 48174962610SAlp Dener static PetscErrorCode TaoSetFromOptions_BQPIP(PetscOptionItems *PetscOptionsObject,Tao tao) 48274962610SAlp Dener { 48374962610SAlp Dener TAO_BQPIP *qp = (TAO_BQPIP*)tao->data; 48474962610SAlp Dener PetscErrorCode ierr; 48574962610SAlp Dener 48674962610SAlp Dener PetscFunctionBegin; 48774962610SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Interior point method for bound constrained quadratic optimization");CHKERRQ(ierr); 48874962610SAlp Dener ierr = PetscOptionsInt("-tao_bqpip_predcorr","Use a predictor-corrector method","",qp->predcorr,&qp->predcorr,0);CHKERRQ(ierr); 48974962610SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 49074962610SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 49174962610SAlp Dener PetscFunctionReturn(0); 49274962610SAlp Dener } 49374962610SAlp Dener 49474962610SAlp Dener static PetscErrorCode TaoDestroy_BQPIP(Tao tao) 49574962610SAlp Dener { 49674962610SAlp Dener TAO_BQPIP *qp = (TAO_BQPIP*)tao->data; 49774962610SAlp Dener PetscErrorCode ierr; 49874962610SAlp Dener 49974962610SAlp Dener PetscFunctionBegin; 50074962610SAlp Dener if (tao->setupcalled) { 50174962610SAlp Dener ierr = VecDestroy(&qp->G);CHKERRQ(ierr); 50274962610SAlp Dener ierr = VecDestroy(&qp->DG);CHKERRQ(ierr); 50374962610SAlp Dener ierr = VecDestroy(&qp->Z);CHKERRQ(ierr); 50474962610SAlp Dener ierr = VecDestroy(&qp->DZ);CHKERRQ(ierr); 50574962610SAlp Dener ierr = VecDestroy(&qp->GZwork);CHKERRQ(ierr); 50674962610SAlp Dener ierr = VecDestroy(&qp->R3);CHKERRQ(ierr); 50774962610SAlp Dener ierr = VecDestroy(&qp->S);CHKERRQ(ierr); 50874962610SAlp Dener ierr = VecDestroy(&qp->DS);CHKERRQ(ierr); 50974962610SAlp Dener ierr = VecDestroy(&qp->T);CHKERRQ(ierr); 51074962610SAlp Dener 51174962610SAlp Dener ierr = VecDestroy(&qp->DT);CHKERRQ(ierr); 51274962610SAlp Dener ierr = VecDestroy(&qp->TSwork);CHKERRQ(ierr); 51374962610SAlp Dener ierr = VecDestroy(&qp->R5);CHKERRQ(ierr); 51474962610SAlp Dener ierr = VecDestroy(&qp->HDiag);CHKERRQ(ierr); 51574962610SAlp Dener ierr = VecDestroy(&qp->Work);CHKERRQ(ierr); 51674962610SAlp Dener ierr = VecDestroy(&qp->XL);CHKERRQ(ierr); 51774962610SAlp Dener ierr = VecDestroy(&qp->XU);CHKERRQ(ierr); 51874962610SAlp Dener ierr = VecDestroy(&qp->DiagAxpy);CHKERRQ(ierr); 51974962610SAlp Dener ierr = VecDestroy(&qp->RHS);CHKERRQ(ierr); 52074962610SAlp Dener ierr = VecDestroy(&qp->RHS2);CHKERRQ(ierr); 52174962610SAlp Dener ierr = VecDestroy(&qp->C);CHKERRQ(ierr); 52274962610SAlp Dener } 52374962610SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 52474962610SAlp Dener PetscFunctionReturn(0); 52574962610SAlp Dener } 52674962610SAlp Dener 52774962610SAlp Dener static PetscErrorCode TaoComputeDual_BQPIP(Tao tao,Vec DXL,Vec DXU) 52874962610SAlp Dener { 52974962610SAlp Dener TAO_BQPIP *qp = (TAO_BQPIP*)tao->data; 53074962610SAlp Dener PetscErrorCode ierr; 53174962610SAlp Dener 53274962610SAlp Dener PetscFunctionBegin; 53374962610SAlp Dener ierr = VecCopy(qp->Z,DXL);CHKERRQ(ierr); 53474962610SAlp Dener ierr = VecCopy(qp->S,DXU);CHKERRQ(ierr); 53574962610SAlp Dener ierr = VecScale(DXU,-1.0);CHKERRQ(ierr); 53674962610SAlp Dener PetscFunctionReturn(0); 53774962610SAlp Dener } 53874962610SAlp Dener 53974962610SAlp Dener /*MC 54074962610SAlp Dener TAOBQPIP - interior-point method for quadratic programs with 54174962610SAlp Dener box constraints. 54274962610SAlp Dener 54374962610SAlp Dener Notes: 54474962610SAlp Dener This algorithms solves quadratic problems only, the Hessian will 54574962610SAlp Dener only be computed once. 54674962610SAlp Dener 54774962610SAlp Dener Options Database Keys: 54874962610SAlp Dener . -tao_bqpip_predcorr - use a predictor/corrector method 54974962610SAlp Dener 55074962610SAlp Dener Level: beginner 55174962610SAlp Dener M*/ 55274962610SAlp Dener 55374962610SAlp Dener PETSC_EXTERN PetscErrorCode TaoCreate_BQPIP(Tao tao) 55474962610SAlp Dener { 55574962610SAlp Dener TAO_BQPIP *qp; 55674962610SAlp Dener PetscErrorCode ierr; 55774962610SAlp Dener 55874962610SAlp Dener PetscFunctionBegin; 55974962610SAlp Dener ierr = PetscNewLog(tao,&qp);CHKERRQ(ierr); 56074962610SAlp Dener 56174962610SAlp Dener tao->ops->setup = TaoSetup_BQPIP; 56274962610SAlp Dener tao->ops->solve = TaoSolve_BQPIP; 56374962610SAlp Dener tao->ops->view = TaoView_BQPIP; 56474962610SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BQPIP; 56574962610SAlp Dener tao->ops->destroy = TaoDestroy_BQPIP; 56674962610SAlp Dener tao->ops->computedual = TaoComputeDual_BQPIP; 56774962610SAlp Dener 56874962610SAlp Dener /* Override default settings (unless already changed) */ 56974962610SAlp Dener if (!tao->max_it_changed) tao->max_it=100; 57074962610SAlp Dener if (!tao->max_funcs_changed) tao->max_funcs = 500; 57174962610SAlp Dener #if defined(PETSC_USE_REAL_SINGLE) 57274962610SAlp Dener if (!tao->catol_changed) tao->catol=1e-6; 57374962610SAlp Dener #else 57474962610SAlp Dener if (!tao->catol_changed) tao->catol=1e-12; 57574962610SAlp Dener #endif 57674962610SAlp Dener 57774962610SAlp Dener /* Initialize pointers and variables */ 57874962610SAlp Dener qp->n = 0; 57974962610SAlp Dener qp->m = 0; 58074962610SAlp Dener 58174962610SAlp Dener qp->predcorr = 1; 58274962610SAlp Dener tao->data = (void*)qp; 58374962610SAlp Dener 58474962610SAlp Dener ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 58574962610SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 58674962610SAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 58774962610SAlp Dener ierr = KSPSetType(tao->ksp,KSPCG);CHKERRQ(ierr); 58874962610SAlp Dener ierr = KSPSetTolerances(tao->ksp,1e-14,1e-30,1e30,PetscMax(10,qp->n));CHKERRQ(ierr); 58974962610SAlp Dener PetscFunctionReturn(0); 59074962610SAlp Dener } 591