private double brentMethod() { double guessVal = (Mathd.Sqrt(obj.parent.gravParam) * currentTime) / semiMajorAxis; //second two params are the min and max values the solver will search for, they are at this point total spitballing Accord.Math.Optimization.BrentSearch searcher = new Accord.Math.Optimization.BrentSearch(substitutionFunction, -2.0d * (guessVal + 20.0d), 2.0d * (guessVal + 20.0d)); searcher.Tolerance = 0.0001; searcher.FindRoot(); return(searcher.Solution); }
public void ConstructorTest() { // Suppose we were given the function x³ + 2x² - 10x and // we have to find its root, maximum and minimum inside // the interval [-4,3]. First, we express this function // as a lambda expression: Func<double, double> function = x => x * x * x + 2 * x * x - 10 * x; // And now we can create the search algorithm: BrentSearch search = new BrentSearch(function, -4, 3); // Finally, we can query the information we need double max = search.Maximize(); // occurs at -2.61 double min = search.Minimize(); // occurs at 1.27 double root = search.FindRoot(); // occurs at 0.50 Assert.AreEqual(-2.6103173042172645, max); Assert.AreEqual(1.2769840667540548, min); Assert.AreEqual(-0.5, root); }
public static PointParamWithRayProjection ClosestPointToRay(this ICurve curve, PointDirection3 ray, double tol = 1e-9) { var bound = curve.Domain(); int numOfRadius = 0; double[] radius = null; MathPoint location = null; var radiusResult = curve.FindMinimumRadius(); var domain = new RangeDouble(curve.Domain()); var tessTol = radiusResult.Radius/10; var closestPointOnEdge = Vector3.Zero; for (var i = 0; i < 1; i++) { var tessPoints = Sequences .LinSpace(domain.Min, domain.Max, 100) .Select(curve.PointParamAt).ToList(); var edges = tessPoints.Buffer(2, 1).Where(buf => buf.Count == 2) .ToList(); var closestEdge = edges .Select(edge => new {edge, connection= MakeEdge(edge).ShortestEdgeJoining(ray, tol)}) .MinBy(o=>o.connection.LengthSquared)[0]; var a = closestEdge.edge[0].T; var b = closestEdge.edge[1].T; domain = new RangeDouble(a, b); tessTol = tessTol/10; } Func<Vector3, Vector3> projectOnRay = p => (p - ray.Point).ProjectOn(ray.Direction) + ray.Point; var solver = new BrentSearch(t => { var p = curve.PointAt(t); var proj = projectOnRay(p); return (p - proj).LengthSquared(); }, domain.Min, domain.Max); solver.Minimize(); var minT = solver.Solution; var pointParam = curve.PointParamAt(minT); return new PointParamWithRayProjection(pointParam, projectOnRay(pointParam.Point)); }
/// <summary> /// Should solve /// </summary> /// <param name="c"></param> /// <param name="t0"></param> /// <param name="distance"></param> /// <returns></returns> public static double PointAtDistanceFrom(this ICurve c, double t0, double distance) { Func<double, double> objFunc = t1 => { var length3 = t0 < t1 ? c.GetLength3(t0, t1) : c.GetLength3(t1, t0); return length3 - Math.Abs(distance); }; var domain = c.Domain(); var min = distance < 0.0 ? 0.8*domain[0] : t0; var max = distance < 0.0 ? t0 : 1.2*domain[1]; var solver = new BrentSearch(objFunc, min, max); solver.FindRoot(); var sol = solver.Solution; return sol; }
public static EdgeDistance ClosestDistanceBetweenTwoCurves(IMathUtility m,ICurve curve0, ICurve curve1) { var curveDomain = curve1.Domain(); var solver = new BrentSearch (t => { var pt = curve1.PointAt(t); return (curve0.ClosestPointOn(pt).Point - pt).Length(); } , curveDomain[0] , curveDomain[1] ); solver.Minimize(); var param = solver.Solution; var pt1 = curve1.PointAt(param); var pt0 = curve0.ClosestPointOn(pt1).Point; var edge = new Edge3(pt1, pt0); return new EdgeDistance(edge, solver.Value); }