void RV_Missing_t_walk_core::find_slice() {
    total_slice_length = 0.0;
    intervals.clear();
    find_peaks();

    peaks.erase(
        std::remove_if(peaks.begin(), peaks.end(),
            [=](double x) {
                return lpdf(x) < ly ? true : false;
            }
        ),
        peaks.end()
    );
    if (peaks.size() < 1) {
			std::cout << "Warning: peak finding failed, defined from" 
									 "\non current state." << std::endl;
			peaks.push_back(x2);
		}
//        throw std::runtime_error("No peaks found above slice.");

    // step out from peak.
    peak_bound_lr.clear();
    for (std::vector<double>::iterator i = peaks.begin();
                i != peaks.end(); ++i) {
        peak_bound_lr.push_back(step_out(i));
    }
    // Fix overlap
    for (unsigned int i = 0; i != (peak_bound_lr.size()-1); i++) {
        if (peak_bound_lr[i+1][0] < peak_bound_lr[i][1] ) {
            double mid = (peaks[i+1] + peaks[i])/2.0;
            peak_bound_lr[i+1][0] = mid;
            peak_bound_lr[i][1] = mid;
        }
    }

    for (std::vector<std::vector<double> >::iterator i = peak_bound_lr.begin();
                i != peak_bound_lr.end(); ++i)
    {
        bool lb = (i == (peak_bound_lr.end() - 1 ));
        // Calculate sub-slice to sub-slice distances:
        total_slice_length += (*i)[1] - (*i)[0];
        if (!lb) {
            intervals.push_back((*(i+1))[0] - (*i)[1]);
        }
    }
    if (peak_bound_lr.size() != peaks.size() )
        throw std::runtime_error("Mismatch between number of peaks and number of bounds.");

}
Beispiel #2
0
double LayerNet::direcmin (
   TrainingSet *tptr , // Training set to use
   double start_err ,  // Error (function value) at starting coefficients
   int itmax ,         // Upper limit on number of iterations allowed
   double eps ,        // Small, but greater than machine precision
   double tol ,        // Brent's tolerance (>= sqrt machine precision)
   double *base ,      // Work area (stepping out point)
   double *direc )     // Work area (stepping out direction)
{
   int key, user_quit, iter ;
   double step, x1, x2, x3, t1, t2, numer, denom, max_step ;
   double xlow, xhigh, xbest, testdist ;
   double current_err, err, previous_err, step_err ;
   double prevdist, etemp, frecent, fthirdbest, fsecbest, fbest ;
   double tol1, tol2, xrecent, xthirdbest, xsecbest, xmid;
   double  first_step = 2.5 ; // Heuristically found best

   user_quit = 0 ;

/*
   Take one step out in the gradient direction.  First preserve
   original weights for use as departure point parameterized by STEP.
*/

   preserve ( base ) ;   // Establishes a base for stepping out
   step_out ( first_step , direc , base ) ;
   err = trial_error ( tptr ) ;

/*
   If it increased, we had numerical problems computing the direction or
   the direction itself is too large a step.
   Negate the direction and use -1, 0 and 1.618 as first three steps.
   Otherwise use 0, 1 and 2.618 as first three steps.
*/

   if (err > start_err) {
      negate_dir ( direc ) ;
      x1 = -first_step ;
      x2 = 0. ;
      previous_err = err ;
      current_err = start_err ;
      }
   else {
      x1 = 0. ;
      x2 = first_step ;
      previous_err = start_err ;
      current_err = err ;
      }

/*
   At this point we have taken a single step and the function decreased.
   Take one more step in the golden ratio.
   Also keep errors lined up as 'previous_err', 'current_err' and 'err'.
   The corresponding abscissae will be x1, x2 and x3.
*/

/************************************************************************
   if (kbhit()) {          // Was a key pressed?
      key = getch () ;     // Read it if so
      while (kbhit())      // Flush key buffer in case function key
         getch () ;        // or key was held down
      if (key == 27)       // ESCape
         return (- err) ;
      }
***********************************************************************/

   x3 = x2 + 1.618034 * first_step ;
   step_out ( x3 , direc , base ) ;
   err = trial_error ( tptr ) ;

/*
   We now have three points x1, x2 and x3 with corresponding errors
   of 'previous_err', 'current_err' and 'err'.
   Endlessly loop until we bracket the minimum with the outer two.
*/

   while (err < current_err) {   // As long as we are descending...

/*********************************************************************
      if (kbhit()) {          // Was a key pressed?
         key = getch () ;     // Read it if so
         while (kbhit())      // Flush key buffer in case function key
            getch () ;        // or key was held down
         if (key == 27) {     // ESCape
            user_quit = 1 ;
            break ;
            }
         }

********************************************************************/

/*
   Try a parabolic fit to estimate the location of the minimum.
*/

      t1 = (x2 - x1) * (current_err - err) ;
      t2 = (x2 - x3) * (current_err - previous_err) ;
      denom = 2. * ( t2 - t1 ) ;
      if (fabs ( denom ) < eps) {
         if (denom > 0.)
            denom = eps ;
         else
            denom = -eps ;
         }
      step = x2 + ((x2 - x1) * t1  -  (x2 - x3) * t2) / denom ;//Here if perfect
      max_step = x2 + 200. * (x3 - x2) ; // Don't jump too far

      if ((x2 - step) * (step - x3)  >  0.) {         // It's between x2 and x3
         step_out ( step , direc , base ) ;
         step_err = trial_error ( tptr ) ;

         if (step_err < err) {   // It worked!  We found min between b and c.

            x1 = x2 ;
            x2 = step ;
            previous_err = current_err ;
            current_err = step_err ;
            goto BOUNDED ;
            }
         else if (step_err > current_err) { // Slight miscalc.  Min at x2.
            x3 = step ;
            err = step_err ;
            goto BOUNDED ;
            }
         else {             // Parabolic fit was total waste.  Use default.
            step = x3 + 1.618034 * (x3 - x2) ;
            step_out ( step , direc , base ) ;
            step_err = trial_error ( tptr ) ;
            }
         }

      else if ((x3 - step) * (step - max_step) > 0.0) { // Between x3 and lim
         step_out ( step , direc , base ) ;
         step_err = trial_error ( tptr ) ;
         if (step_err < err) {  // Decreased, so advance by golden ratio
            x2 = x3 ;
            x3 = step ;
            step = x3 + 1.618034 * (x3 - x2) ;
            current_err = err ;
            err = step_err ;
            step_out ( step , direc , base ) ;
            step_err = trial_error ( tptr ) ;
            }
         }

      else if ((step - max_step) * (max_step - x3)  >= 0.) {  // Beyond limit
         step = max_step ;
         step_out ( step , direc , base ) ;
         step_err = trial_error ( tptr ) ;
         if (step_err < err) {  // Decreased, so advance by golden ratio
            x2 = x3 ;
            x3 = step ;
            step = x3 + 1.618034 * (x3 - x2) ;
            current_err = err ;
            err = step_err ;
            step_out ( step , direc , base ) ;
            step_err = trial_error ( tptr ) ;
            }
         }

      else {  // Wild!  Reject parabolic and use golden ratio.
         step = x3 + 1.618034 * (x3 - x2) ;
         step_out ( step , direc , base ) ;
         step_err = trial_error ( tptr ) ;
         }

/*
   Shift three points and continue endless loop
*/

      x1 = x2 ;
      x2 = x3 ;
      x3 = step ;
      previous_err = current_err ;
      current_err = err ;
      err = step_err ;
      } // Endless stepping out loop

BOUNDED:
   step_out ( x2 , direc , base);//Leave coefs at min

   if (x1 > x3) {  // We may have switched direction at start.
      t1 = x1 ;    // Brent's method which follows assumes ordered parameter.
      x1 = x3 ;
      x3 = t1 ;
      }

   if (user_quit) {
      update_dir ( x2 , direc ) ;// Make it be the actual dist moved
      return -current_err ;
      }

/*
--------------------------------------------------------------------------------

   At this point we have bounded the minimum between x1 and x3.

   Go to the refinement stage.  We use Brent's algorithm.

--------------------------------------------------------------------------------
*/

/*
  Initialize prevdist, the distance moved on the previous step, to 0 so that
  the 'if (fabs ( prevdist )  >  tol1)' encountered on the first iteration
  below will fail, forcing a golden section the first time.  Also initialize
  step to 0 to avoid a zealous compiler from pointing out that it was
  referenced before being set.
*/

   prevdist = step = 0.0 ;

/*
   We always keep the minimum bracketed between xlow and xhigh.
   xbest has the min function so far (or latest if tie).
   xsecbest and xthirdbest are the second and third best.
*/

   xbest = xsecbest = xthirdbest = x2 ;
   xlow = x1 ;
   xhigh = x3 ;

   fbest = fsecbest = fthirdbest = current_err ;


/*
   Main loop.  For safety we impose a limit on iterations.
*/

   for (iter=0 ; iter<itmax ; iter++) {

      xmid = 0.5 * (xlow + xhigh) ;
      tol1 = tol * (fabs ( xbest ) + eps) ;
      tol2 = 2. * tol1 ;

/***************************************************************************
      if (kbhit()) {          // Was a key pressed?
         key = getch () ;     // Read it if so
         while (kbhit())      // Flush key buffer in case function key
            getch () ;        // or key was held down
         if (key == 27) {     // ESCape
            user_quit = 1 ;
            break ;
            }
         }
**************************************************************************/


/*
   The following convergence test simultaneously makes sure xhigh and
   xlow are close relative to tol2, and that xbest is near the midpoint.
*/
      if (fabs ( xbest - xmid )  <=  (tol2 - 0.5 * (xhigh - xlow)))
         break ;

      if (fabs ( prevdist )  >  tol1) {  // If we moved far enough try parabolic fit
         t1 = (xbest - xsecbest) * (fbest - fthirdbest) ; // Temps for the
         t2 = (xbest - xthirdbest) * (fbest - fsecbest) ; // parabolic estimate
         numer = (xbest - xthirdbest) * t2  -  (xbest - xsecbest) * t1 ;
         denom = 2. * (t1 - t2) ;  // Estimate will be numer / denom
         testdist = prevdist ;     // Will soon verify interval is shrinking
         prevdist = step ;         // Save for next iteration
         if (denom != 0.0)         // Avoid dividing by zero
            step = numer / denom ; // This is the parabolic estimate to min
         else 
            step = 1.e30 ;         // Assures failure of next test

         if ((fabs ( step ) < fabs ( 0.5 * testdist ))// If shrinking
          && (step + xbest > xlow)             // and within known bounds
          && (step + xbest < xhigh)) {         // then we can use the
            xrecent = xbest + step ;           // parabolic estimate
            if ((xrecent - xlow  <  tol2)  ||  // If we are very close
                (xhigh - xrecent <  tol2)) {   // to known bounds
               if (xbest < xmid)               // then stabilize
                  step = tol1 ;
               else
                  step = -tol1 ;
               }
            }
         else {  // Parabolic estimate poor, so use golden section
            prevdist = (xbest >= xmid)  ?  xlow - xbest  :  xhigh - xbest ;          // Poor so use    
            step = .3819660 * prevdist ;
            }
         }
      else { // prevdist did not exceed tol1: we did not move far enough
             // to justify a parabolic fit.  Use golden section.
         prevdist = (xbest >= xmid)  ?  xlow - xbest  :  xhigh - xbest ;
         step = .3819660 * prevdist ;
         }

      if (fabs (step)  >=  tol1)     // In order to numerically justify
         xrecent = xbest + step ;    // another trial we must move a
      else {                         // decent distance.
         if (step > 0.)
            xrecent = xbest + tol1 ;
         else
            xrecent = xbest - tol1 ;
         }

/*
   At long last we have a trial point 'xrecent'.  Evaluate the function.
*/

      step_out ( xrecent , direc , base ) ;
      frecent = trial_error ( tptr ) ;

      if (frecent <= fbest) {    // If we improved...
         if (xrecent >= xbest)   // Shrink the (xlow,xhigh) interval by
            xlow = xbest ;       // replacing the appropriate endpoint
         else
            xhigh = xbest ;
         xthirdbest = xsecbest ; // Update x and f values for best,
         xsecbest = xbest ;      // second and third best
         xbest = xrecent ;
         fthirdbest = fsecbest ;
         fsecbest = fbest ;
         fbest = frecent ;
         }

      else {                  // We did not improve
         if (xrecent < xbest) // Shrink the (xlow,xhigh) interval by
            xlow = xrecent ;  // replacing the appropriate endpoint
         else
            xhigh = xrecent ;

         if ((frecent <= fsecbest)   // If we at least beat the second best
          || (xsecbest == xbest)) {  // or we had a duplication
            xthirdbest = xsecbest ;  // we can update the second and third
            xsecbest = xrecent ;     // best, though not the best.
            fthirdbest = fsecbest ;  // Recall that we started iters with
            fsecbest = frecent ;     // best, sec and third all equal.
            }
         else if ((frecent <= fthirdbest) // Oh well.  Maybe at least we can
           || (xthirdbest == xbest)       // beat the third best or rid
           || (xthirdbest == xsecbest)) { // ourselves of a duplication
            xthirdbest = xrecent ;        // (which is how we start the
            fthirdbest = frecent ;        // iterations)
            }
         }
      }
 
   step_out ( xbest , direc , base );//Leave coefs at min
   update_dir ( xbest , direc ) ;// Make it be the actual distance moved

   if (user_quit)
      return -fbest ;
   else 
      return fbest ;
}