public double GoldenSection(double[] X, double eps, double left, double right, double[] p) { double a = left, b = right, t, x1, x2, F1, F2; int i = 0; t = 0.618; x1 = b - (b - a) * t; x2 = a + (b - a) * t; F1 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]); F2 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]); while (true) { i++; if (F1 <= F2) { b = x2; x2 = x1; F2 = F1; x1 = b - (b - a) * t; F1 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]); } else { a = x1; x1 = x2; F1 = F2; x2 = a + (b - a) * t; F2 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]); } if ((b - a) < eps) { break; } } x1 = (a + b) / 2; if (x1 == left) { GoldenSection(X, eps, x1 - right + left, x1, p); } else if (x1 == right) { GoldenSection(X, eps, x1, x1 + right - left, p); } return(x1); }
private void HookJeevesButton_Click(object sender, EventArgs e) { OutBox.Text = string.Empty; double eps = Convert.ToDouble(EpsilonBox.Text); // Точность вычислений double step = Convert.ToDouble(StepBox.Text); // Начальный шаг // Начальное приближение double x = Convert.ToDouble(x0Box.Text); double y = Convert.ToDouble(y0Box.Text); double y0 = FunctionClass.Function2(x, y); int IterCount = 0; double fx; double lenght, y1, y2, y3, x1n, x2n, x1nn, x2nn; int fl = 0; lenght = 1; do { fx = FunctionClass.Function2(x, y); OutBox.Text += "x = " + Math.Round(x, 6).ToString() + " y = " + Math.Round(y, 6).ToString() + " f(x, y) = " + Math.Round(fx, 6).ToString() + "\r\n"; fl = 0; y1 = FunctionClass.Function2(x + step, y); if (y1 < y0) { x1n = x + step; } else { y1 = FunctionClass.Function2(x - step, y); if (y1 < y0) { x1n = x - step; } else { x1n = x; y1 = y0; } } y2 = FunctionClass.Function2(x1n, y + step); if (y2 < y1) { x2n = y + step; } else { y2 = FunctionClass.Function2(x1n, y - step); if (y2 < y1) { x2n = y - step; } else { x2n = y; y2 = y1; } } if ((x1n == x) && (x2n == y)) { if (step > eps) { fl = 1; step = step / 2; } } else { fl = 1; do { x1nn = x1n + lenght * (x1n - x); x2nn = x2n + lenght * (x2n - y); y3 = FunctionClass.Function2(x1nn, x2nn); x = x1nn; y = x2nn; lenght = lenght * 0.5; } while (y2 < y3); IterCount++; y0 = y3; } } while (fl == 1); fx = FunctionClass.Function2(x, y); MinXBox.Text = x.ToString(); MinYBox.Text = y.ToString(); MinFBox.Text = fx.ToString(); IterCountBox.Text = IterCount.ToString(); }
private void BuildButton_Click(object sender, EventArgs e) { // Границы вычисления функции по осям X и Y double minX = Convert.ToDouble(MinXBox.Text); double maxX = Convert.ToDouble(MaxXBox.Text); double minY = Convert.ToDouble(MinYBox.Text); double maxY = Convert.ToDouble(MaxYBox.Text); // Масштаб double intervalX = maxX - minX; double intervalY = maxY - minY; double zoomX = intervalX / bitmap.Width; // 1 пиксель : 1 ед.измерения оси X double zoomY = intervalY / bitmap.Height; // 1 пиксель : 1 ед.измерения оси Y double eps = Convert.ToDouble(EpsilonBox.Text); // Точность int levelCount = Convert.ToInt32(LevelBox.Text); // Количество линий уровня // Уровни int countX = Convert.ToInt32(bitmap.Width); int countY = Convert.ToInt32(bitmap.Height); double[,] values = new double[countX, countY]; // Сетка функции double[] levels = new double[levelCount]; // Уровни функции for (int i = 0; i < bitmap.Width; i++) { for (int j = 0; j < bitmap.Height; j++) { double x = minX + i * zoomX; double y = minY + j * zoomY; double z = FunctionClass.Function2(x, y); values[i, j] = z; } } double minValue = values[0, 0]; // Локальный минимум функции double maxValue = values[0, 0]; // Локальный максимум функции for (int i = 0; i < values.GetLength(0); i++) { for (int j = 0; j < values.GetLength(1); j++) { if (values[i, j] < minValue) { minValue = values[i, j]; } if (values[i, j] > maxValue) { maxValue = values[i, j]; } } } int levelStepX = bitmap.Width / levelCount / 2; int levelStepY = bitmap.Height / levelCount / 2; for (int i = 0; i < levelCount; i++) { levels[i] = values[i * levelStepX, i *levelStepY]; } // Рисуем линии уровней ProgressBar.Value = 0; ProgressBar.Maximum = bitmap.Width * bitmap.Height * levels.Length; for (int i = 0; i < bitmap.Width; i++) { for (int j = 0; j < bitmap.Height; j++) { for (int k = 0; k < levels.Length; k++) { double x = minX + i * zoomX; double y = minY + j * zoomY; double z = FunctionClass.Function2(x, y); if (z >= levels[k] - eps && z <= levels[k] + eps) { int c = (int)(255 * Math.Abs(z - levels[k]) / eps); DrawPoint(i, bitmap.Height - j - 1, Color.FromArgb(c, c, c)); } ProgressBar.Value++; } } } }
private void GaussButton_Click(object sender, EventArgs e) { OutBox.Text = string.Empty; double eps = Convert.ToDouble(EpsilonBox.Text); // Точность вычислений double step = Convert.ToDouble(StepBox.Text); // Начальный шаг // Начальное приближение double x = Convert.ToDouble(x0Box.Text); double y = Convert.ToDouble(y0Box.Text); int IterCount = 0; double fx, prevX, prevY, curX = x, curY = y; double leftBorder, rightBorder; double x1, xm, x2; double y1, ym, y2; double z1, zm, z2; do { IterCount++; prevX = curX; prevY = curY; // По 1 координате leftBorder = prevX - step; rightBorder = prevX + step; x1 = leftBorder + (rightBorder - leftBorder) / 4; xm = (leftBorder + rightBorder) / 2; x2 = rightBorder - (rightBorder - leftBorder) / 4; z1 = FunctionClass.Function2(x1, prevY); zm = FunctionClass.Function2(xm, prevY); z2 = FunctionClass.Function2(x2, prevY); while (Math.Abs(rightBorder - leftBorder) > eps) { if ((z1 > zm) && (zm < z2)) { leftBorder = x1; rightBorder = x2; x1 = leftBorder + (rightBorder - leftBorder) / 4; x2 = rightBorder - (rightBorder - leftBorder) / 4; } else if ((z1 > zm) && (zm > z2)) { leftBorder = xm; x1 = leftBorder + (rightBorder - leftBorder) / 4; x2 = rightBorder - (rightBorder - leftBorder) / 4; xm = (leftBorder + rightBorder) / 2; zm = FunctionClass.Function2(xm, prevY); } else if ((z1 < zm) && (zm < z2)) { rightBorder = xm; x1 = leftBorder + (rightBorder - leftBorder) / 4; x2 = rightBorder - (rightBorder - leftBorder) / 4; xm = (leftBorder + rightBorder) / 2; zm = FunctionClass.Function2(xm, prevY); } z1 = FunctionClass.Function2(x1, prevY); z2 = FunctionClass.Function2(x2, prevY); } curX = (leftBorder + rightBorder) / 2; // По 2 координате leftBorder = prevY - step; rightBorder = prevY + step; y1 = leftBorder + (rightBorder - leftBorder) / 4; ym = (leftBorder + rightBorder) / 2; y2 = rightBorder - (rightBorder - leftBorder) / 4; z1 = FunctionClass.Function2(curX, y1); zm = FunctionClass.Function2(curX, ym); z2 = FunctionClass.Function2(curX, y2); while (Math.Abs(rightBorder - leftBorder) > eps) { if ((z1 > zm) && (zm < z2)) { leftBorder = y1; rightBorder = y2; y1 = leftBorder + (rightBorder - leftBorder) / 4; y2 = rightBorder - (rightBorder - leftBorder) / 4; } else if ((z1 > zm) && (zm > z2)) { leftBorder = ym; y1 = leftBorder + (rightBorder - leftBorder) / 4; y2 = rightBorder - (rightBorder - leftBorder) / 4; ym = (leftBorder + rightBorder) / 2; zm = FunctionClass.Function2(curX, ym); } else if ((z1 < zm) && (zm < z2)) { rightBorder = ym; y1 = leftBorder + (rightBorder - leftBorder) / 4; y2 = rightBorder - (rightBorder - leftBorder) / 4; ym = (leftBorder + rightBorder) / 2; zm = FunctionClass.Function2(curX, ym); } z1 = FunctionClass.Function2(curX, y1); z2 = FunctionClass.Function2(curX, y2); } curY = (leftBorder + rightBorder) / 2; }while (Math.Abs(FunctionClass.Function2(curX, curY) - FunctionClass.Function2(prevX, prevY)) > eps); fx = FunctionClass.Function2(curX, curY); MinXBox.Text = curX.ToString(); MinYBox.Text = curY.ToString(); MinFBox.Text = fx.ToString(); IterCountBox.Text = IterCount.ToString(); }
private void NewtonButton_Click(object sender, EventArgs e) { OutBox.Text = string.Empty; // Шаг 1 int k = 0; // Счетчик итераций double x0, y0; // Начальное приближение double a = 1; // Шаг для модифицированного метода x0 = Convert.ToDouble(x0Box.Text); y0 = Convert.ToDouble(y0Box.Text); eps = Convert.ToDouble(EpsilonBox.Text); //a = Convert.ToDouble(StepBox.Text); double x = x0, y = y0; // Текущая точка double[] grad = new double[2]; // Градиент double [,] matrix = new double[2, 2]; // Матрица Гессе double[,] invertMatrix = new double[2, 2]; // Обратная матрица Гессе double[] p = new double[2]; // Направление спуска double[] curPoint = new double[2]; // Текущая точка double[] nextPoint = new double[2]; // Следущая точка calculate: OutBox.Text += "Итерация № " + k.ToString() + "\r\n" + "Текущая точка (" + x + ", " + y + ")\r\n" + "Значение функции в точке " + FunctionClass.Function2(x, y) + "\r\n"; // Вычисляем градиент grad = GetGrad(x, y); OutBox.Text += "Градиент\r\n (" + grad[0] + ", " + grad[1] + ")\r\n"; // Вычисляем матрицу Гессе matrix = GetHesse(x, y); OutBox.Text += "Матрица Гессе\r\n" + "| " + matrix[0, 0] + " | " + matrix[0, 1] + " |\r\n" + "| " + matrix[1, 0] + " | " + matrix[1, 1] + " |\r\n"; // Шаг 2 // Определяем обратную матрицу invertMatrix = InvertMatrix(matrix); if (invertMatrix == null) { return; } OutBox.Text += "Обратная матрица Гессе\r\n" + "| " + invertMatrix[0, 0] + " | " + invertMatrix[0, 1] + " |\r\n" + "| " + invertMatrix[1, 0] + " | " + invertMatrix[1, 1] + " |\r\n"; // Шаг 3 // Определяем направление спуска p = GetDirect(grad, invertMatrix); OutBox.Text += "Направление спуска\r\n (" + p[0] + ", " + p[1] + ")\r\n"; // Шаг 4 // Определяем следующую точку curPoint[0] = x; curPoint[1] = y; //a = GoldenSection(curPoint, eps, -10, 10, p); nextPoint = GetNextPoint(curPoint, a, p); OutBox.Text += "Новая точка (" + nextPoint[0] + ", " + nextPoint[1] + ")\r\n"; // Шаг 5 // Вычисление в новой точке градиента grad = GetGrad(nextPoint[0], nextPoint[1]); // Шаг 6 // Если точность не достигнута, то продолжаем итерации x = nextPoint[0]; y = nextPoint[1]; if ((Math.Sqrt(grad[0] * grad[0] + grad[1] * grad[1]) > eps && Math.Abs(FunctionClass.Function2(curPoint[0], curPoint[1]) - FunctionClass.Function2(nextPoint[0], nextPoint[1])) > eps)) { k++; OutBox.Text += "________________________________\r\n"; goto calculate; } double f = FunctionClass.Function2(x, y); OutBox.Text += "*************************************\r\n" + "Минимум функции равен " + f + "\r\n" + "в точке (" + x + ", " + y + ")\r\n"; MinXBox.Text = x.ToString(); MinYBox.Text = y.ToString(); MinFBox.Text = f.ToString(); IterCountBox.Text = (k + 1).ToString(); }
public double GetDfDy(double _x, double _y) { return((FunctionClass.Function2(_x, _y + Math.Pow(eps, 2)) - FunctionClass.Function2(_x, _y)) / Math.Pow(eps, 2)); }