コード例 #1
0
        public static double[] GetRoots(double[] сoefficients, double precision = 0.00000000000001, double InitialStep = 1, double MinStep = 0.25, SolverOptions options = SolverOptions.StopIfNumberOfRootsCeasedIncrease)
        {
            RootsLimits Limits = GetRootsLimits(сoefficients);

            //отделение корнеЙ
            double h = InitialStep;

            Interval[] IntervalsWithNormalStep;
            Interval[] IntervalsWithHalfOfStep;

            //лямбда полинома с коефициентами
            var lambda = FormLambdaForPolinom(сoefficients.ToArray());

            do
            {
                IntervalsWithNormalStep = GetIntervalsWithRoots(lambda, h, Limits.NLower, Limits.NUpper, Limits.PLower, Limits.PUpper);
                IntervalsWithHalfOfStep = GetIntervalsWithRoots(lambda, h / 2, Limits.NLower, Limits.NUpper, Limits.PLower, Limits.PUpper);
                h /= 2;
            }while (IntervalsWithNormalStep.Length != IntervalsWithHalfOfStep.Length);

            //уточнение корней
            double[] roots = ClarifyRoots(lambda, IntervalsWithHalfOfStep, precision);

            return(roots);
        }
コード例 #2
0
        public static double[] GetRoots(double[] сoefficients, int numberOfroots, int startIntervalsCount = 64, double precision = 0.00000001)
        {
            RootsLimits     Limits    = GetRootsLimits(сoefficients);
            List <Interval> intervals = new List <Interval>();

            //лямбда полинома с коефициентами
            var lambda1 = FormLambdaForPolinom(сoefficients.ToArray());
            var lambda2 = FormLambdaForPolinom(сoefficients.ToArray());

            Func <double, double, Func <double, double>, List <Interval> > getIntervals = (a, b, polinom) =>
            {
                double h = (b - a) / startIntervalsCount;

                double lBrd = 0;
                double rBrd = 0;

                List <Interval> result = new List <Interval>();

                //для отрицательной части
                for (double i = a; i < b; i = rBrd)
                {
                    lBrd = i;
                    rBrd = i + h;
                    if (polinom(lBrd) * polinom(rBrd) < 0)
                    {
                        result.Add(new Interval(lBrd, rBrd));
                    }
                }

                return(result);
            };

            do
            {
                intervals.Clear();

                Task <List <Interval> > t1 = Task <List <Interval> > .Run(() => getIntervals(Limits.NLower, Limits.NUpper, lambda1));

                Task <List <Interval> > t2 = Task <List <Interval> > .Run(() => getIntervals(Limits.PLower, Limits.PUpper, lambda2));

                Task.WaitAll((new[] { t1, t2 }));

                intervals.AddRange(t1.Result);
                intervals.AddRange(t2.Result);

                startIntervalsCount *= 2;
            }while (numberOfroots != intervals.Count);


            //уточнение корней
            double[] roots = ClarifyRoots(lambda1, intervals.ToArray(), precision);

            return(roots);
        }
コード例 #3
0
        private static RootsLimits GetRootsLimits(double[] сoefficients)
        {
            var Limits = new RootsLimits();

            //то же что и умножить на икс в высшей степени и подставить 1/x
            var ReverceCoefs = сoefficients.Reverse().ToArray();;  //Для фи1 и фи3

            //поиск границ корней
            Limits.PUpper = UpperLimitSearcher.GetUpperLimit(сoefficients);
            Limits.PLower = 1d / UpperLimitSearcher.GetUpperLimit(ReverceCoefs);
            Limits.NLower = -UpperLimitSearcher.GetUpperLimit(SubstituteNegativeArgument(сoefficients)); //минус там не зря)
            Limits.NUpper = -1d / UpperLimitSearcher.GetUpperLimit(SubstituteNegativeArgument(ReverceCoefs));
            return(Limits);
        }