double powellMethod::goldenSectionSearch(double a, double b, double c, double tau, std::vector<Expression> x_next,double preValue) { double x; double valueX, valueB; b = (a + c) / 2; if (b < c) x = b + resphi * (c - b); else x = b - resphi * (b - a); //std::cout << "a = " << a << std::endl; //std::cout << "c = " << c << std::endl; //std::cout << "x = " << x << std::endl; //std::cout << " " << std::endl; if ((std::abs(c - a) < tau * (std::abs(b) + std::abs(x))) || std::abs(preValue - x) <= tau ) { return (c + a) / 2; } if (x_next.size() == 1) { valueX = myExpression.getValue(x_next[0].getValue(x), 0); valueB = myExpression.getValue(x_next[0].getValue(b), 0); } else if (x_next.size() == 2) { valueX = myExpression.getValue(x_next[0].getValue(x), x_next[1].getValue(x)); valueB = myExpression.getValue(x_next[0].getValue(b), x_next[1].getValue(b)); } //std::cout << "f(x) = " << valueX << std::endl; //std::cout << "f(b) = " << valueB << std::endl; //std::cout << "---" << std::endl; if (valueX < valueB) { return (b < c) ? goldenSectionSearch(b, x, c, tau, x_next, x) : goldenSectionSearch(a, x, b, tau, x_next, x); } else { return (b < c) ? goldenSectionSearch(a, b, x, tau, x_next, x) : goldenSectionSearch(x, b, c, tau, x_next, x); } //if (x_next.size() == 1) { // if (myExpression.getValue(x_next[0].getValue(x), 0) < myExpression.getValue(x_next[0].getValue(b), 0)) // return (b < c) ? goldenSectionSearch(b, x, c, tau, x_next, x) : goldenSectionSearch(a, x, b, tau, x_next,x); // else // return (b < c) ? goldenSectionSearch(a, b, x, tau, x_next, x) : goldenSectionSearch(x, b, c, tau, x_next, x); //} //else if (x_next.size() == 2) { // if (myExpression.getValue(x_next[0].getValue(x), x_next[1].getValue(x)) < myExpression.getValue(x_next[0].getValue(b), x_next[1].getValue(b))) // return (b < c) ? goldenSectionSearch(b, x, c, tau, x_next, x) : goldenSectionSearch(a, x, b, tau, x_next, x); // else // return (b < c) ? goldenSectionSearch(a, b, x, tau, x_next, x) : goldenSectionSearch(x, b, c, tau, x_next, x); //} }
double goldenSectionSearch(const GEdge *ge, const SPoint3 &q, double x1, double x2, double x3, double tau) { // Create a new possible center in the area between x2 and x3, closer to x2 double x4 = x2 + GOLDEN2 * (x3 - x2); // Evaluate termination criterion if (fabs(x3 - x1) < tau * (fabs(x2) + fabs(x4))) return (x3 + x1) / 2; const SVector3 dp4 = q - ge->position(x4); const SVector3 dp2 = q - ge->position(x2); const double d4 = dp4.norm(); const double d2 = dp2.norm(); if (d4 < d2) return goldenSectionSearch(ge, q, x2, x4, x3, tau); else return goldenSectionSearch(ge,q , x4, x2, x1, tau); }
GPoint GEdge::closestPoint(const SPoint3 &q, double &t) const { // printf("looking for closest point in curve %d to point %g %g\n",tag(),q.x(),q.y()); const int nbSamples = 100; Range<double> interval = parBounds(0); double tMin = std::min(interval.high(), interval.low()); double tMax = std::max(interval.high(), interval.low()); double DMIN = 1.e22; double topt = tMin; const double DT = (tMax - tMin) / (nbSamples - 1.) ; for (int i = 0; i < nbSamples; i++){ t = tMin + i * DT; const SVector3 dp = q - position(t); const double D = dp.norm(); if (D < DMIN) { topt = t; DMIN = D; } } // printf("parameter %g as an initial guess (dist = %g)\n",topt,DMIN); if (topt == tMin) t = goldenSectionSearch (this, q, topt, topt + DT/2, topt + DT, 1.e-9); else if (topt == tMax) t = goldenSectionSearch (this, q, topt - DT, topt - DT/2 , topt, 1.e-9); else t = goldenSectionSearch (this, q, topt - DT, topt, topt + DT, 1.e-9); const SVector3 dp = q - position(t); // const double D = dp.norm(); // printf("after golden section parameter %g (dist = %g)\n",t,D); return point(t); }