Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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.");
        }
Exemple #5
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
        }