2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


Посмотреть правила форума



Начать новую тему Ответить на тему
 
 Как компьютер вычисляет значение трансцендентных функций?
Сообщение14.09.2021, 17:57 


05/06/21
19
Добрый день! Помогите, пожалуйста, ответить на вопрос по теме машинного вычисления значения трансцендентных функций $\sin(x)$, $e^x$, $\ln(x)$. Преподаватель озвучил следующую проблему: если аргумент очень велик, то приближение рядом Тейлора сопряжено с большими погрешностями (тем более, у $\sin(x)$ члены разложения знакопеременные, а если где-то происходит вычитание близких чисел, то за этим следует большая потеря точности), что делать? Также нужно дать комментарии по идее в случае с функцией $\sin(x)$ воспользоваться периодичностью и вычесть из аргумента необходимое количество периодов, чтобы сдвинуть его, насколько возможно, к нулю, но, если аргумент был огромен, то, учитывая погрешность округления числа $\pi$, вычитание из аргумента большого количества $\pi$ также приведёт к потере точности - так как и когда можно достаточно точно вычислить $\sin(x)$?

У меня есть несколько общих идей: перегруппировать сложение членов ряда, чтобы минимизировать погрешность (складывать близкие числа и избегать вычитания близких чисел), для $e^x$ домножить и поделить $x$ на $10^{-k}$, чтобы $x \cdot 10^{-k}$ было достаточно мало (и тогда экспонента с помощью приближения первыми членами ряда Тейлора будет вычисляться достаточно точно), и результат возвести в степень $10^k$ (что тоже сопряжено с погрешностями, выиграем ли точность таким образом?), а для задачи с логарифмом в случае большого $x$ перебором найти такое натуральное $k$, чтобы $x^\frac{1}{k}$ было достаточно близко к единице, для него посчитать приближённое значение логарифма c помощью нескольких первых членов ряда Тейлора в единице, и потом умножить результат на $k$.
Для $\sin(x)$ и идеи использовать периодичность можно, например, заранее вычислить "сетку" из некоторых значений, кратных $\pi$, (например, каждые $1000 \pi n$) с машинной точностью (для этого специально выделив при вычислении дополнительную точность), и тогда погрешность при сдвиге на периоды удастся сделать поменьше.

Что из этого действительно неплохо применить, что бесполезно, и что ещё можно предложить для ответа на поставленный вопрос? Такое ощущение, что что-то достаточно эффективное должно лежать совсем на поверхности (преподаватель заверил, что достаточно знаний из базового курса численных методов и обычной сообразительности).

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение14.09.2021, 18:10 


05/09/16
12066
По поводу синусов, мне кажется что $\pi$ известно как предвычисленное с такой огромной точностью, что вычесть из аргумента синуса $2 \pi n$ можно без ущерба для любых практически требуемых $n$

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение14.09.2021, 19:05 
Заслуженный участник
Аватара пользователя


16/07/14
9151
Цюрих
Это огромная тема, и на практике для разных функций приходится думать. Но ряд Тейлора работает плохо всегда. Общая схема - как-то заменить аргумент значением поменьше и использовать какую-нибудь хорошую полиномиальную аппроксимацию. Для экспоненты, например, можно написать $e^x = e^a \cdot 2^b$ где $b$ целое (и на $2^b$ соответственно можно умножать без потери точности), а $|a| \leqslant \frac{\ln 2}{2}$. Для логарифма иногда можно написать $x = \frac{1 - y}{1 + y}$ и вместо $\ln x$ считать $\ln(1 \pm y)$.
Для точного вычисления синуса в любом случае нужно точно знать далекие разряды аргументов. Если аргумент в 32-битном числе с плавающей запятой и по модулю больше чем $2^{26}$, то синус от него может быть любым числом от $-1$ до $1$, и с этим ничего не поделать.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение14.09.2021, 19:31 
Заслуженный участник
Аватара пользователя


