Вычислить

13

Функция имеет особенность вблизи . Эту особенность можно снять, однако: для следует иметь , поскольку И, следовательно, Однако форма не только не определена в , он также численно нестабилен в окрестности этой точки; чтобы оценить для очень малых численно, можно использовать разложение Тейлора, то есть усечение вышеупомянутого степенного ряда.x = 0 x = 1 f ( x ) = 1 e x = k = 0 x kf:x(ex1)/xx=0x=1f(x)=1(ex-1)/x=k=1x k - 1

ex=k=0xkk!
(ex1)/x=k=1xk1k!
(ex1)/xx=0f(x)x

Q : у функции есть имя? Другими словами, это общая проблема?е

Q : Кто-нибудь знает библиотеку C / C ++, которая хорошо справляется с этой ситуацией, то есть использует разложение Тейлора соответствующей степени около 0, а другое представление далеко от нуля?

анонимный
источник

Ответы:

19

Возможно, можно начать с функции которая является частью стандарта C99, и точно вычисляет вблизи .еИкспм1еИкс-1Иксзнак равно0

n00b
источник
17

Это пример ошибки отмены. Стандартная библиотека C (начиная с C99) включает функцию, expm1которая позволяет избежать этой проблемы. Если вы используете expm1(x) / xвместо (exp(x) - 1.0) / x, вы не будете испытывать эту проблему (см. График ниже). <code> fabs (expm1 (x) / x - (exp (x) - 1.0) / x) </ code>

Детали и решение этой конкретной проблемы подробно обсуждаются в разделе 1.14.1 Точность и устойчивость численных алгоритмов . Это же решение объясняется также на странице 19 статьи В. Кахана под названием « Насколько бесполезны оценки бездумного округления при вычислении с плавающей запятой?». , Фактическая реализация expm1в библиотеке GNU C отличается от подхода, описанного в ссылках выше, и тщательно документирована в исходном коде .

Хуан М. Белло-Ривас
источник
1
Спасибо, это как раз то, что мне нужно! К сожалению, я могу принять только один ответ ...
анонимный
Конечно! Нет проблем :-)
Хуан М. Белло-Ривас
3

Чтобы ответить на ваш первый вопрос, нет, у функции нет имени (по крайней мере, не очень известного).

Как уже упоминалось, лучший способ вычислить функцию - это обработать несколько особых случаев. Вот как любая библиотека будет вычислять функцию.

  1. Случай 0: х = 0, возврат 1.
  2. |Икс|<δ1+Икс/2δdouble2e-85e-4
  3. Случай еще: возврат expm1(x)/x.

Вы можете быть более изощренными и в особом случае иметь больше вещей с усеченными сериями Тейлора, но, вероятно, это того не стоит. На самом деле, не совсем ясно, что дело 1 нужно обрабатывать отдельно, поскольку, как указало k20, отмена является безопасной. Тем не менее, обработка этого отдельно позволила бы мне чувствовать себя более уверенно.

Виктор Лю
источник
2

Я помню этот вопрос, который был задан ранее на этом сайте, и удивительно, что ответ заключается в том, что вам нужно только точное равенство нулю в особых случаях. Ошибки сводятся к нулю. У меня нет ссылки.

Да, этот ответ был совершенно неверным. Я не уверен, почему за это проголосовали так много, вероятно, потому что это было заявлено так авторитетно. Я нашел ссылку, которую я имел в виду. Это было на математике stackexchange здесь , а не на SciComp stackexchange. Формула expm1отмены без ошибок приведена в ответе JM и использует u = exp(x)преобразование.

k20
источник
ИксdИкс(еdИкс-1)/dИкс(1+dИкс-1)/dИкс1
1
dИкс1+dИксзнак равно1
0

Чтобы ответить на первый вопрос и предоставить (вероятно, численно неэффективный) метод для второго, отметим, что это обратная производящая функция чисел Бернулли .

Nikolaj-K
источник
Это интересная связь, спасибо за указание на это. К сожалению, я считаю, что тройная сумма сделает это непомерно дорогим. Более того, не сразу понятно, где обрезать каждую сумму для получения желаемой точности.
Аноним
@anonymous: Какую тройную сумму вы имеете в виду? Вам не нужны полиномы Бернулли, только числа Бернулли, и вы можете перечислить их заранее. Но да, это все же не должно быть лучше, чем серия Тейлор.
Николай-К
Вы можете вычислить их заранее, если ясно, что вам нужно только фиксированное конечное число только для любого ввода.
Аноним
@anonymous: Да, точно так же, как вы бы заранее перечислили коэффициенты Тейлора.
Николай-К