public static double integrate(func f, System.Collections.Generic.IReadOnlyList <double> init_ticks, double eps1)
        {
            var points = new System.Collections.Generic.Stack <Point>();
            var areas  = new System.Collections.Generic.List <double>();

            foreach (var x in init_ticks)
            {
                points.Push(new Point(x, f(x)));
            }

            var    full_width = init_ticks.Last() - init_ticks.First();
            Point  right;
            double eps = eps1 * 4.0 / full_width;

            while (points.Count > 1)
            {
                //Console.WriteLine(points.Count);
                right = points.Pop();
                var left = points.Peek();
                var mid  = Integration.midpoint(ref left, ref right, f);
                if (Math.Abs(left.f + right.f - mid.f * 2.0) <= eps)
                {
                    areas.Add((left.f + right.f + mid.f * 2.0) * (right.x - left.x) / 4.0);
                }
                else
                {
                    points.Push(mid);
                    points.Push(right);
                }
            }
            areas.Sort(delegate(double x, double y){
                return(Math.Abs(x).CompareTo(Math.Abs(y)));
            });
            return(areas.Sum());
        }
Пример #2
0
        public static double integrate(func f, System.Collections.Generic.IReadOnlyList <double> init_ticks, double eps1)
        {
            var points = new System.Collections.Generic.Stack <Point>();
            //var areas=new System.Collections.Generic.List<double>();
            double total_area = 0;
            double comp       = 0;

            foreach (var x in init_ticks)
            {
                points.Push(new Point(x, f(x)));
            }

            var    full_width = init_ticks.Last() - init_ticks.First();
            Point  right      = points.Pop();
            double eps        = eps1 * 4.0 / full_width;

            while (points.Count > 0)
            {
                //Console.WriteLine(points.Count);
                var left = points.Peek();
                var mid  = Integration.midpoint(ref left, ref right, f);
                if (Math.Abs(left.f + right.f - mid.f * 2.0) <= eps)
                {
                    //areas.Add((left.f+right.f+mid.f*2.0)*(right.x-left.x)/4.0);
                    double area = (left.f + right.f + mid.f * 2.0) * (right.x - left.x) / 4.0;
                    (total_area, comp) = neumaier_sum(total_area, area, comp);

                    right = points.Pop();
                }
                else
                {
                    points.Push(mid);
                }
            }
            return(total_area + comp);
        }