01/08/06
3131
Уфа
О, я как раз писал такую библиотеку.
С синусом так и не решил проблему (я сам предвычислял $\pi$, готовыми результатами не пользовался). У меня была мысль воспользоваться формулами двойного угла: $(\sin\alpha, \cos\alpha) \to (\sin 2\alpha, \cos 2\alpha)$, но я её не довёл до логического завершения. Поскольку в моей библиотеке максимальное представимое число было $10^{10^8}$, то аргумент функции $e^x$ был ограничен сравнительно небольшим значением. С остальными функциями ещё проще, тут уже написали.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 08:39 
Заслуженный участник


11/05/08
32166
mihaild в сообщении #1531606 писал(а):
Для логарифма иногда можно написать $x = \frac{1 - y}{1 + y}$ и вместо $\ln x$ считать $\ln(1 \pm y)$.

Только непонятно, зачем. Число в машине хранится как комбинация двоичного порядка и мантиссы, причём мантисса нормализована.
Благодаря нормализации двоичный логарифм мантиссы эффективно считается, скажем, чебышёвским приближением, после чего надо просто извлечь порядок из соответствующего поля и прибавить.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 11:23 
Заслуженный участник


12/08/10
1677

(Оффтоп)

Чую программирование 1-2 курса мехмата МГУ. :-)
Если мне память не изменяет, придется писать длинную арифметику и делить на $2\pi$ столбиком. Типа $1000000000$ вполне себе точное число и синус должен считаться с любой требуемой точностью доступной в типе double(C/C++). Преподу надо сказать что погрешность результата не ниже погрешности исходного числа в типе double. То есть если $\varepsilon$ - машинный эпсилон, то посчитать $\sin(x)$ с точностью меньше $\max(\varepsilon x,\varepsilon)$ не получиться(не требуется). Если $x>1/\varepsilon$ выдаем ноль, типа точнее не возможно.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 12:39 


14/01/11
3040
Null в сообщении #1531634 писал(а):
делить на $2\pi$ столбиком

Боюсь, если требуется считать быстро, столбик - не самый эффективный метод. Обычно деление заменяется умножением, а методы быстрого умножения известны.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 12:52 
Заслуженный участник


12/08/10
1677
Sender в сообщении #1531639 писал(а):
Боюсь, если требуется считать быстро, столбик - не самый эффективный метод. Обычно деление заменяется умножением, а методы быстрого умножения известны.
Разрядов там мало для быстрых способов. Но да умножить можно.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 14:08 
Заслуженный участник
Аватара пользователя


11/03/08
9906
Москва
Тейлор для вычисления функций плох. Если только аргумент $\Delta x$ не слишком мал. Да и тогда можно найти получше. Обычно находят способ приведения аргумента в определённый интервал, и ищут наилучшее в этом интервале приближение. Естественным способом приведения для тригонометрических функций является вычитание $ 2\pi n$. Погрешность задания числа Пи здесь, конечно, может сказаться, но только при очень больших n: даже если использовать тип данных float (одинарная точность), существенная ошибка появится, учитывая, что для этого типа в среднем 7.2 десятичных знака, при n порядка сотен тысяч, для наиболее распространённого double при n порядка сотни триллионов (15.9 знака) и для extended (long double), также аппаратно поддерживаемого, это уже должно быть что-то около сотни миллионов миллиардов (19.2 знака). Но если n настолько велико - надо пересматривать алгоритм. Что-то в нём не так. Очевидно приведение для гамма-функции, для экспоненты и логарифма.
Помимо представления в виде полиномов (Чебышева, в частности), могут использоваться дробно-рациональные функции, есть методы вычисления "цифра за цифрой", особенно хорошие для тригонометрических функций.
Могу указать на справочник Вычисление функций на ЭВМ. Попов Б.А., Теслер Г.С. Наукова думка 1984
и более ранний Благовещенского и Теслера.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 15:19 
Заслуженный участник
Аватара пользователя


23/07/05
17976
Москва
Ю. Люк. Специальные математические функции и их аппроксимации. "Мир", Москва, 1980.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение15.09.2021, 16:08 
Заслуженный участник
Аватара пользователя


