private boolean performLineSearch ( ) { // if true then it can't iterate any more if ( lineSearch . iterate ( ) ) { // see if the line search failed if ( ! lineSearch . isConverged ( ) ) { if ( firstStep ) { // if it failed on the very first step then it might have been too large // try halving the step size initialStep /= 2 ; if ( initialStep != 0 ) { invokeLineInitialize ( fx , maxStep ) ; return false ; } else { if ( verbose != null && verboseLevel != 0 ) { verbose . println ( "Initial step reduced to zero" ) ; } return terminateSearch ( false ) ; } } else { return terminateSearch ( false ) ; } } else { firstStep = false ; } // update variables double step = lineSearch . getStep ( ) ; // save the new x System . arraycopy ( function . getCurrentState ( ) , 0 , x . data , 0 , N ) ; // compute the change in the x for ( int i = 0 ; i < N ; i ++ ) s . data [ i ] = step * searchVector . data [ i ] ; updated = true ; // convergence tests // function value at end of line search double fstp = lineSearch . getFunction ( ) ; if ( verbose != null ) { double actualStep = NormOps_DDRM . fastNormF ( s ) ; double ftest_val = Math . abs ( fstp - fx ) / Math . abs ( fx ) ; double gtest_val = Math . abs ( derivAtZero ) ; verbose . printf ( "%-4d %9.3E %10.3E %9.3E %9.3E %9.3E %6.3f\n" , iterations , fstp , fstp - fx , actualStep , ftest_val , gtest_val , maxStep ) ; } // see if the actual different and predicted differences are smaller than the // error tolerance if ( Math . abs ( fstp - fx ) <= ftol * Math . abs ( fx ) || Math . abs ( derivAtZero ) < gtol ) { if ( verbose != null ) { verbose . println ( "converged after line search." ) ; } return terminateSearch ( true ) ; } if ( fstp > fx ) { throw new RuntimeException ( "Bug! Worse results!" ) ; } // current function value is now the previous fx = fstp ; // start the loop again mode = 0 ; } return false ; }
Performs a 1 - D line search along the chosen direction until the Wolfe conditions have been meet .