public double Simpson(double left, double right, int n) { sw.Start(); //Замеряем время решения! object block = new object(); double result = 0; void calculate(int part) { double width = (right - left) / (n); double local_left = left + (right - left) * part / parts; //Console.WriteLine("{0} local_left = {1}", part, local_left); double local_result = 0; int steps = n / parts; for (int step = 0; step < (n / parts); step++) { double x1 = local_left + step * width; double x2 = local_left + (step + 1) * width; local_result += (x2 - x1) / 6.0 * (function(x1) + 4.0 * function(0.5 * (x1 + x2)) + function(x2)); EventDraw?.Invoke(x1, x2, part); //для рисования метода симпсона // donePercent += percentsDelta; } Monitor.Enter(block); result += local_result; Monitor.Exit(block); } Parallel.For(0, parts, calculate); sw.Stop(); EventFinish?.Invoke(result, sw.ElapsedMilliseconds); return(result); }
public double Rectangular(double left, double right, int n) { sw.Start(); //Замеряем время Random random = new Random(); double dt = (right - left) / n; double result = 0; int partsSize = (int)n / parts; int reminder = n - partsSize * parts; object block = new object(); void calculating(int part) { int start = part * partsSize + ((part < reminder) ? part : reminder); int finish = (part + 1) * partsSize + ((part + 1 < reminder) ? part : (reminder - 1)); //Console.WriteLine("Для {0} потока начальный индекс - {1}, конечный - {2}", part, start, finish); int percentsDelta = (int)(Math.Round((double)(100 / n))); //Console.WriteLine("{0}: Start - {1}, Finish - {2}, PercentDt - {3}",part, start, finish, percentsDelta); double x = left + (start + 0.5) * dt; double part_result = 0; for (int i = start; i <= finish; i++) { part_result += function(x) * dt; EventDraw?.Invoke(x, function(x), part); x += dt; } Monitor.Enter(block); result += part_result; Monitor.Exit(block); } Parallel.For(0, parts, calculating); sw.Stop(); EventFinish?.Invoke(result, sw.ElapsedMilliseconds); return(result); }
public double SimpsonI(double left, double right, int n) { sw.Start(); //Замеряем время object block = new object(); double result = 0; void calculate(int part) { int percents_step = 10; double width = (right - left) / (n); double local_left = left + (right - left) * part / parts; Console.WriteLine("{0} local_left = {1}", part, local_left); double local_result = 0; int steps = n / parts; int percentsDelta = (int)(Math.Round((double)(100 / n))); for (int step = 0; step < steps; step++) { double x1 = local_left + step * width; double x2 = local_left + (step + 1) * width; local_result += (x2 - x1) / 6.0 * (function(x1) + 4.0 * function(0.5 * (x1 + x2)) + function(x2)); EventDraw?.Invoke(x1, x2, part); donePercent += percentsDelta; if (donePercent > percents_step) { EventProgress?.Invoke(donePercent); percents_step += 10; } } Monitor.Enter(block); result += local_result; Monitor.Exit(block); } Parallel.For(0, parts, calculate); sw.Stop(); EventFinish?.Invoke(result, sw.ElapsedMilliseconds); return(result); }
public double Monte_Carlo(double left, double right, int throwsMultiplier, double sup, double inf, int strats_count) { sw.Start(); //Замеряем время double dt = (right - left) / strats_count; //Console.WriteLine("dt: {0}", dt); int throws = (int)(Math.Round((sup - inf) / dt)) * strats_count * throwsMultiplier; //Console.WriteLine("Всего будет сделано {0} бросков", throws); double result = 0; double partLength = (right - left) / parts; int partsSize = strats_count / parts; int reminder = strats_count - partsSize * parts; object block = new object(); void calculating(int part) { int percentsDelta = throws / 100; Random randomX = new Random(DateTime.Now.Millisecond * (part + 1)); Random randomY = new Random(DateTime.Now.Millisecond * (part + 2)); //Console.WriteLine("[Thread №{0}] Начаты вычисления в потоке...", part); int count = 0; //Кол-во точек под графиком int start = part * partsSize + ((part < reminder) ? part : reminder); int finish = (part + 1) * partsSize + ((part + 1 < reminder) ? part : (reminder - 1)); //Console.WriteLine("[Thread №{0}] Задана область интегрирования: [{1}; {2}]x[{3}, {4}]", part, start*dt, finish*dt + dt, inf, sup); double x_id = left + start * dt; double y_id = inf; for (int i = 0; i < throws / parts; i++) { //Console.WriteLine("[Thread №{0}] Страта - [{1}; {2}]x[{3}, {4}]", part, x_id, x_id + dt, y_id, y_id + dt); double x = randomX.NextDouble() * dt + x_id; // Генерируем случайную точку в диапазоне (x_id + dx, y_id + dy) double y = randomY.NextDouble() * dt + y_id; if (i % 117 == 0) { EventDraw?.Invoke(x, y, part); //Проверяем вхождение точки в область под графиком } if (function(x) >= 0) { if (y <= function(x) && y >= 0) { count++; } } else { if (y >= function(x) && y < 0) { count--; //Console.WriteLine("[{2}] ({1}) Y[{5}, {6}]", x, y, part, x_id, x_id + dx, y_id, y_id + dy); } } //Дальше Изменение области генерации x_id += dt; //Сдвигаемся по Х if (x_id > left + finish * dt) //При выходе за границу по Х { y_id += dt; //Поднимаемся на уровень выше x_id = left + start * dt; //Возвращаемся на начальное значения Х if (y_id >= sup) { y_id = inf; //При выходе за границу по Y и по Х начинаем сначала } } if ((i) % (percentsDelta) == 0) { donePercent++; EventProgress?.Invoke(donePercent); } } //Console.WriteLine("[Thread №{0}]: Кол-во попаданий = {1}\n" + "\t Всего бросков: {2}", part, count, throws / parts); Monitor.Enter(block); result += count; Monitor.Exit(block); } Parallel.For(0, parts, calculating); result = (result / throws) * (right - left) * (sup - inf); sw.Stop(); // EventFinish?.Invoke(result, sw.ElapsedMilliseconds); return(result); }