Задачи на тему
"Вычисление стандартных функций с помощью суммирования рядов"
Во всех задачах надо вычислить стандартную функцию с
точностью ε=1e-12. Для небольших значений x
это делается с помощью суммирования степенного ряда.
Для значений x, при которых ряд не сходится или
сходится очень медленно, надо воспользоваться какой-либо
формулой, позволяющей свести вычисление нужной функции
к вычислению ее или других функций при "хороших" значениях
x. Например, формула
arctg(x) = 2*arctg(y),
y = (sqrt(1 + x*x) - 1)/x,
позволяет вычислить arctg(1)=π/4, сведя задачу к
суммированию степенного ряда для
y = sqrt(2) - 1.
Список задач
-
Вычислить
arctg(x).
Поскольку ряд
$$
\text{arctg}(x) = x - x^3/3 + x^5/5 - x^7/7 + \dots
$$
сходится лишь в интервале $(-1, 1)$ (для $x=1$ он тоже сходится,
но фантастически медленно),
его можно суммировать лишь для значений $|x| < 1$. Для проивольного значения
$x \ge 1$ можно воспользоваться формулой
$$
\begin{array}{l}
\text{arctg}(x) = 2 \cdot \text{arctg}(y),\quad \text{где}\\
y = (\sqrt{1 + x^2} - 1)/x
\end{array}
$$
(учитывая нечетность функции $\text{arctg}(x)$, можно считать,
что $x > 0$). Формула позволяет свести вычисление значения функции
$\text{arctg}(x)$ для произвольного $x$ к суммированию ряда для
$\text{arctg}(y)$ при $0 < y < 1$.
Доказательство формулы.
Воспользуемся формулой тангенса двойного угла:
$$
\text{tg}(2z) = \text{sin}(2z)/\text{cos}(2z) =
\frac{2\text{sin}(z)\text{cos}(z)}{\text{cos}^2(z) - \text{sin}^2(z)} =
\frac{2\cdot\text{tg}(z)}{1 - \text{tg}^2(z)}
$$
Обозначим $2z = \text{arctg}(x)$, тогда $\text{tg}(2z) = x$. Имеем
$$
x =
\frac{2\cdot\text{tg}(z)}{1 - \text{tg}^2(z)}
$$
Это равенство позволяет выразить $\text{tg}(z)$ через $x$.
Обозначим $\text{tg}(z) = y$. Получим квадратное уравнение:
$$
x =
\frac{2y}{1 - y^2} \quad \Rightarrow \quad
y^2 x + 2y - x = 0,
$$
откуда, учитывая ограничение $y > 0$, получаем
$$
y = \frac{-2 + \sqrt{4 + 4x^2}}{2x} = (-1 + \sqrt{1 + x^2})/x
$$
Учитывая, что $y = \text{tg}(z)$, получаем
$$
z = \text{arctg}(y) = \text{arctg}((\sqrt{1 + x^2} - 1)/x)
$$
Поскольку $2z = \text{arctg}(x)$, окончательно получаем формулу при
$x > 0$:
$$
\text{arctg}(x) = 2\cdot \text{arctg}((\sqrt{1 + x^2} - 1)/x)
$$
Покажем теперь, что $0 < y < 1$. Действительно, поскольку $x > 0$, то
$$
y = (\sqrt{1 + x^2} - 1)/x < (\sqrt{1 + 2x + x^2} - 1)/x =
((x + 1) - 1)/x = 1
$$
-
Вычислить
arcsin(x).
Ряд для функции $\text{arcsin}(x)$ сходится очень плохо вблизи точек
$x = \pm 1$, поскольку в этих точках производная функции бесконечна.
Решение состоит в том, чтобы свести вычисление $\text{arcsin}(x)$
к вычислению функции arctg. Поскольку функция $\text{arcsin}(x)$
нечетная, можно считать, что $0 < x < 1$ (при $x=1$
$\text{arcsin}(x) = \pi/2$ и можно воспользоваться константой $\pi$).
Пусть $y = \text{arcsin}(x)$, тогда $x = \text{sin}(y)$ и
$$
\text{tg}(y) = \text{sin}(y)/\text{cos}(y) =
x/\sqrt{1 - x^2}
$$
Поэтому
$$
y = \text{arctg}(x/\sqrt{1 - x^2})
$$
При решении данной задачи можно считать, что функция $\text{arctg}$
уже реализована (это первая задача), и воспользоваться библиотечной
функцией $\text{atan}(x)$.
-
Вычислить
arccos(x).
Как и в предыдущей задаче, сведем вычисление $y = \text{arccos}(x)$
к вычислению функции arctg. Имеем $x = \text{cos}(y)$, поэтому
$$
\text{tg}(y) = \text{sin}(y)/\text{cos}(y) =
\sqrt{1 - x^2}/x
$$
(мы воспользовались тем, что $y = \text{arccos}(x)$, следовательно,
$0 \le y \le \pi$ и $\text{sin}(y) \ge 0$; можно считать также, что
$x \ne 0$, поскольку при $x = 0$ $\text{arccos}(x) = \pi/2$
и в программе можно воспользоваться константой $\pi$).
Заметим также, что функция $\text{tg}(y)$ периодическая с периодом $\pi$.
Поэтому из предыдущего равенства следует, что
$$
y = \text{arctg}(\sqrt{1 - x^2}/x) + \pi k, \quad k\in\Bbb{Z}.
$$
Если $0 < x \le 1$, то $0 \le \text{arccos}(x) < \pi/2$, поэтому $k = 0$
и
$$
y = \text{arccos}(x) = \text{arctg}(\sqrt{1 - x^2}/x) \quad
\text{при}\ x > 0.
$$
Если $-1 \le x < 0$, то $\pi/2 < \text{arccos}(x) \le \pi$, поэтому $k = 1$
и
$$
y = \text{arccos}(x) = \text{arctg}(\sqrt{1 - x^2}/x) + \pi\quad
\text{при}\ x < 0.
$$
Наконец, $\text{arccos}(0) = \pi/2$.
Как и в предыдущей задаче, можно считать, что функция $\text{arctg}$
уже реализована, и воспользоваться библиотечной
функцией $\text{atan}(x)$, а также константой $\pi$.
-
Вычислить
ln(x).
В принципе, можно свести вычисление логарифма произвольного числа
к суммированию ряда для маленького x. Однако есть более
интересный алгорим, основанный на применении схемы инварианта цикла.
Итак, пусть дано число $x > 0$, и надо приближенно вычислить
$\ln(x)$ с точностью $\varepsilon$:
$$
y = \ln(x)
$$
Это означает, что
$$
e^y = x
$$
Используем следующий инвариант цикла:
$$
e^y\cdot z^t = x
$$
В цикле будут изменяться 3 переменные $y$, $z$, $t$
так, чтобы инвариант сохранялся (т.е. выполнялось бы это
равенство). Начальные значения этих трех переменных
подбираются так, чтобы инвариант выполнялся:
$$
y = 0,\quad z = x,\quad t = 1.
$$
Пусть инвариант выполняется. В каком случае мы сразу
можем выдать ответ? Тогда, когда выполняется приблизительное
равенство
$$
z^t \approx 1,
$$
в этом случае из выполнения инварианта
$$
e^y\cdot z^t = x
$$
следует, что
$$
e^y\cdot z^t \approx e^y\cdot 1 \approx x,
$$
то есть
$$
y \approx \ln(x)
$$
и ответ содержится в переменной $y$.
Значит, наша цель — добиться того, чтобы
$z^t \approx 1$. Для этого достаточно, чтобы показатель
$t$ степени был бы очень мал, а основание $z$ степени было
бы не очень мало и не очень велико. Точнее, достаточно,
чтобы выполнялись неравенства
$$
1/e \le z \le e\quad \text{и}\quad |t| \le \varepsilon.
$$
Это условие завершения цикла.
В цикле мы будем выполнять действия так, чтобы
переменная $t$ по модулю только уменьшалась, а переменная
$z$ рано или поздно входила бы в интервал
$1/e \le z \le e$, и при этом величина $e^y\cdot z^t$
сохранялась бы. Вот какие действия для этого выполняются:
$$
\begin{array}{lll}
z > e \quad & \Longrightarrow \quad & z = z/e,\quad y = y+t \\
z < e \quad & \Longrightarrow \quad & z = z\cdot e,\quad y = y-t \\
\text{иначе} &\Longrightarrow \quad & z = z^2,\quad t = t/2 \\
\end{array}
$$
Напишем алгоритм приближенного вычисления $\ln(x)$
на псевдокоде:
Дано: x > 0, малое ε > 0
Надо: вычислить ln(x) с точностью ε
e = 2.7182818284590452354
y = 0; z = x; t = 1
цикл пока z < 1/e или z > e или |t| > ε
| если z < 1/e
| | z = z*e; y = y - t
| иначе если z > e
| | z = z/e; y = y + t
| иначе
| | z = z*z; t = t/2
| конец если
конец цикла
ответ = y
-
Вычислить
xα
Вычисление степенной функции можно свести
к вычислению экспоненты и логарифма. А именно,
поскольку $x = e^{\ln(x)}$, то
$$
x^\alpha = (e^{\ln(x)})^\alpha = e^{\alpha\ln(x)}
$$
В этой задаче будем считать, что мы уже умеем вычислять
$\ln(x)$ (это задача 4) и можно просто воспользоваться
стандартной функцией log(x) языка C из математической
библиотеки (она вычисляет натуральный логарифм).
Остается самостоятельно написать алгоритм вычисления
экспоненты как суммы ряда:
$$
e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + \dots
$$
Теоретически ряд сходится для любых значений $x$,
но на практике из-за ошибок округления его можно суммировать
только для небольших значений $x$, например, при
$|x| < 1$.
Для сведения вычисления экспоненты
к суммированию ряда для значений $|x| < 1$
воспользуемся следующим соображением. Выделим целую и
дробную части $x$:
$$
x = k + r, \quad \text{где}\quad
k\in{\bf{Z}}\quad\text{и}\quad |r| < 1
$$
Тогда
$$
e^x = e^k \cdot e^r
$$
Мы вычисляем $e^k$, просто возводя константу
$$
e = 2.7182818284590452354
$$
в целую степень $k$, а $e^r$ вычисляем как сумму ряда.
|