11/03/08
9906
Москва
Вот ещё можно
Muller J.-M. etc. Handbook of Floating-Point Arithmetic

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение16.09.2021, 15:41 
Заслуженный участник
Аватара пользователя


11/03/08
9906
Москва
Ещё есть
Иванов В.В. Методы вычислений на ЭВМ
К.: Наукова думка, 1986.
Но там вообще численные методы, вычисление функций лишь в одной главе книги.
И по поводу Тейлора. Он вещь не бесполезная, но напрямую для вычисления функций плох. Он "узкий специалист согласно Бернарду Шоу", который "знает всё ни о чём". Даёт наилучшее приближение не только для значения функции, но и всех её производных в точке. А нам надо в отдалении от точки. Можно, например, взяв ряд Тейлора с очень большим числом членов, непрактичным для расчёта, но гарантирующим нужную точность в выбранном интервале, затем его "телескопировать", представив через Чебышева, отбросив члены с совсем уж малыми коэффициентами, и вернувшись к обычным полиномам, но теперь уже равномерное приближение в отрезке.
Или вообще не полиномы, а, скажем, CORDIC. Очень хорош для как раз тригонометрии (гиперболические тоже).
А возвращаясь к "синусу от очень большого аргумента" - вычитание $2\pi$ и вообще приведение замечательно помогает, а значения аргумента, при которых доступная точность числа Пи недостаточна, это либо чистая казуистика, в реальности не бываемая, либо грандиозный прокол в разработке алгоритма. Хотя тут надо посоветовать использовать заложенное в библиотеках значение этой константы с полутора десятками знаков, довольствоваться привычным 3.14 или даже "Это я знаю и помню прекрасно" недостаточно, даже продолжение "пи многие знаки мне лишни-напрасны" может не хватить.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение16.09.2021, 19:52 
Заслуженный участник


11/05/08
32166

(Оффтоп)

Евгений Машеров в сообщении #1531646 писал(а):
extended (long double), также аппаратно поддерживаемого, это уже должно быть что-то около сотни миллионов миллиардов (19.2 знака)

Ньюанец. Не знаю, что такое long double, но extended -- это стандартный десятибайтовый формат внутреннего представления в регистрах процессора (в отличие от выноса double наружу), и хранит он всего лишь 17-18 десятичных цифр.


Да, раз уж пошла такая пьянка. Естественно, универсально оптимальных алгоритмов действительно не бывает. (далее оффтопик)

Вот, скажем, классическая задачка -- как извлечь квадратный корень.

Есть очень древний алгоритм; не помню, какого года и месяца издания -- но по существу это просто (более поздний формально, видимо) метод Ньютона: $x_{k+1}=x_k-\frac1{2x_k}$. И конкретно для этой задачки он оптимален.

Вопрос: а с какого начального приближения начинать?...
Сходится-то он с любого начального приближения; но какое оптимально?...

Почему-то мне только вчера пришла в голову банальная мысль. Надо просто разделить пополам двоичный порядок, мантиссу же усреднить с единицей.

А ещё лучше не усреднить, а просто заменить на единицу, т.к. деление порядка пополам, реализуемое двоичным сдвигом, этот порядок занижает.

Можно ли это дальше оптимизировать? -- сильно вряд ли. Ну допустим, улучшим мы начальное приближение. Максимум, на что можно в данном случае рассчитывать -- это на уменьшение количества итераций примерно на единицу. Т.е. примерно на три арифметические операции. Любая попытка оптимизации займёт заведомо больше.

Да и замена квадратичной скорости сходимости на, допустим, кубическую ситуацию тоже качественно не меняет.

Ну это так, лирика была; прошу пардону.

 Профиль  
                  
 
 Re: Как компьютер вычисляет значение трансцендентных функций?
Сообщение16.09.2021, 22:02 
Заслуженный участник
Аватара пользователя


11/03/08
9906
Москва
long double - употребляемое в некоторых компиляторах название 10-байтного плавающего. Из 80 бит на мантиссу приходится у него 65, что и позволяет заявлять о "19.2 десятичных разрядах". 17-18 это уже "разумная перестраховка".

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: talash, YandexBot [bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group