realtype N_VMinQuotient_SensWrapper(N_Vector num, N_Vector denom)
{
  int i;
  realtype min, tmp;

  min = N_VMinQuotient(NV_VEC_SW(num,0), NV_VEC_SW(denom,0));

  for (i=1; i < NV_NVECS_SW(num); i++) {
    tmp = N_VMinQuotient(NV_VEC_SW(num,i), NV_VEC_SW(denom,i));
    if (tmp < min) min = tmp;
  }

  return(min);
}
Пример #2
0
static int IDALineSrch(IDAMem IDA_mem, realtype *delnorm, realtype *fnorm)
{
  booleantype conOK;
  int retval;
  realtype f1norm, fnormp, f1normp, ratio, lambda, minlam, slpi;
  N_Vector mc;

  /* Initialize work space pointers, f1norm, ratio.
     (Use of mc in constraint check does not conflict with ypnew.) */
  mc = ee;
  dtemp = phi[3];
  ynew = tempv2;
  ypnew = ee;
  f1norm = (*fnorm)*(*fnorm)*HALF;
  ratio = ONE;

  /* If there are constraints, check and reduce step if necessary. */
  if(constraintsSet) {

    /* Update y and check constraints. */
    IDANewy(IDA_mem);
    conOK = N_VConstrMask(constraints, ynew, mc);

    if(!conOK) {
      /* Not satisfied.  Compute scaled step to satisfy constraints. */
      N_VProd(mc, delta, dtemp);
      ratio = PT99*N_VMinQuotient(yy0, dtemp);
      (*delnorm) *= ratio;
      if((*delnorm) <= steptol) return(IC_CONSTR_FAILED);
      N_VScale(ratio, delta, delta);
    }

  } /* End of constraints check */

  slpi = -TWO*f1norm*ratio;
  minlam = steptol/(*delnorm);
  lambda = ONE;

  /* In IDA_Y_INIT case, set ypnew = yp0 (fixed) for linesearch. */
  if(icopt == IDA_Y_INIT) N_VScale(ONE, yp0, ypnew);

  /* Loop on linesearch variable lambda. */

  loop {

    /* Get new (y,y') = (ynew,ypnew) and norm of new function value. */
    IDANewyyp(IDA_mem, lambda);
    retval = IDAfnorm(IDA_mem, &fnormp);
    if(retval != IDA_SUCCESS) return(retval);

    /* If lsoff option is on, break out. */
    if(lsoff) break;

    /* Do alpha-condition test. */
    f1normp = fnormp*fnormp*HALF;
    if(f1normp <= f1norm + ALPHALS*slpi*lambda) break;
    if(lambda < minlam) return(IC_LINESRCH_FAILED);
    lambda /= TWO;
    nbacktr++;

  }  /* End of breakout linesearch loop */

  /* Update yy0, yp0, and fnorm, then return. */
  N_VScale(ONE, ynew,  yy0);
  if(icopt == IDA_YA_YDP_INIT) N_VScale(ONE, ypnew, yp0);
  *fnorm = fnormp;
  return(IDA_SUCCESS);

}