T operator()( const Image<T> & src , const float y , const float x ) const { const int im_width = src.Width() ; const int im_height = src.Height() ; // Get sampler coefficients double coefs_x[ SamplerFunc::neighbor_width ] ; double coefs_y[ SamplerFunc::neighbor_width ] ; // Compute difference between exact pixel location and sample const double dx = static_cast<double>( x ) - floor( x ) ; const double dy = static_cast<double>( y ) - floor( y ) ; // Get sampler weights sampler_( dx , coefs_x ) ; sampler_( dy , coefs_y ) ; typename RealPixel<T>::real_type res( 0 ) ; // integer position of sample (x,y) const int grid_x = static_cast<int>( floor( x ) ); const int grid_y = static_cast<int>( floor( y ) ); // Sample a grid around specified grid point double total_weight = 0.0 ; for( int i = 0 ; i < SamplerFunc::neighbor_width ; ++i ) { // Get current i value // +1 for correct scheme (draw it to be conviced) const int cur_i = grid_y + 1 + i - half_width_ ; // handle out of range if( cur_i < 0 || cur_i >= im_height ) { continue ; } for( int j = 0 ; j < SamplerFunc::neighbor_width ; ++j ) { // Get current j value // +1 for the same reason const int cur_j = grid_x + 1 + j - half_width_ ; // handle out of range if( cur_j < 0 || cur_j >= im_width ) { continue ; } // sample input image and weight according to sampler const double w = coefs_x[ j ] * coefs_y[ i ] ; const typename RealPixel<T>::real_type pix = RealPixel<T>::convert_to_real( src( cur_i , cur_j ) ) ; const typename RealPixel<T>::real_type wp = pix * w ; res += wp ; total_weight += w ; } } // If value too small, it should be so instable, so return the sampled value if( total_weight <= 0.2 ) { return T(); } if( total_weight != 1.0 ) { res /= total_weight ; } return RealPixel<T>::convert_from_real( res ) ; }
EndCriteria::Type HybridSimulatedAnnealing<Sampler, Probability, Temperature, Reannealing>::minimize(Problem &P, const EndCriteria &endCriteria) { EndCriteria::Type ecType = EndCriteria::None; P.reset(); reannealing_.setProblem(P); Array x = P.currentValue(); Size n = x.size(); Size k = 1; Size kStationary = 1; Size kReAnneal = 1; Size kReset = 1; Size maxK = endCriteria.maxIterations(); Size maxKStationary = endCriteria.maxStationaryStateIterations(); bool temperatureBreached = false; Array currentTemperature(n, startTemperature_); Array annealStep(n, 1.0); Array bestPoint(x); Array currentPoint(x); Array startingPoint(x); Array newPoint(x); Real bestValue = P.value(bestPoint); Real currentValue = bestValue; Real startingValue = bestValue; //to reset to starting point if desired while (k <= maxK && kStationary <= maxKStationary && !temperatureBreached) { //Draw a new sample point sampler_(newPoint, currentPoint, currentTemperature); //Evaluate new point Real newValue = P.value(newPoint); //Determine if new point is accepted if (probability_(currentValue, newValue, currentTemperature)) { if (optimizeScheme_ == EveryNewPoint) { P.setCurrentValue(newPoint); P.setFunctionValue(newValue); localOptimizer_->minimize(P, endCriteria); newPoint = P.currentValue(); newValue = P.functionValue(); } currentPoint = newPoint; currentValue = newValue; } //Check if we have a new best point if (newValue < bestValue) { if (optimizeScheme_ == EveryBestPoint) { P.setCurrentValue(newPoint); P.setFunctionValue(newValue); localOptimizer_->minimize(P, endCriteria); newPoint = P.currentValue(); newValue = P.functionValue(); } kStationary = 0; bestValue = newValue; bestPoint = newPoint; } //Increase steps k++; kStationary++; for (Size i = 0; i < annealStep.size(); i++) annealStep[i]++; //Reanneal if necessary if (kReAnneal == reAnnealSteps_) { kReAnneal = 0; reannealing_(annealStep, currentPoint, currentValue, currentTemperature); } kReAnneal++; //Reset if necessary if (kReset == resetSteps_) { kReset = 0; switch (resetScheme_) { case NoResetScheme: break; case ResetToBestPoint: currentPoint = startingPoint; currentValue = startingValue; break; case ResetToOrigin: currentPoint = bestPoint; currentValue = bestValue; break; } } kReset++; //Update the current temperature according to current step temperature_(currentTemperature, currentTemperature, annealStep); //Check if temperature condition is breached for (Size i = 0; i < n; i++) temperatureBreached = temperatureBreached && currentTemperature[i] < endTemperature_; } //Change end criteria type if appropriate if (k > maxK) ecType = EndCriteria::MaxIterations; else if (kStationary > maxKStationary) ecType = EndCriteria::StationaryPoint; //Set result to best point P.setCurrentValue(bestPoint); P.setFunctionValue(bestValue); return ecType; }