/// <summary> /// A combination of bisection and tangent (Newton) method. Bisection is used to determine all /// possible zeros and then additional steps are made to convengance to those solutions using Newton's /// method. /// </summary> /// <param name="f">The actual function.</param> /// <param name="df">The derivate of function.</param> /// <param name="interval">The interval of method.</param> /// <param name="maxBError">Maximum bisection error.</param> /// <param name="maxPError">Maximum polishing error.</param> /// <returns></returns> public static List <double> MultiBisectionAndPolish([NotNull] Functiond f, [NotNull] Functiond df, Intervald interval, double maxBError, double maxPError) { // We do progressivelly for all values. List <double> roots = new List <double>(); // We first create iteration values. double a = interval.A, fa = f(interval.A); double b = interval.A + maxBError; // We iterate through all values. for (double fb; b <= interval.B; b += maxBError) { // Calculate fb first. fb = f(b); // We check it there is a root between a and b. if (fa * fb < 0.0) { // We have a root or singularity. We do not check for // singularity, we add it to the list. roots.Add(TangentRoot(f, df, 0.5 * (a + b), maxPError)); } // We iterate to next. a = b; fa = fb; } return(roots); }
/// <summary> /// A normal bisection method. The finding needs quite a few interations because /// the convengence is guaranteed but slow. /// </summary> /// <param name="f">The function.</param> /// <param name="resolution">Number of interations.</param> /// <param name="maxError">The maximum error.</param> /// <returns>Whe x where the approcimate root exists.</returns> public static double Bisection([NotNull] Functiond f, Intervald interval, double maxError) { // Actual error is multiplied by 2.0, because we use A+b average. maxError *= 2.0; double A = interval.A, B = interval.B; double fA = f(A); double fB = f(B); if (fA * fB > 0.0) { throw new ArgumentException("The bisection can only be performed on interval, where one side " + "is more then 0.0 and one is less the 0.0."); } double C = 0.0, fC = 0.0; // We interate. for (; ;) { C = (A + B) * 0.5; fC = f(C); // We check what kind we have. if (fC > 0.0) { if (fA > 0.0) { fA = fC; A = C; } else { fB = fC; B = C; } } else { if (fA > 0.0) { fB = fC; B = C; } else { fA = fC; A = C; } } // Check if condition is met. if (B - A < maxError) { break; } } // Return best approximation. return((A + B) * 0.5); }
/// <summary> /// Finds all real roots of polynomial. /// </summary> /// <param name="coeficents">The coefficients of polynomial.</param> /// <param name="error">The error tollerance, actual roots are further polished to give /// much better approximation (around 1/100 of unpolished).</param> /// <returns>List of zeros.</returns> public static List <double> RealRoots([NotNull] double[] coeficents, Intervald range, double error) { // For now, replace by Laguerre when implemented. return(RootFinder.MultiBisectionAndPolish( Polynomial.CreateFunctiond(coeficents), Polynomial.CreateFunctiond(Polynomial.Differentiate(coeficents)), range, error, error * 0.01)); }
/// <summary> /// /// </summary> public static void Remap(this ISampledField <double> field, Intervald from, Intervald to, ISampledField <double> result, bool parallel = false) { if (parallel) { Vector.Parallel.Remap(field.Values, from, to, result.Values); } else { Vector.Remap(field.Values, from, to, result.Values); } }
/// <summary> /// /// </summary> public static void Remap(this IDiscreteField <double> field, Intervald from, Intervald to, IDiscreteField <double> result, bool parallel = false) { if (parallel) { ArrayMath.Parallel.Remap(field.Values, from, to, result.Values); } else { ArrayMath.Remap(field.Values, from, to, result.Values); } }
/// <summary> /// /// </summary> public static void Evaluate(this IDiscreteField <double> field, Intervald interval, IDiscreteField <double> result, bool parallel = false) { if (parallel) { ArrayMath.Parallel.Evaluate(field.Values, interval, result.Values); } else { ArrayMath.Evaluate(field.Values, interval, result.Values); } }
/// <summary> /// /// </summary> public static void Evaluate(this ISampledField <double> field, Intervald interval, ISampledField <double> result, bool parallel = false) { if (parallel) { Vector.Parallel.Evaluate(field.Values, interval, result.Values); } else { Vector.Evaluate(field.Values, interval, result.Values); } }
/// <summary> /// /// </summary> /// <returns></returns> Mesh SolveInstanceImpl(HeMesh3d mesh, IReadOnlyList <Color> colors, Intervald interval, out Intervald range) { var verts = mesh.Vertices; var faces = mesh.Faces; var planarDev = new double[faces.Count]; mesh.GetFacePlanarity(v => v.Position, (f, t) => planarDev[f] = t); // get planarity range range = new Intervald(planarDev); if (!interval.IsValid) { interval = range; } // create new mesh return(mesh.ToPolySoup(f => colors.Lerp(interval.Normalize(planarDev[f])))); }
/// <summary> /// Finds roots using Brent's method. /// </summary> /// <param name="f">The function.</param> /// <param name="interval">Interval where to search.</param> /// <param name="eps">The maximum allowed error.</param> /// <returns>The root.</returns> public static double BrentRoot([NotNull] Functiond f, Intervald interval, double eps) { throw new NotImplementedException(); }
/// <summary> /// Real roots of polynomial. /// </summary> /// <param name="interval">The interval.</param> /// <param name="precission">Precission.</param> /// <returns>The list of real zeros.</returns> public List <double> RealRoots(Intervald interval) { return(Polynomial.RealRoots(coefficients, interval)); }
/// <summary> /// Finds all real roots of polynomial. /// </summary> /// <param name="coeficents">The coefficients od polynomial.</param> /// <returns></returns> public static List <double> RealRoots([NotNull] double[] coeficents, Intervald range) { return(RealRoots(coeficents, range, defaultError)); }
/// <summary> /// Creates a derivate function using samples. /// </summary> /// <param name="f">The function.</param> /// <param name="interval">Interval where to compute derivate.</param> /// <param name="samples">Number of samples.</param> /// <param name="h">The delta for computation.</param> /// <returns>Function, a polynomial.</returns> public static Functions.Polynomial DerivatePolynomial([NotNull] Functiond f, Intervald interval, uint samples, double h) { return(null); }
/// <summary> /// Quadratic integrator. /// </summary> /// <param name="func"></param> /// <param name="range"></param> public QuadraticIntegratord(Functiond func, Intervald range) { this.func = func; this.range = range; }
/// <summary> /// /// </summary> /// <param name="mesh"></param> /// <param name="vertexValues"></param> /// <param name="interval"></param> /// <returns></returns> public static T CreateIsoTrim(T mesh, IReadOnlyList <double> vertexValues, Intervald interval) { // TODO implement throw new NotImplementedException(); }
/// <summary> /// All roots of rational function at interval. /// </summary> /// <param name="range">The interval.</param> /// <param name="error">Precission of calculation.</param> /// <returns>List of zeros.</returns> public List <double> Roots(Intervald range, double error) { return(p.RealRoots(range)); }
/// <summary> /// The poles of polynomial, with default precission calculation. /// </summary> /// <param name="range">The range where poles are to be found.</param> /// <returns>List of poles.</returns> public List <double> Poles(Intervald range) { return(q.RealRoots(range)); }
/// <summary> /// /// </summary> /// <param name="mesh"></param> /// <param name="vertexValues"></param> /// <param name="interval"></param> /// <returns></returns> public static Mesh IsoTrim(this Mesh mesh, IReadOnlyList <double> vertexValues, Intervald interval) { return(RhinoFactory.Mesh.CreateIsoTrim(mesh, vertexValues, interval)); }
/// <summary> /// Creates a derivate function using samples. /// </summary> /// <param name="f">The function.</param> /// <param name="interval">Interval where to compute derivate.</param> /// <param name="samples">Number of samples.</param> /// <param name="h">The delta for computation.</param> /// <returns>Function, a polynomial in compact compiled form.</returns> public static Functiond Derivate([NotNull] Functiond f, Intervald interval, uint samples, double h) { return(null); }