Date: 2015-10-02T22:30:47+00:00

Actual source code: bqpip.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      1: #include <../src/tao/bound/impls/bqpip/bqpip.h>
      2: #include <petscksp.h>

      6: static PetscErrorCode TaoSetUp_BQPIP(Tao tao)
      7: {
      8:   TAO_BQPIP      *qp =(TAO_BQPIP*)tao->data;

     12:   /* Set pointers to Data */
     13:   VecGetSize(tao->solution,&qp->n);

     15:   /* Allocate some arrays */
     16:   if (!tao->gradient) {
     17:       VecDuplicate(tao->solution, &tao->gradient);
     18:   }
     19:   if (!tao->stepdirection) {
     20:       VecDuplicate(tao->solution, &tao->stepdirection);
     21:   }
     22:   if (!tao->XL) {
     23:       VecDuplicate(tao->solution, &tao->XL);
     24:       VecSet(tao->XL, -1.0e-20);
     25:   }
     26:   if (!tao->XU) {
     27:       VecDuplicate(tao->solution, &tao->XU);
     28:       VecSet(tao->XU, 1.0e20);
     29:   }

     31:   VecDuplicate(tao->solution, &qp->Work);
     32:   VecDuplicate(tao->solution, &qp->XU);
     33:   VecDuplicate(tao->solution, &qp->XL);
     34:   VecDuplicate(tao->solution, &qp->HDiag);
     35:   VecDuplicate(tao->solution, &qp->DiagAxpy);
     36:   VecDuplicate(tao->solution, &qp->RHS);
     37:   VecDuplicate(tao->solution, &qp->RHS2);
     38:   VecDuplicate(tao->solution, &qp->C0);

     40:   VecDuplicate(tao->solution, &qp->G);
     41:   VecDuplicate(tao->solution, &qp->DG);
     42:   VecDuplicate(tao->solution, &qp->S);
     43:   VecDuplicate(tao->solution, &qp->Z);
     44:   VecDuplicate(tao->solution, &qp->DZ);
     45:   VecDuplicate(tao->solution, &qp->GZwork);
     46:   VecDuplicate(tao->solution, &qp->R3);

     48:   VecDuplicate(tao->solution, &qp->T);
     49:   VecDuplicate(tao->solution, &qp->DT);
     50:   VecDuplicate(tao->solution, &qp->DS);
     51:   VecDuplicate(tao->solution, &qp->TSwork);
     52:   VecDuplicate(tao->solution, &qp->R5);
     53:   qp->m=2*qp->n;
     54:   return(0);
     55: }

     59: static PetscErrorCode  QPIPSetInitialPoint(TAO_BQPIP *qp, Tao tao)
     60: {
     62:   PetscReal      two=2.0,p01=1;
     63:   PetscReal      gap1,gap2,fff,mu;

     66:   /* Compute function, Gradient R=Hx+b, and Hessian */
     67:   TaoComputeVariableBounds(tao);
     68:   VecMedian(qp->XL, tao->solution, qp->XU, tao->solution);
     69:   MatMult(tao->hessian, tao->solution, tao->gradient);
     70:   VecCopy(qp->C0, qp->Work);
     71:   VecAXPY(qp->Work, 0.5, tao->gradient);
     72:   VecAXPY(tao->gradient, 1.0, qp->C0);
     73:   VecDot(tao->solution, qp->Work, &fff);
     74:   qp->pobj = fff + qp->c;

     76:   /* Initialize Primal Vectors */
     77:   /* T = XU - X; G = X - XL */
     78:   VecCopy(qp->XU, qp->T);
     79:   VecAXPY(qp->T, -1.0, tao->solution);
     80:   VecCopy(tao->solution, qp->G);
     81:   VecAXPY(qp->G, -1.0, qp->XL);

     83:   VecSet(qp->GZwork, p01);
     84:   VecSet(qp->TSwork, p01);

     86:   VecPointwiseMax(qp->G, qp->G, qp->GZwork);
     87:   VecPointwiseMax(qp->T, qp->T, qp->TSwork);

     89:   /* Initialize Dual Variable Vectors */
     90:   VecCopy(qp->G, qp->Z);
     91:   VecReciprocal(qp->Z);

     93:   VecCopy(qp->T, qp->S);
     94:   VecReciprocal(qp->S);

     96:   MatMult(tao->hessian, qp->Work, qp->RHS);
     97:   VecAbs(qp->RHS);
     98:   VecSet(qp->Work, p01);
     99:   VecPointwiseMax(qp->RHS, qp->RHS, qp->Work);

    101:   VecPointwiseDivide(qp->RHS, tao->gradient, qp->RHS);
    102:   VecNorm(qp->RHS, NORM_1, &gap1);
    103:   mu = PetscMin(10.0,(gap1+10.0)/qp->m);

    105:   VecScale(qp->S, mu);
    106:   VecScale(qp->Z, mu);

    108:   VecSet(qp->TSwork, p01);
    109:   VecSet(qp->GZwork, p01);
    110:   VecPointwiseMax(qp->S, qp->S, qp->TSwork);
    111:   VecPointwiseMax(qp->Z, qp->Z, qp->GZwork);

    113:   qp->mu=0;qp->dinfeas=1.0;qp->pinfeas=1.0;
    114:   while ( (qp->dinfeas+qp->pinfeas)/(qp->m+qp->n) >= qp->mu ){

    116:     VecScale(qp->G, two);
    117:     VecScale(qp->Z, two);
    118:     VecScale(qp->S, two);
    119:     VecScale(qp->T, two);

    121:     QPIPComputeResidual(qp,tao);

    123:     VecCopy(tao->solution, qp->R3);
    124:     VecAXPY(qp->R3, -1.0, qp->G);
    125:     VecAXPY(qp->R3, -1.0, qp->XL);

    127:     VecCopy(tao->solution, qp->R5);
    128:     VecAXPY(qp->R5, 1.0, qp->T);
    129:     VecAXPY(qp->R5, -1.0, qp->XU);

    131:     VecNorm(qp->R3, NORM_INFINITY, &gap1);
    132:     VecNorm(qp->R5, NORM_INFINITY, &gap2);
    133:     qp->pinfeas=PetscMax(gap1,gap2);

    135:     /* Compute the duality gap */
    136:     VecDot(qp->G, qp->Z, &gap1);
    137:     VecDot(qp->T, qp->S, &gap2);

    139:     qp->gap = (gap1+gap2);
    140:     qp->dobj = qp->pobj - qp->gap;
    141:     if (qp->m>0) qp->mu=qp->gap/(qp->m); else qp->mu=0.0;
    142:     qp->rgap=qp->gap/( PetscAbsReal(qp->dobj) + PetscAbsReal(qp->pobj) + 1.0 );
    143:   }
    144:   return(0);
    145: }

    149: static PetscErrorCode TaoDestroy_BQPIP(Tao tao)
    150: {
    151:   TAO_BQPIP      *qp = (TAO_BQPIP*)tao->data;

    155:   if (tao->setupcalled) {
    156:     VecDestroy(&qp->G);
    157:     VecDestroy(&qp->DG);
    158:     VecDestroy(&qp->Z);
    159:     VecDestroy(&qp->DZ);
    160:     VecDestroy(&qp->GZwork);
    161:     VecDestroy(&qp->R3);
    162:     VecDestroy(&qp->S);
    163:     VecDestroy(&qp->DS);
    164:     VecDestroy(&qp->T);

    166:     VecDestroy(&qp->DT);
    167:     VecDestroy(&qp->TSwork);
    168:     VecDestroy(&qp->R5);
    169:     VecDestroy(&qp->HDiag);
    170:     VecDestroy(&qp->Work);
    171:     VecDestroy(&qp->XL);
    172:     VecDestroy(&qp->XU);
    173:     VecDestroy(&qp->DiagAxpy);
    174:     VecDestroy(&qp->RHS);
    175:     VecDestroy(&qp->RHS2);
    176:     VecDestroy(&qp->C0);
    177:   }
    178:   PetscFree(tao->data);
    179:   return(0);
    180: }

    184: static PetscErrorCode TaoSolve_BQPIP(Tao tao)
    185: {
    186:   TAO_BQPIP          *qp = (TAO_BQPIP*)tao->data;
    187:   PetscErrorCode     ierr;
    188:   PetscInt           its;
    189:   PetscReal          d1,d2,ksptol,sigma;
    190:   PetscReal          sigmamu;
    191:   PetscReal          dstep,pstep,step=0;
    192:   PetscReal          gap[4];
    193:   TaoConvergedReason reason;

    196:   qp->dobj           = 0.0;
    197:   qp->pobj           = 1.0;
    198:   qp->gap            = 10.0;
    199:   qp->rgap           = 1.0;
    200:   qp->mu             = 1.0;
    201:   qp->sigma          = 1.0;
    202:   qp->dinfeas        = 1.0;
    203:   qp->psteplength    = 0.0;
    204:   qp->dsteplength    = 0.0;

    206:   /* Tighten infinite bounds, things break when we don't do this
    207:     -- see test_bqpip.c
    208:   */
    209:   VecSet(qp->XU,1.0e20);
    210:   VecSet(qp->XL,-1.0e20);
    211:   VecPointwiseMax(qp->XL,qp->XL,tao->XL);
    212:   VecPointwiseMin(qp->XU,qp->XU,tao->XU);

    214:   TaoComputeObjectiveAndGradient(tao,tao->solution,&qp->c,qp->C0);
    215:   TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);
    216:   MatMult(tao->hessian, tao->solution, qp->Work);
    217:   VecDot(tao->solution, qp->Work, &d1);
    218:   VecAXPY(qp->C0, -1.0, qp->Work);
    219:   VecDot(qp->C0, tao->solution, &d2);
    220:   qp->c -= (d1/2.0+d2);
    221:   MatGetDiagonal(tao->hessian, qp->HDiag);

    223:   QPIPSetInitialPoint(qp,tao);
    224:   QPIPComputeResidual(qp,tao);

    226:   /* Enter main loop */
    227:   while (PETSC_TRUE){

    229:     /* Check Stopping Condition      */
    230:     TaoMonitor(tao,tao->niter,qp->pobj,PetscSqrtScalar(qp->gap + qp->dinfeas),qp->pinfeas, step, &reason);
    231:     if (reason != TAO_CONTINUE_ITERATING) break;
    232:     tao->niter++;
    233:     tao->ksp_its=0;

    235:     /*
    236:        Dual Infeasibility Direction should already be in the right
    237:        hand side from computing the residuals
    238:     */

    240:     QPIPComputeNormFromCentralPath(qp,&d1);

    242:     if (tao->niter > 0 && (qp->rnorm>5*qp->mu || d1*d1>qp->m*qp->mu*qp->mu) ) {
    243:       sigma=1.0;sigmamu=qp->mu;
    244:       sigma=0.0;sigmamu=0;
    245:     } else {
    246:       sigma=0.0;sigmamu=0;
    247:     }
    248:     VecSet(qp->DZ, sigmamu);
    249:     VecSet(qp->DS, sigmamu);

    251:     if (sigmamu !=0){
    252:       VecPointwiseDivide(qp->DZ, qp->DZ, qp->G);
    253:       VecPointwiseDivide(qp->DS, qp->DS, qp->T);
    254:       VecCopy(qp->DZ,qp->RHS2);
    255:       VecAXPY(qp->RHS2, 1.0, qp->DS);
    256:     } else {
    257:       VecZeroEntries(qp->RHS2);
    258:     }

    261:     /*
    262:        Compute the Primal Infeasiblitiy RHS and the
    263:        Diagonal Matrix to be added to H and store in Work
    264:     */
    265:     VecPointwiseDivide(qp->DiagAxpy, qp->Z, qp->G);
    266:     VecPointwiseMult(qp->GZwork, qp->DiagAxpy, qp->R3);
    267:     VecAXPY(qp->RHS, -1.0, qp->GZwork);

    269:     VecPointwiseDivide(qp->TSwork, qp->S, qp->T);
    270:     VecAXPY(qp->DiagAxpy, 1.0, qp->TSwork);
    271:     VecPointwiseMult(qp->TSwork, qp->TSwork, qp->R5);
    272:     VecAXPY(qp->RHS, -1.0, qp->TSwork);
    273:     VecAXPY(qp->RHS2, 1.0, qp->RHS);

    275:     /*  Determine the solving tolerance */
    276:     ksptol = qp->mu/10.0;
    277:     ksptol = PetscMin(ksptol,0.001);

    279:     MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);
    280:     MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);
    281:     MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);

    283:     KSPSetOperators(tao->ksp, tao->hessian, tao->hessian_pre);
    284:     KSPSolve(tao->ksp, qp->RHS, tao->stepdirection);
    285:     KSPGetIterationNumber(tao->ksp,&its);
    286:     tao->ksp_its+=its;
    287:     tao->ksp_tot_its+=its;

    289:     VecScale(qp->DiagAxpy, -1.0);
    290:     MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);
    291:     MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);
    292:     MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);
    293:     VecScale(qp->DiagAxpy, -1.0);
    294:     QPComputeStepDirection(qp,tao);
    295:     QPStepLength(qp);

    297:     /* Calculate New Residual R1 in Work vector */
    298:     MatMult(tao->hessian, tao->stepdirection, qp->RHS2);
    299:     VecAXPY(qp->RHS2, 1.0, qp->DS);
    300:     VecAXPY(qp->RHS2, -1.0, qp->DZ);
    301:     VecAYPX(qp->RHS2, qp->dsteplength, tao->gradient);

    303:     VecNorm(qp->RHS2, NORM_2, &qp->dinfeas);
    304:     VecDot(qp->DZ, qp->DG, gap);
    305:     VecDot(qp->DS, qp->DT, gap+1);

    307:     qp->rnorm=(qp->dinfeas+qp->psteplength*qp->pinfeas)/(qp->m+qp->n);
    308:     pstep = qp->psteplength; dstep = qp->dsteplength;
    309:     step = PetscMin(qp->psteplength,qp->dsteplength);
    310:     sigmamu= ( pstep*pstep*(gap[0]+gap[1]) +
    311:                (1 - pstep + pstep*sigma)*qp->gap  )/qp->m;

    313:     if (qp->predcorr && step < 0.9){
    314:       if (sigmamu < qp->mu){
    315:         sigmamu=sigmamu/qp->mu;
    316:         sigmamu=sigmamu*sigmamu*sigmamu;
    317:       } else {sigmamu = 1.0;}
    318:       sigmamu = sigmamu*qp->mu;

    320:       /* Compute Corrector Step */
    321:       VecPointwiseMult(qp->DZ, qp->DG, qp->DZ);
    322:       VecScale(qp->DZ, -1.0);
    323:       VecShift(qp->DZ, sigmamu);
    324:       VecPointwiseDivide(qp->DZ, qp->DZ, qp->G);

    326:       VecPointwiseMult(qp->DS, qp->DS, qp->DT);
    327:       VecScale(qp->DS, -1.0);
    328:       VecShift(qp->DS, sigmamu);
    329:       VecPointwiseDivide(qp->DS, qp->DS, qp->T);

    331:       VecCopy(qp->DZ, qp->RHS2);
    332:       VecAXPY(qp->RHS2, -1.0, qp->DS);
    333:       VecAXPY(qp->RHS2, 1.0, qp->RHS);

    335:       /* Approximately solve the linear system */
    336:       MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);
    337:       MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);
    338:       MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);
    339:       KSPSolve(tao->ksp, qp->RHS2, tao->stepdirection);
    340:       KSPGetIterationNumber(tao->ksp,&its);
    341:       tao->ksp_its+=its;
    342:       tao->ksp_tot_its+=its;

    344:       MatDiagonalSet(tao->hessian, qp->HDiag, INSERT_VALUES);
    345:       MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);
    346:       MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);
    347:       QPComputeStepDirection(qp,tao);
    348:       QPStepLength(qp);

    350:     }  /* End Corrector step */

    353:     /* Take the step */
    354:     pstep = qp->psteplength; dstep = qp->dsteplength;

    356:     VecAXPY(qp->Z, dstep, qp->DZ);
    357:     VecAXPY(qp->S, dstep, qp->DS);
    358:     VecAXPY(tao->solution, dstep, tao->stepdirection);
    359:     VecAXPY(qp->G, dstep, qp->DG);
    360:     VecAXPY(qp->T, dstep, qp->DT);

    362:     /* Compute Residuals */
    363:     QPIPComputeResidual(qp,tao);

    365:     /* Evaluate quadratic function */
    366:     MatMult(tao->hessian, tao->solution, qp->Work);

    368:     VecDot(tao->solution, qp->Work, &d1);
    369:     VecDot(tao->solution, qp->C0, &d2);
    370:     VecDot(qp->G, qp->Z, gap);
    371:     VecDot(qp->T, qp->S, gap+1);

    373:     qp->pobj=d1/2.0 + d2+qp->c;
    374:     /* Compute the duality gap */
    375:     qp->gap = (gap[0]+gap[1]);
    376:     qp->dobj = qp->pobj - qp->gap;
    377:     if (qp->m>0) qp->mu=qp->gap/(qp->m);
    378:     qp->rgap=qp->gap/( PetscAbsReal(qp->dobj) + PetscAbsReal(qp->pobj) + 1.0 );
    379:   }  /* END MAIN LOOP  */

    381:   return(0);
    382: }

    386: static PetscErrorCode QPComputeStepDirection(TAO_BQPIP *qp, Tao tao)
    387: {

    392:   /* Calculate DG */
    393:   VecCopy(tao->stepdirection, qp->DG);
    394:   VecAXPY(qp->DG, 1.0, qp->R3);

    396:   /* Calculate DT */
    397:   VecCopy(tao->stepdirection, qp->DT);
    398:   VecScale(qp->DT, -1.0);
    399:   VecAXPY(qp->DT, -1.0, qp->R5);

    402:   /* Calculate DZ */
    403:   VecAXPY(qp->DZ, -1.0, qp->Z);
    404:   VecPointwiseDivide(qp->GZwork, qp->DG, qp->G);
    405:   VecPointwiseMult(qp->GZwork, qp->GZwork, qp->Z);
    406:   VecAXPY(qp->DZ, -1.0, qp->GZwork);

    408:   /* Calculate DS */
    409:   VecAXPY(qp->DS, -1.0, qp->S);
    410:   VecPointwiseDivide(qp->TSwork, qp->DT, qp->T);
    411:   VecPointwiseMult(qp->TSwork, qp->TSwork, qp->S);
    412:   VecAXPY(qp->DS, -1.0, qp->TSwork);

    414:   return(0);
    415: }

    419: static PetscErrorCode QPIPComputeResidual(TAO_BQPIP *qp, Tao tao)
    420: {
    422:   PetscReal dtmp = 1.0 - qp->psteplength;

    426:   /* Compute R3 and R5 */

    428:   VecScale(qp->R3, dtmp);
    429:   VecScale(qp->R5, dtmp);
    430:   qp->pinfeas=dtmp*qp->pinfeas;

    433:   VecCopy(qp->S, tao->gradient);
    434:   VecAXPY(tao->gradient, -1.0, qp->Z);

    436:   MatMult(tao->hessian, tao->solution, qp->RHS);
    437:   VecScale(qp->RHS, -1.0);
    438:   VecAXPY(qp->RHS, -1.0, qp->C0);
    439:   VecAXPY(tao->gradient, -1.0, qp->RHS);

    441:   VecNorm(tao->gradient, NORM_1, &qp->dinfeas);
    442:   qp->rnorm=(qp->dinfeas+qp->pinfeas)/(qp->m+qp->n);

    444:   return(0);
    445: }

    449: static PetscErrorCode QPStepLength(TAO_BQPIP *qp)
    450: {
    451:   PetscReal tstep1,tstep2,tstep3,tstep4,tstep;

    455:   /* Compute stepsize to the boundary */
    456:   VecStepMax(qp->G, qp->DG, &tstep1);
    457:   VecStepMax(qp->T, qp->DT, &tstep2);
    458:   VecStepMax(qp->S, qp->DS, &tstep3);
    459:   VecStepMax(qp->Z, qp->DZ, &tstep4);

    462:   tstep = PetscMin(tstep1,tstep2);
    463:   qp->psteplength = PetscMin(0.95*tstep,1.0);

    465:   tstep = PetscMin(tstep3,tstep4);
    466:   qp->dsteplength = PetscMin(0.95*tstep,1.0);

    468:   qp->psteplength = PetscMin(qp->psteplength,qp->dsteplength);
    469:   qp->dsteplength = qp->psteplength;

    471:   return(0);
    472: }

    477: PetscErrorCode TaoComputeDual_BQPIP(Tao tao,Vec DXL, Vec DXU)
    478: {
    479:   TAO_BQPIP *qp = (TAO_BQPIP*)tao->data;
    480:   PetscErrorCode       ierr;

    483:   VecCopy(qp->Z, DXL);
    484:   VecCopy(qp->S, DXU);
    485:   VecScale(DXU, -1.0);
    486:   return(0);
    487: }

    492: PetscErrorCode QPIPComputeNormFromCentralPath(TAO_BQPIP *qp, PetscReal *norm)
    493: {
    494:   PetscErrorCode       ierr;
    495:   PetscReal    gap[2],mu[2], nmu;

    498:   VecPointwiseMult(qp->GZwork, qp->G, qp->Z);
    499:   VecPointwiseMult(qp->TSwork, qp->T, qp->S);
    500:   VecNorm(qp->TSwork, NORM_1, &mu[0]);
    501:   VecNorm(qp->GZwork, NORM_1, &mu[1]);

    503:   nmu=-(mu[0]+mu[1])/qp->m;

    505:   VecShift(qp->GZwork,nmu);
    506:   VecShift(qp->TSwork,nmu);

    508:   VecNorm(qp->GZwork,NORM_2,&gap[0]);
    509:   VecNorm(qp->TSwork,NORM_2,&gap[1]);
    510:   gap[0]*=gap[0];
    511:   gap[1]*=gap[1];

    514:   qp->pathnorm=PetscSqrtScalar( (gap[0]+gap[1]) );
    515:   *norm=qp->pathnorm;

    517:   return(0);
    518: }

    522: static PetscErrorCode TaoSetFromOptions_BQPIP(PetscOptions *PetscOptionsObject,Tao tao)
    523: {
    524:   TAO_BQPIP      *qp = (TAO_BQPIP*)tao->data;

    528:   PetscOptionsHead(PetscOptionsObject,"Interior point method for bound constrained quadratic optimization");
    529:   PetscOptionsInt("-tao_bqpip_predcorr","Use a predictor-corrector method","",qp->predcorr,&qp->predcorr,0);
    530:   PetscOptionsTail();
    531:   KSPSetFromOptions(tao->ksp);
    532:   return(0);
    533: }

    537: static PetscErrorCode TaoView_BQPIP(Tao tao, PetscViewer viewer)
    538: {
    540:   return(0);
    541: }

    543: /* --------------------------------------------------------- */
    544: /*MC
    545:  TAOBQPIP - bounded quadratic interior point algorithm for quadratic
    546:     optimization with box constraints.

    548:  Notes: This algorithms solves quadratic problems only, the linear Hessian will
    549:         only be computed once.

    551:  Options Database Keys:
    552: . -tao_bqpip_predcorr - use a predictor/corrector method

    554:   Level: beginner
    555: M*/

    559: PETSC_EXTERN PetscErrorCode TaoCreate_BQPIP(Tao tao)
    560: {
    561:   TAO_BQPIP      *qp;

    565:   PetscNewLog(tao,&qp);
    566:   tao->ops->setup = TaoSetUp_BQPIP;
    567:   tao->ops->solve = TaoSolve_BQPIP;
    568:   tao->ops->view = TaoView_BQPIP;
    569:   tao->ops->setfromoptions = TaoSetFromOptions_BQPIP;
    570:   tao->ops->destroy = TaoDestroy_BQPIP;
    571:   tao->ops->computedual = TaoComputeDual_BQPIP;

    573:   /* Override default settings (unless already changed) */
    574:   if (!tao->max_it_changed) tao->max_it=100;
    575:   if (!tao->max_funcs_changed) tao->max_funcs = 500;
    576: #if defined(PETSC_USE_REAL_SINGLE)
    577:   if (!tao->fatol_changed) tao->fatol=1e-6;
    578:   if (!tao->frtol_changed) tao->frtol=1e-6;
    579:   if (!tao->catol_changed) tao->catol=1e-6;
    580: #else
    581:   if (!tao->fatol_changed) tao->fatol=1e-12;
    582:   if (!tao->frtol_changed) tao->frtol=1e-12;
    583:   if (!tao->catol_changed) tao->catol=1e-12;
    584: #endif

    586:   /* Initialize pointers and variables */
    587:   qp->n              = 0;
    588:   qp->m              = 0;
    589:   qp->ksp_tol       = 0.1;

    591:   qp->predcorr       = 1;
    592:   tao->data = (void*)qp;

    594:   KSPCreate(((PetscObject)tao)->comm, &tao->ksp);
    595:   KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix);
    596:   KSPSetType(tao->ksp, KSPCG);
    597:   KSPSetTolerances(tao->ksp, 1e-14, 1e-30, 1e30, PetscMax(10,qp->n));
    598:   return(0);
    599: }