public static bool TryFindRoot(Func <double, double> function, double lowerBound, double upperBound, out double root, double accuracy = 1e-6, int maxIterations = 100) { try { double lowerBoundValue = function(lowerBound); if (lowerBoundValue == 0.0 && lowerBoundValue == function(upperBound)) { // For our usage, we don't want to consider a constant function at zero to have any roots. root = lowerBound; return(false); } if (Brent.TryFindRoot(function, lowerBound, upperBound, accuracy: accuracy, maxIterations: maxIterations, root: out root)) { return(true); } return(Bisection.TryFindRoot(function, lowerBound, upperBound, accuracy: accuracy, maxIterations: maxIterations, root: out root)); } catch (ArithmeticException) { root = double.NaN; return(false); } }
private VoltageLimitCurve buildVoltageLimitCurve(int count = 50, double Imax = 55, double Umax = 140, double max_speed = 6000) { var mtpa = buildTableMaxtorquePerAmple(); VoltageLimitCurve vlc = new VoltageLimitCurve() { Imax = Imax, Umax = Umax, MaxSpeed = max_speed, }; for (int i = 0; i < count + 1; i++) { double t = mtpa.GetMaxTorqueWithCurrentMagnitude(i * Imax / count); var idq = mtpa.GetCurrentForTorque(t); // look for speed, that is suitable for given current (in max torque condition) and u=Umax double ss = 0; bool success = Brent.TryFindRoot(s => { var data_ = calculatePointdata(idq.d, idq.q, s); var u_ = Math.Sqrt(data_.ud * data_.ud + data_.uq * data_.uq); return(u_ - Umax); }, 100, max_speed, 1e-3, 100, out ss); if (success) { vlc.speeds.Add(ss); vlc.torques.Add(t); vlc.currents.Add(idq); } } return(vlc); }
/// <summary>Find a solution of the equation f(x)=0.</summary> /// <param name="f">The function to find roots from.</param> /// <param name="lowerBound">The low value of the range where the root is supposed to be.</param> /// <param name="upperBound">The high value of the range where the root is supposed to be.</param> /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14.</param> /// <param name="maxIterations">Maximum number of iterations. Example: 100.</param> public static double OfFunction(Func <double, double> f, double lowerBound, double upperBound, double accuracy = 1e-8, int maxIterations = 100) { double root; if (Brent.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root)) { return(root); } if (Bisection.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root)) { return(root); } throw new NonConvergenceException(Resources.RootFindingFailed); }
/// <summary>Find a solution of the equation f(x)=0.</summary> /// <param name="f">The function to find roots from.</param> /// <param name="lowerBound">The low value of the range where the root is supposed to be.</param> /// <param name="upperBound">The high value of the range where the root is supposed to be.</param> /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14.</param> /// <param name="maxIterations">Maximum number of iterations. Example: 100.</param> public static double OfFunction(Func <double, double> f, double lowerBound, double upperBound, double accuracy = 1e-8, int maxIterations = 100) { if (!ZeroCrossingBracketing.ExpandReduce(f, ref lowerBound, ref upperBound, 1.6, maxIterations, maxIterations * 10)) { throw new NonConvergenceException("The algorithm has failed, exceeded the number of iterations allowed or there is no root within the provided bounds."); } if (Brent.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out var root)) { return(root); } if (Bisection.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root)) { return(root); } throw new NonConvergenceException("The algorithm has failed, exceeded the number of iterations allowed or there is no root within the provided bounds."); }
public InterestRate FindCompoundInterestRate( Money principal, Money totalRepayment, int numberOfMonthlyPayments, InterestRate lowerBoundInterestRate, InterestRate upperBoundInterestRate) { double CompoundInterestFunction(double x) => Convert.ToDouble(principal.Amount) * x / (1 - 1 / Math.Pow(1d + x, numberOfMonthlyPayments)) - Convert.ToDouble(totalRepayment.Amount) / Convert.ToDouble(numberOfMonthlyPayments); var findRootSuccess = Brent.TryFindRoot(CompoundInterestFunction, lowerBoundInterestRate.Monthly, upperBoundInterestRate.Monthly, findRootAccuracy, maxFindRootIterations, out var monthlyInterestRate); if (findRootSuccess) { return(new InterestRate(monthlyInterestRate * 12d)); } throw new CompoundInterestRateConvergenceException("No root for compond interest rate can be found by the algorithm."); }
/// <summary>Find a solution of the equation f(x)=0.</summary> /// <param name="f">The function to find roots from.</param> /// <param name="lowerBound">The low value of the range where the root is supposed to be.</param> /// <param name="upperBound">The high value of the range where the root is supposed to be.</param> /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14.</param> /// <param name="maxIterations">Maximum number of iterations. Example: 100.</param> public static double OfFunction(Func <double, double> f, double lowerBound, double upperBound, double accuracy = 1e-8, int maxIterations = 100) { double root; if (!ZeroCrossingBracketing.ExpandReduce(f, ref lowerBound, ref upperBound, 1.6, maxIterations, maxIterations * 10)) { throw new NonConvergenceException(Resources.RootFindingFailed); } if (Brent.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root)) { return(root); } if (Bisection.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root)) { return(root); } throw new NonConvergenceException(Resources.RootFindingFailed); }
private List <Fdq> curveSameTorque(double t, double Imax = 55) { //Fdq Imin = mtpa.GetCurrentForTorque(t); //double iq_maxbeta; //bool b_iq = Brent.TryFindRoot(iq_ => //{ // var d = interpolateData(-Imax, iq_, 3000); // return d.torque - t; //}, 0, Imax, 1e-8, 500, out iq_maxbeta); //if (!b_iq) // return new List<Fdq>();//nothing int count = 50; List <Fdq> idqs = new List <Fdq>(); for (int i = 0; i < count + 1; i++) { double id = -Imax * i / count; double iq = 0; bool bI = Brent.TryFindRoot(iq_ => { var d = calculatePointdata(id, iq_, 3000); return(d.torque - t); }, 0, Imax, 1e-5, 100, out iq); if (bI) { idqs.Add(new Fdq() { d = id, q = iq, }); } } return(idqs); }
private VoltageLimitEllipse buildVoltageLimitEllipse(double speed, int count = 50, double Imax = 55, double Umax = 140) { var vle = new VoltageLimitEllipse { speed = speed, Imax = Imax, Umax = Umax, curve = new List <Fdq>(), torques = new List <double>(), }; double maxt = 0; bool minfound = false; int index = 0; for (int j = 0; j < count + 1; j++) { double id = -Imax * j / count; double iq; double t = 0; bool bb = Brent.TryFindRoot(iq_ => { var d = calculatePointdata(id, iq_, speed); double u = Math.Sqrt(d.ud * d.ud + d.uq * d.uq); t = d.torque; return(u - Umax); }, 0, Imax, 1e-5, 100, out iq); if (bb) { var idq = new Fdq { d = id, q = iq }; if (maxt < t) { maxt = t; vle.maxtorque_point = index; } if (!minfound) { vle.minid_point = index; minfound = true; } vle.curve.Add(idq); vle.torques.Add(t); index++; } } if (vle.curve[0].d < 0) { Fdq idq1 = vle.curve[0]; Fdq idq2 = vle.curve[1]; Fdq idq0 = new Fdq { d = idq1.d + (Imax / count) * (idq1.q / idq2.q) / (1 - idq1.q / idq2.q), q = 0, }; vle.curve.Insert(0, idq0); vle.torques.Insert(0, 0); vle.maxtorque_point++; } return(vle); }