int main(int argc, char ** argv) { MPI_Init(&argc, &argv); QUESO::FullEnvironment env(MPI_COMM_WORLD, "", "", NULL); QUESO::VectorSpace<QUESO::GslVector, QUESO::GslMatrix> paramSpace(env, "space_", 3, NULL); QUESO::GslVector minBound(paramSpace.zeroVector()); minBound[0] = -10.0; minBound[1] = -10.0; minBound[2] = -10.0; QUESO::GslVector maxBound(paramSpace.zeroVector()); maxBound[0] = 10.0; maxBound[1] = 10.0; maxBound[2] = 10.0; QUESO::BoxSubset<QUESO::GslVector, QUESO::GslMatrix> domain("", paramSpace, minBound, maxBound); ObjectiveFunction<QUESO::GslVector, QUESO::GslMatrix> objectiveFunction( "", domain); QUESO::GslVector initialPoint(paramSpace.zeroVector()); initialPoint[0] = 9.0; initialPoint[1] = -9.0; initialPoint[1] = -1.0; QUESO::GslOptimizer optimizer(objectiveFunction); double tol = 1.0e-10; optimizer.setTolerance(tol); optimizer.set_solver_type(QUESO::GslOptimizer::STEEPEST_DESCENT); QUESO::OptimizerMonitor monitor(env); monitor.set_display_output(true,true); std::cout << "Solving with Steepest Decent" << std::endl; optimizer.minimize(&monitor); if (std::abs( optimizer.minimizer()[0] - 1.0) > tol) { std::cerr << "GslOptimize failed. Found minimizer at: " << optimizer.minimizer()[0] << std::endl; std::cerr << "Actual minimizer is 1.0" << std::endl; queso_error(); } std::string nm = "nelder_mead2"; optimizer.set_solver_type(nm); monitor.reset(); monitor.set_display_output(true,true); std::cout << std::endl << "Solving with Nelder Mead" << std::endl; optimizer.minimize(&monitor); monitor.print(std::cout,false); return 0; }
void Curve::feed(PathSink &sink, bool moveto_initial) const { std::vector<Point> pts; sbasis_to_bezier(pts, toSBasis(), 2); //TODO: use something better! if (moveto_initial) { sink.moveTo(initialPoint()); } sink.curveTo(pts[0], pts[1], pts[2]); }
int main() { SimpleFunction func(10); Optimization::LBFGS lbfgs; vector<double> initialPoint(10, 1); vector<double> minPoint; Optimization::ICallable eventHandler; lbfgs.Optimize(func, &eventHandler, initialPoint, &minPoint, 1000); }
Curve *EllipticalArc::transformed(Affine const& m) const { Ellipse e(center(X), center(Y), ray(X), ray(Y), _rot_angle); Ellipse et = e.transformed(m); Point inner_point = pointAt(0.5); return et.arc( initialPoint() * m, inner_point * m, finalPoint() * m, isSVGCompliant() ); }
Path &Path::operator*=(Affine const &m) { unshare(); Sequence::iterator last = get_curves().end() - 1; Sequence::iterator it; Point prev; for (it = get_curves().begin() ; it != last ; ++it) { *it = boost::shared_ptr<Curve>((*it)->transformed(m)); if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) { THROW_CONTINUITYERROR(); } prev = (*it)->finalPoint(); } for ( int i = 0 ; i < 2 ; ++i ) { final_->setPoint(i, (*final_)[i] * m); } if (get_curves().size() > 1) { if ( front().initialPoint() != initialPoint() || back().finalPoint() != finalPoint() ) { THROW_CONTINUITYERROR(); } } return *this; }
D2<SBasis> EllipticalArc::toSBasis() const { D2<SBasis> arc; // the interval of parametrization has to be [0,1] Coord et = initialAngle().radians() + ( _sweep ? sweepAngle() : -sweepAngle() ); Linear param(initialAngle(), et); Coord cos_rot_angle, sin_rot_angle; sincos(_rot_angle, sin_rot_angle, cos_rot_angle); // order = 4 seems to be enough to get a perfect looking elliptical arc SBasis arc_x = ray(X) * cos(param,4); SBasis arc_y = ray(Y) * sin(param,4); arc[0] = arc_x * cos_rot_angle - arc_y * sin_rot_angle + Linear(center(X),center(X)); arc[1] = arc_x * sin_rot_angle + arc_y * cos_rot_angle + Linear(center(Y),center(Y)); // ensure that endpoints remain exact for ( int d = 0 ; d < 2 ; d++ ) { arc[d][0][0] = initialPoint()[d]; arc[d][0][1] = finalPoint()[d]; } return arc; }
/* * NOTE: this implementation follows Standard SVG 1.1 implementation guidelines * for elliptical arc curves. See Appendix F.6. */ void EllipticalArc::_updateCenterAndAngles(bool svg) { Point d = initialPoint() - finalPoint(); // TODO move this to SVGElipticalArc? if (svg) { if ( initialPoint() == finalPoint() ) { _rot_angle = _start_angle = _end_angle = 0; _center = initialPoint(); _rays = Geom::Point(0,0); _large_arc = _sweep = false; return; } _rays[X] = std::fabs(_rays[X]); _rays[Y] = std::fabs(_rays[Y]); if ( are_near(ray(X), 0) || are_near(ray(Y), 0) ) { _rays[X] = L2(d) / 2; _rays[Y] = 0; _rot_angle = std::atan2(d[Y], d[X]); _start_angle = 0; _end_angle = M_PI; _center = middle_point(initialPoint(), finalPoint()); _large_arc = false; _sweep = false; return; } } else { if ( are_near(initialPoint(), finalPoint()) ) { if ( are_near(ray(X), 0) && are_near(ray(Y), 0) ) { _start_angle = _end_angle = 0; _center = initialPoint(); return; } else { THROW_RANGEERROR("initial and final point are the same"); } } if ( are_near(ray(X), 0) && are_near(ray(Y), 0) ) { // but initialPoint != finalPoint THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints: " "ray(X) == 0 && ray(Y) == 0 but initialPoint != finalPoint" ); } if ( are_near(ray(Y), 0) ) { Point v = initialPoint() - finalPoint(); if ( are_near(L2sq(v), 4*ray(X)*ray(X)) ) { Angle angle(v); if ( are_near( angle, _rot_angle ) ) { _start_angle = 0; _end_angle = M_PI; _center = v/2 + finalPoint(); return; } angle -= M_PI; if ( are_near( angle, _rot_angle ) ) { _start_angle = M_PI; _end_angle = 0; _center = v/2 + finalPoint(); return; } THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints: " "ray(Y) == 0 " "and slope(initialPoint - finalPoint) != rotation_angle " "and != rotation_angle + PI" ); } if ( L2sq(v) > 4*ray(X)*ray(X) ) { THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints: " "ray(Y) == 0 and distance(initialPoint, finalPoint) > 2*ray(X)" ); } else { THROW_RANGEERROR( "there is infinite ellipses that satisfy the given constraints: " "ray(Y) == 0 and distance(initialPoint, finalPoint) < 2*ray(X)" ); } } if ( are_near(ray(X), 0) ) { Point v = initialPoint() - finalPoint(); if ( are_near(L2sq(v), 4*ray(Y)*ray(Y)) ) { double angle = std::atan2(v[Y], v[X]); if (angle < 0) angle += 2*M_PI; double rot_angle = _rot_angle.radians() + M_PI/2; if ( !(rot_angle < 2*M_PI) ) rot_angle -= 2*M_PI; if ( are_near( angle, rot_angle ) ) { _start_angle = M_PI/2; _end_angle = 3*M_PI/2; _center = v/2 + finalPoint(); return; } angle -= M_PI; if ( angle < 0 ) angle += 2*M_PI; if ( are_near( angle, rot_angle ) ) { _start_angle = 3*M_PI/2; _end_angle = M_PI/2; _center = v/2 + finalPoint(); return; } THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints: " "ray(X) == 0 " "and slope(initialPoint - finalPoint) != rotation_angle + PI/2 " "and != rotation_angle + (3/2)*PI" ); } if ( L2sq(v) > 4*ray(Y)*ray(Y) ) { THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints: " "ray(X) == 0 and distance(initialPoint, finalPoint) > 2*ray(Y)" ); } else { THROW_RANGEERROR( "there is infinite ellipses that satisfy the given constraints: " "ray(X) == 0 and distance(initialPoint, finalPoint) < 2*ray(Y)" ); } } } Rotate rm(_rot_angle); Affine m(rm); m[1] = -m[1]; m[2] = -m[2]; Point p = (d / 2) * m; double rx2 = _rays[X] * _rays[X]; double ry2 = _rays[Y] * _rays[Y]; double rxpy = _rays[X] * p[Y]; double rypx = _rays[Y] * p[X]; double rx2py2 = rxpy * rxpy; double ry2px2 = rypx * rypx; double num = rx2 * ry2; double den = rx2py2 + ry2px2; assert(den != 0); double rad = num / den; Point c(0,0); if (rad > 1) { rad -= 1; rad = std::sqrt(rad); if (_large_arc == _sweep) rad = -rad; c = rad * Point(rxpy / ray(Y), -rypx / ray(X)); _center = c * rm + middle_point(initialPoint(), finalPoint()); } else if (rad == 1 || svg) { double lamda = std::sqrt(1 / rad); _rays[X] *= lamda; _rays[Y] *= lamda; _center = middle_point(initialPoint(), finalPoint()); } else { THROW_RANGEERROR( "there is no ellipse that satisfies the given constraints" ); } Point sp((p[X] - c[X]) / ray(X), (p[Y] - c[Y]) / ray(Y)); Point ep((-p[X] - c[X]) / ray(X), (-p[Y] - c[Y]) / ray(Y)); Point v(1, 0); _start_angle = angle_between(v, sp); double sweep_angle = angle_between(sp, ep); if (!_sweep && sweep_angle > 0) sweep_angle -= 2*M_PI; if (_sweep && sweep_angle < 0) sweep_angle += 2*M_PI; _end_angle = _start_angle; _end_angle += sweep_angle; }
std::vector<Coord> EllipticalArc::roots(Coord v, Dim2 d) const { std::vector<Coord> sol; if ( are_near(ray(X), 0) && are_near(ray(Y), 0) ) { if ( center(d) == v ) sol.push_back(0); return sol; } static const char* msg[2][2] = { { "d == X; ray(X) == 0; " "s = (v - center(X)) / ( -ray(Y) * std::sin(_rot_angle) ); " "s should be contained in [-1,1]", "d == X; ray(Y) == 0; " "s = (v - center(X)) / ( ray(X) * std::cos(_rot_angle) ); " "s should be contained in [-1,1]" }, { "d == Y; ray(X) == 0; " "s = (v - center(X)) / ( ray(Y) * std::cos(_rot_angle) ); " "s should be contained in [-1,1]", "d == Y; ray(Y) == 0; " "s = (v - center(X)) / ( ray(X) * std::sin(_rot_angle) ); " "s should be contained in [-1,1]" }, }; for ( unsigned int dim = 0; dim < 2; ++dim ) { if ( are_near(ray((Dim2) dim), 0) ) { if ( initialPoint()[d] == v && finalPoint()[d] == v ) { THROW_INFINITESOLUTIONS(0); } if ( (initialPoint()[d] < finalPoint()[d]) && (initialPoint()[d] > v || finalPoint()[d] < v) ) { return sol; } if ( (initialPoint()[d] > finalPoint()[d]) && (finalPoint()[d] > v || initialPoint()[d] < v) ) { return sol; } double ray_prj = 0.0; switch(d) { case X: switch(dim) { case X: ray_prj = -ray(Y) * std::sin(_rot_angle); break; case Y: ray_prj = ray(X) * std::cos(_rot_angle); break; } break; case Y: switch(dim) { case X: ray_prj = ray(Y) * std::cos(_rot_angle); break; case Y: ray_prj = ray(X) * std::sin(_rot_angle); break; } break; } double s = (v - center(d)) / ray_prj; if ( s < -1 || s > 1 ) { THROW_LOGICALERROR(msg[d][dim]); } switch(dim) { case X: s = std::asin(s); // return a value in [-PI/2,PI/2] if ( logical_xor( _sweep, are_near(initialAngle(), M_PI/2) ) ) { if ( s < 0 ) s += 2*M_PI; } else { s = M_PI - s; if (!(s < 2*M_PI) ) s -= 2*M_PI; } break; case Y: s = std::acos(s); // return a value in [0,PI] if ( logical_xor( _sweep, are_near(initialAngle(), 0) ) ) { s = 2*M_PI - s; if ( !(s < 2*M_PI) ) s -= 2*M_PI; } break; } //std::cerr << "s = " << rad_to_deg(s); s = map_to_01(s); //std::cerr << " -> t: " << s << std::endl; if ( !(s < 0 || s > 1) ) sol.push_back(s); return sol; } } double rotx, roty; sincos(_rot_angle, roty, rotx); if (d == X) roty = -roty; double rxrotx = ray(X) * rotx; double c_v = center(d) - v; double a = -rxrotx + c_v; double b = ray(Y) * roty; double c = rxrotx + c_v; //std::cerr << "a = " << a << std::endl; //std::cerr << "b = " << b << std::endl; //std::cerr << "c = " << c << std::endl; if ( are_near(a,0) ) { sol.push_back(M_PI); if ( !are_near(b,0) ) { double s = 2 * std::atan(-c/(2*b)); if ( s < 0 ) s += 2*M_PI; sol.push_back(s); } } else { double delta = b * b - a * c; //std::cerr << "delta = " << delta << std::endl; if ( are_near(delta, 0) ) { double s = 2 * std::atan(-b/a); if ( s < 0 ) s += 2*M_PI; sol.push_back(s); } else if ( delta > 0 ) { double sq = std::sqrt(delta); double s = 2 * std::atan( (-b - sq) / a ); if ( s < 0 ) s += 2*M_PI; sol.push_back(s); s = 2 * std::atan( (-b + sq) / a ); if ( s < 0 ) s += 2*M_PI; sol.push_back(s); } } std::vector<double> arc_sol; for (unsigned int i = 0; i < sol.size(); ++i ) { //std::cerr << "s = " << rad_to_deg(sol[i]); sol[i] = map_to_01(sol[i]); //std::cerr << " -> t: " << sol[i] << std::endl; if ( !(sol[i] < 0 || sol[i] > 1) ) arc_sol.push_back(sol[i]); } return arc_sol; }