Является ли реализация функции exp() с плавающей запятой эквивалентной расширению усеченного ряда Тейлора?

Является ли реализация функции exp() с плавающей запятой в cmath эквивалентной усеченному расширению ряда Тейлора очень высокого порядка? Один из возможных источников ошибки, о котором следует помнить, — это конечность числа битов для представления ответа.


person Tarek    schedule 09.09.2012    source источник
comment
Это крайне маловероятно. Существуют гораздо лучшие практические алгоритмы для аппаратных арифметических устройств (а также для программных реализаций), которые сходятся гораздо быстрее. Обычно они довольно неясны, очень изящны и не очень широко известны среди чистых математиков.   -  person Kerrek SB    schedule 09.09.2012
comment
Хотя ряды Тейлора теоретически работают, расширение ряда может привести к значительной потере точности.   -  person    schedule 09.09.2012


Ответы (4)


Является ли реализация функции exp() с плавающей запятой в cmath эквивалентной усеченному расширению ряда Тейлора очень высокого порядка?

Эквивалент? Да. Это потому, что любая приличная реализация exp() имеет ошибку в половину ULP (единица наименьшей точности) или около того. Игнорируя проблемы с арифметикой конечной точности, всегда можно построить усеченный ряд Тейлора, который делает то же самое.

Однако никакая приличная реализация exp() не будет использовать расширение Тейлора. Это было бы очень-очень медленно и не достигло бы желаемой точности. Это была бы откровенно глупая реализация. Гораздо лучше использовать тот факт, что существует сильная связь между 2x и ex, а также тот факт, что 2x довольно легко вычислить. вычислить, учитывая почти универсальную мощность 2 представления чисел с плавающей запятой.

person David Hammen    schedule 09.09.2012

Это зависит от реализации компилятора, среды выполнения C и процессора. Однако тот, кто вычисляет показатель степени, вряд ли будет использовать разложение Тейлора, поскольку существуют лучшие методы.

Согласно glibc, он может использовать свою собственную реализацию, которая говорит об этом в комментарии (из sysdeps/ieee754/dbl-64/e_exp.c):

/* An ultimate exp routine. Given an IEEE double machine number x          */
/* it computes the correctly rounded (to nearest) value of e^x             */

Или он может использовать аппаратно поддерживаемые инструкции процессора для вычислений с плавающей запятой, как в x86 FPU. В обоих случаях вы, вероятно, получите правильно округленное значение с полной точностью.

person Yakov Galka    schedule 09.09.2012

Просто пример того, как вы можете рассчитать exp (x):

Если x достаточно велико, результатом будет +inf. Если x достаточно мал, то результат равен 0.

Пусть k = округлое (x/ln 2). Тогда exp (x) = 2^k * exp (x - k ln 2). 2^k очень легко вычислить. Небольшая проблема состоит в том, чтобы вычислить x - k ln 2 без какой-либо ошибки округления. Это довольно просто: пусть L1 = ln 2 округляется до 35 бит, а L2 = ln 2 - L1. k — небольшое целое число, поэтому k * L1 не имеет ошибки округления, равно как и x — k * L1; затем мы вычитаем k * L2, что мало и, следовательно, имеет небольшую ошибку округления.

Чтобы сделать это быстрее (без деления), вычисляем k = round(x * (1/ln 2)). И мы проверяем, близко ли x к нулю, так что весь расчет не нужен. В любом случае, теперь мы вычисляем exp (x), где результат находится между sqrt (1/2) и sqrt (2).

Вы можете вычислить exp (x), используя полином Тейлора. Вместо этого вы, вероятно, использовали бы полином Чебычева, минимизирующий ошибку отсечки с гораздо более низкой степенью. С некоторой осторожностью вы можете найти многочлен с ошибкой отсечения, существенно меньшей, чем младший бит результата.

person gnasher729    schedule 09.04.2014

Это зависит от того, какую реализацию библиотеки C вы используете. В очень популярном glibc это не так.

person Community    schedule 09.09.2012
comment
Я использую компилятор Intel. Какой алгоритм используется в glibc для вычисления exp()? - person Tarek; 09.09.2012
comment
@Tarek Я точно не знаю, что это такое, что-то связанное с магическими константами, но почему бы не увидеть это самому? - person ; 09.09.2012
comment
@Tarek: я тоже не знаю, но гораздо лучшим методом, чем расширение Тейлора, было бы использование Hermite на конечном интервале с использованием предварительно вычисленных констант и использовать экспоненциальный формат числа с плавающей запятой, чтобы свести задачу к этому конечному интервалу. - person Yakov Galka; 09.09.2012