//Returns intersection interval if it exist, NULL if there is no. bool Interval::intersect(interval_t result, interval_t interval1, interval_t interval2) { double x1 = INTERVAL_X1(interval1), x2 = INTERVAL_X2(interval1), y1 = INTERVAL_X1(interval2), y2 = INTERVAL_X2(interval2); if(x1 > y2) { result->null(); return false; } if(x1 < y1) { if(x2 < y1) { result->null(); return false; } if(x2 > y2) newInterval(result, y1, y2); else newInterval(result, y1, x2); } else if(x2 < y2) // [x1,x2] in [y1,y2] newInterval(result, x1, x2); else newInterval(result, x1, y2); return true; }
double root_find_solution( const MatrixFactory &mf, const interval_t ®ion, const std::vector< double > lower_vals, const std::vector< double > upper_vals, double epsilon ) { int index = std::upper_bound( lower_vals.begin(), lower_vals.end(), region.lower() ) - lower_vals.begin(); double flower = lower_vals[index] - region.lower(); double fupper = upper_vals[index] - region.upper(); return util::false_position( boost::bind( base_root_function, _1, boost::cref(mf), index ), region.lower(), region.upper(), flower, fupper, epsilon ); }
static void get_closed_bounds(const interval_t &interval, channel_t &lower, channel_t &upper) { lower = interval.lower(); upper = interval.upper(); if(!(interval.bounds().bits() & 2)) { lower += 1; } if(!(interval.bounds().bits() & 1)) { upper -= 1; } }
// This is the main search algorithm for the (D)ERPA. std::vector< double > solve_region( const MatrixFactory &mf, const interval_t ®ion, const std::vector< double > lower_vals, const std::vector< double > upper_vals, double epsilon ) { // Determine # solutions int num_solutions = get_num_solutions( lower_vals, region.lower(), upper_vals, region.upper() ); // If no solutions, return empty. if ( 0 == num_solutions ) { return std::vector< double >(); } // If the interval has no width, but has solutions, return the value. if ( std::abs( region.upper() - region.lower() ) < epsilon ) { return std::vector< double >( 1, region.lower() ); } // If 1 solution, root_find. if ( 1 == num_solutions ) { std::vector< double > temp( 1, root_find_solution( mf, region, lower_vals, upper_vals, epsilon ) ); return temp; } // If > 1 solution, sub-divide region. double center = boost::numeric::median( region ); std::vector< double > center_vals = util::sorted_eigenvalues( mf.build( center ) ); std::vector< double > solutions = solve_region( mf, interval_t( region.lower(), center ), lower_vals, center_vals, epsilon ); { std::vector< double > upper_solutions = solve_region( mf, interval_t( center, region.upper() ), center_vals, upper_vals, epsilon ); solutions.insert( solutions.end(), upper_solutions.begin(), upper_solutions.end() ); } return solutions; }