private double CalculateDoubleSimpsonWithThreads(DoubleIntegrationInfo integrationInfo,
                                                         Func <double, double, double> surfaceFunction,
                                                         int n,
                                                         int numberOfThreads)
        {
            var lockObject = new object();
            var stepX      = GetStep(n, integrationInfo.XStart, integrationInfo.XEnd);
            var stepY      = GetStep(n, integrationInfo.YStart, integrationInfo.YEnd);

            var options = new ParallelOptions {
                MaxDegreeOfParallelism = numberOfThreads
            };

            var totalSum = 0.0;

            using (var writer = new StreamWriter("ThreadsInfo/" + numberOfThreads + ".txt"))
            {
                Parallel.For <double>(0, (long)n, options, () => 0, (i, state, subtotal) =>
                {
                    for (var j = 0; j < n; j++)
                    {
                        subtotal +=
                            surfaceFunction(GetByOffset(2 * (int)i, integrationInfo.XStart, stepX),
                                            GetByOffset(2 * j, integrationInfo.YStart, stepY)) +
                            surfaceFunction(GetByOffset(2 * (int)i + 2, integrationInfo.XStart, stepX),
                                            GetByOffset(2 * j, integrationInfo.YStart, stepY)) +
                            surfaceFunction(GetByOffset(2 * (int)i + 2, integrationInfo.XStart, stepX),
                                            GetByOffset(2 * j + 2, integrationInfo.YStart, stepY)) +
                            surfaceFunction(GetByOffset(2 * (int)i, integrationInfo.XStart, stepX),
                                            GetByOffset(2 * j + 2, integrationInfo.YStart, stepY)) +
                            4 *
                            (surfaceFunction(GetByOffset(2 * (int)i + 1, integrationInfo.XStart, stepX),
                                             GetByOffset(2 * j, integrationInfo.YStart, stepY)) +
                             surfaceFunction(GetByOffset(2 * (int)i + 2, integrationInfo.XStart, stepX),
                                             GetByOffset(2 * j + 1, integrationInfo.YStart, stepY)) +
                             surfaceFunction(GetByOffset(2 * (int)i + 1, integrationInfo.XStart, stepX),
                                             GetByOffset(2 * j + 2, integrationInfo.YStart, stepY)) +
                             surfaceFunction(GetByOffset(2 * (int)i, integrationInfo.XStart, stepX),
                                             GetByOffset(2 * j + 1, integrationInfo.YStart, stepY))) +
                            16 *
                            surfaceFunction(GetByOffset(2 * (int)i + 1, integrationInfo.XStart, stepX),
                                            GetByOffset(2 * j + 1, integrationInfo.YStart, stepY));
                    }


                    return(subtotal);
                }, sum =>
                {
                    lock (lockObject)
                    {
                        totalSum += sum;
                        writer.WriteLine(Thread.CurrentThread.ManagedThreadId + " : " + totalSum);
                    }
                });
            }

            return(stepX * stepY / 9 * totalSum);
        }
示例#2
0
        static void Main(string[] args)
        {
            string expression = "-2*x^2+(-2*y^2)+(-3*sin(x)*cos(y))";

            Surface _surface = new Surface(expression);

            var integrationInfo = new DoubleIntegrationInfo
            {
                XStart = -100,
                XEnd   = 100,
                YStart = -20,
                YEnd   = 20
            };

            var numericalIntegration = new NumericalIntegration();

            numericalIntegration.CalculateBySimpsonMethod(integrationInfo, _surface.CalculateSurfaceFunction);
        }
        public IntegrationExtendedInfo CalculateBySimpsonMethod(DoubleIntegrationInfo integrationInfo, Func <double, double, double> surfaceFunction)
        {
            var n = (int)(((integrationInfo.XEnd - integrationInfo.XStart) + (integrationInfo.YEnd - integrationInfo.YStart)));
            //var n = 600;
            double result      = 0;
            var    threadsTime = new Dictionary <int, TimeSpan>();

            var stopwatch = new Stopwatch();

            for (var i = 1; i <= 15; i++)
            {
                stopwatch.Start();
                result = CalculateDoubleSimpsonWithThreads(integrationInfo, surfaceFunction, n, i);
                stopwatch.Stop();
                threadsTime.Add(i, stopwatch.Elapsed);
                stopwatch.Reset();
            }

            return(new IntegrationExtendedInfo
            {
                IntegrationResult = result,
                ThreadsTime = threadsTime
            });
        }