Язык Си в примерах/Корень уравнения: различия между версиями

Содержимое удалено Содержимое добавлено
орфография
м Замена <tt /> на <code />; избыточные <big /> и <font /> вокруг <source />; {{SUBPAGENAME}}; пробелы.
Строка 4:
<math>e^x = x + 2.\,\!</math>
С помощью компьютера необходимо найти положительный корень этого уравнения с
погрешностью по оси <math>x</math> не более <math>10^{-10}\,\!</math>.
 
Вот решение этой задачи:
 
<big><source lang="c">
/* root.c: Вычисление корня трансцендентного уравнения */
#include <stdio.h>
Строка 27:
printf ("%.10lf\n", (l + r)/2 ); // выводим результат
}
</source></big>
 
При компиляции этой программы с помощью GCC следует указать опцию <ttcode>-lm</ttcode>, которая указывает что при компоновке программы необходимо подключить библиотеку <ttcode>libm</ttcode> с математическими функциями:
 
bash$ gcc -lm root.c -o root
 
В библиотеке <ttcode>mlib</ttcode>, в частности, определена функция <ttcode>exp</ttcode>, вычисляющая экспоненту, а также многие другие математические функции: тригонометричекие (<ttcode>sin</ttcode>, <ttcode>cos</ttcode>, <ttcode>asin</ttcode>, <ttcode>acos</ttcode>, <ttcode>tan</ttcode>, ...), корень (<ttcode>sqrt</ttcode>), степень (<ttcode>pow</ttcode>), логарифм (<ttcode>log</ttcode>), ...
 
Директива <ttcode>#define EPS 1e-10</ttcode> означает: в тексте программы идентификатор EPS
заменить на число <ttcode>1e-10</ttcode>, то есть <math>1\cdot 10^{-10}\,\!</math>. Число <ttcode>EPS</ttcode> &mdash; это погрешность по оси <math>x</math>,
с которой мы хотим найти корень.
 
Алгоритм вычисления корня основан на [[:w:Метод бисекции|методе деления пополам]]:
Предположим, что искомый корень находится между
<ttcode>l = 0</ttcode> и <ttcode>r = 2</ttcode>. Найдем середину <ttcode>c</ttcode> отрезка <ttcode>[l, r]</ttcode>.
Корень находится на одном из отрезков: либо на <ttcode>[l, c]</ttcode>,
либо на <ttcode>[с, r]</ttcode>, а именно, на том, значение функции на концах которого
имеет разные знаки (вспомните [[w:Теорема Ролля|теорему Ролля]] про непрерывную функцию из курса мат. анализа).
Выберем нужный из двух отрезков и применим к нему такие же рассуждения.
Будем осуществлять деление пополам, пока размер отрезка не станет меньше необходимой точности. (В [[:w:Метод бисекции|методе деления отрезка пополам]] отрезок на оси <math>x</math> делится пополам пока <math>|f(x_c)|>\varepsilon_f</math>, в приведённом же методе отрезок на оси <math>x</math> может достичь заданной величины <math>\varepsilon_x</math>, а значения функций <math>f(x)</math> (особенно крутых) на оси <math>y</math> могут очень далеко отстоять от нуля, при пологих же функциях <math>f(x)</math> этот метод приводит к большому числу лишних вычислений.)
 
 
== Вопросы и задачи ==
 
* За один шаг длина отрезка <ttcode>[l, r]</ttcode> уменьшается в два раза. Сколько нужно шагов, чтобы уменьшить отрезок более, чем в 1000 раз?
* Сколько требуется шагов, чтобы начиная с отрезка длины <math>r-l=2\,\!</math> дойти до отрезка длины меньше <math>10^{-10}\,\!</math>? Сколько требуется шагов, чтобы найти корень с точностью до 100 знаков после запятой?
* В случае деления пополам у нас есть нижняя и верхняя граница для значения корня. С каждым шагом эти границы сближаются. В методе Ньютона нахождения корня уравнения у нас имеется одно число ''x'' &mdash; текущее приближение корня. И следующее приближение получается по следующему алгоритму: находим точку на графике с абсциссой x и проводим из неё касательную к графику; абсцисса точки пересечения касательной с осью абсцисс будет новым значением ''x''. Так делается до тех пор, пока новое ''x'' отличается от старого на число меньше, чем <math>10^{-10}/2\,\!</math>. Реализуйте этот алгоритм. Для этого вам понадобится определить еще одну функцию, которая возвращает значение производной <math>f'(x) = (e^x-x-2)' = e^x-1\,\!</math>.
Строка 61:
Для этого нужно научиться передавать функцию в качестве аргумента --- это возможно, и совсем несложно:
 
<big><source lang="c">
/* Универсальная функция вычисления корня уравнения f(x) = 0 */
#include <stdio.h>
Строка 84:
return 0;
}
</source></big>
 
Вывод программы выглядит следующим образом:
Строка 94:
 
* [[Язык Си в примерах/Библиотека complex|Библиотека complex]]
[[Категория:Язык Си в примерах|Корень уравнения{{SUBPAGENAME}}]]