Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void ScanViewer::Min_Search_Golden_Section
- (
- qreal* a, qreal *fa , /// X->Y on the left side
- qreal* b, qreal* fb , /// X->Y on the right side
- qreal tolerance, QVector < int > x , QVector < int > y /// tolerance limit , vector x ( encoder in mm ) , vector y ( beams in mm )
- /// in case of light grid vector < int > y => QVector <QPair < int , int > limit;
- )
- {
- auto metrics = [this,x,y](qreal A)->qreal /// finds S value based on max and min values of coordinates in rotated CS
- {
- qreal xmax , xmin;
- qreal ymax , ymin;
- QPoint AS = rotate(QPoint(x[0],y[0]),A);
- xmax = xmin = AS.x();
- ymax = ymin = AS.y();
- for ( int m = 0 ; m < x.size() ; m++ )
- {
- QPoint AS = rotate(QPoint(x[m],y[m]),A);
- if (AS.x()>xmax) xmax = AS.x();
- if (AS.x()<xmin) xmin = AS.x();
- if (AS.y()>ymax) ymax = AS.y();
- if (AS.y()<ymin) ymin = AS.y();
- // #form first optimization factor
- }
- return fabs(xmax-xmin)*(ymax-ymin);
- };
- static const double lambda = 0.5 * (sqrt5 - 1.0); /// Constant of golden section ( lambda )
- static const double mu = 0.5 * (3.0 - sqrt5); /// Constant equal 1 - lambda
- double x1; /// left bound
- double x2; /// right bound
- double fx1; /// left bound functional
- double fx2; /// right bound functional
- // Find first two internal points and evaluate
- // the function at the two internal points.
- /// Первичное объявление функций . ( A , B ) = ( 0, Pi/2 ) ; ( x1,x2 ) = (internal points dividing [a;b] & [ b;a ] in gold section)
- x1 = *b - lambda * (*b - *a);
- x2 = *a + lambda * (*b - *a);
- /// S where alfa = x1 and x2
- fx1 = metrics(x1);
- fx2 = metrics(x2);
- // Verify that the tolerance is an acceptable number
- // if (tolerance <= 0.0) tolerance = sqrt(DBL_EPSILON) * (*b - *a);
- // Loop by exluding segments from current endpoints a, b
- // to current internal points x1, x2 and then calculating
- // a new internal point until the length of the interval
- // is less than or equal to the tolerance.
- while ( ! Stopping_Rule( *a, *b, tolerance) ) { /// Пока не достигнута заданная точность
- if (fx1 > fx2) { /// если площадь прямоугольника со сторонами \\ осям в точке 1 > 2
- *a = x1; /// сужаем поисковый интервал слева до точки X1 + захват результата на выход
- *fa = fx1; /// пересчет левого значения площади не нужен - он известен и так
- if ( Stopping_Rule( *a, *b, tolerance) ) break; /// Если поисковый интервал стал подходить по точности выходим
- x1 = x2; /// левая внутренняя точка стала правой
- fx1 = fx2; /// соответствующая запись значения площади
- x2 = *b - mu * (*b - *a); ///
- fx2 = metrics(x2);
- }
- else { /// если площадь прямоугольника со сторонами \\ осям в точке 1 < 2
- *b = x2; /// сужаем поисковый интервал справа до точки X2 + захват результата на выход
- *fb = fx2; /// пересчет правого значения площади не нужен - он известен и так
- if ( Stopping_Rule( *a, *b, tolerance) ) break; /// Если поисковый интервал стал подходить по точности выходим
- x2 = x1; /// правая внутренняя точка стала левой
- fx2 = fx1; /// соответствующая запись значения площади
- x1 = *a + mu * (*b - *a);
- fx1 = metrics(x1);
- }
- }
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement