Вычисление корней алгебраического уравнения методом Ньютона-Рафсона - комментарии к коду - C (СИ)
Формулировка задачи:
ВЫЧИСЛЕНИЕ КОРНЕЙ АЛГЕБРАИЧЕСКОГО УРАВНЕНИЯ МЕТОДОМ НЬЮТОНА-РАФСОНА
#include // Для printf
#include
#include // Для комплексной арифметики (crealf, cimagf)
typedef float complexFloat; // Создание собственного имени типа
void Newton_Raphson(int n, Float q[n + 1], Float p[n], float eps);
Float hor(int n, Float a[n + 1], Float x, Float* b)
{
int i; // Рабочая переменная
Float val = a[n];
if (b) {
b[n - 1] = val;
}
for (i = n - 1; i >= 0; --i) {
val *= x;
val += a[i];
if (b && i) {
b[i - 1] = val;
}
}
return val;
}
Float dhor(int n, Float a[n + 1], Float x)
{
int i; // Рабочая переменная
Float val = n * a[n];
for (i = n - 1; i > 0; --i) {
val *= x;
val += i * a[i];
}
return val;
}
void newton(int n, Float a[n + 1], Float* px, Float x0, float eps)
{
Float x = x0, dx, f_val, df_val;
int niter = 1;
do {
f_val = hor(n, a, x, NULL);
df_val = dhor(n, a, x);
if (df_val != 0) {
dx = f_val / df_val;
} else {
break;
}
x -= dx;
} while (++niter <= 100 && cabsf(dx) > eps);
*px = x;
}
void Newton_Raphson(int n, Float q[n + 1], Float p[n], float eps)
{
Float x, x0;
int i; // Рабочая переменная
float err;
while (n) {
x0 = 1.0f; // Нулевая итерация
newton(n, q, &x, x0, eps);
err = cabsf(hor(n, q, x, NULL));
if (err > eps) {
newton(n, q, &x, x0 * I, eps);
err = cabsf(hor(n, q, x, NULL));
}
Float b[n];
hor(n, q, x, b);
p[n - 1] = x;
for (i = 0; i < n; ++i) {
q[i] = b[i];
}
--n;
}
}
int main(int argc, char* argv[])
{
int n; // Степень уравнения
int i; // Рабочая переменная
printf("\nThe degree of the equation = "); // Степень уравнения
scanf("%d", &n);
Float q[n + 1]; // Вектор коэффициентов исходного уравнения
// по возрастанию степеней
Float p[n]; // массив корней уравнения
printf("\nA vector of the coefficients:\n"); // Вектор коэффициентов
for (i = 0; i <= n; i++) {
float x;
scanf("%f", &x);
q[i] = x;
}
Newton_Raphson(n, q, p, 1e-6);
printf("\n The roots of the equation"); // Корни уравнения
printf("\n");
printf("\n Real part\ Imaginary part\n"); // Действительная и мнимая части
for (i = 0; i < n; i++) {
printf("%16f\%16f\n", crealf(p[i]), cimagf(p[i])); // Вывод действительной и мнимой части
}
printf("\n");
return 0;
}Решение задачи: «Вычисление корней алгебраического уравнения методом Ньютона-Рафсона - комментарии к коду»
textual
Листинг программы
typedef float complexFloat; // Создание собственного имени типа
Объяснение кода листинга программы
- Создание собственного имени типа
complexFloatдля представления комплексных чисел с плавающей точкой. float complex x = 0.0, z = 1.0; // Начальное приближение для x и z - Инициализация переменных
xиzначальными приближениями для метода Ньютона-Рафсона. Значениеxустановлено равным 0.0, аzравно 1.0. float complex f(float complex w) // Определение функции { return w*w - 1.0; // Функция f(w) = w^2 - 1.0 } - Определение функции
f(w), которая представляет собой квадрат комплексного числа минус единица. float complex g(float complex w) // Определение функции { return 2.0*w; // Функция g(w) = 2w } - Определение функции
g(w), которая представляет собой удвоенное значение комплексного числаw. float complex newtonRaphson(float complex z) // Определение метода Ньютона-Рафсона { float complex fz = f(z); // Вычисление значения функции f(z) float complex gz = g(z); // Вычисление значения функции g(z) float complex newz = z - fz/gz; // Вычисление нового значения z return newz; // Возврат нового значения z } - Определение функции
newtonRaphson(z), которая реализует метод Ньютона-Рафсона для нахождения корней уравнения. for (int i = 0; i < 20; i++) // Цикл для выполнения метода Ньютона-Рафсона до достижения 20 итераций { float complex temp = z; // Создание временной переменной для хранения текущего значения z z = newtonRaphson(z); // Вычисление нового значения z с помощью метода newtonRaphson if (temp == z) // Проверка на сходимость break; // Если значения z не изменились, то выход из цикла } - Цикл, который выполняет метод Ньютона-Рафсона до достижения 20 итераций или до тех пор, пока значения
zне перестанут изменяться. printf(Корни уравнения: x = %f + %fi, x = %f + %fi\n, creal(z), cimag(z), creal(z), cimag(z)); // Вывод результатов - Вывод результатов на экран с помощью функции
printf. Значения реального и мнимого компонентов корней уравнения выводятся в форматеx = a + bi, гдеaиbпредставляют собой действительную и мнимую части соответственно.