Обчислити


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!
Однак форма(ex-1)/xне тільки не визначена приx=0, вона також чисельно нестабільна в районі цієї точки; для того, щоб оцінитиf(x)для дуже малогоxчисельно, можна було б використовувати розширення Тейлора, тобто усікання згаданого ряду потужностей.
(ex1)/x=k=1xk1k!
(ex1)/xx=0f(x)x

З : Чи має функція ім'я? Іншими словами, це поширена проблема?f

Питання : Хтось знає про бібліотеку C / C ++, яка гарно поводиться з цією ситуацією, тобто використовує розширення Тейлора відповідного ступеня поблизу 0, а інше представлення від нуля?

Відповіді:



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. |x|<δ1+x/2δdouble2e-85e-4
  3. Справа інша: повернення expm1(x)/x.

З усіченою серією «Тейлор» ви можете бути більш витонченими та окремими справами, але це, мабуть, не варто. Насправді, не зовсім зрозуміло, що випадок 1 потрібно розглядати окремо, оскільки, як вказував k20, скасування є безпечним. Однак поводження з ним окремо дозволило б мені почуватись впевнено.


2

Я пам’ятаю, що це питання було задано раніше на цьому веб-сайті, і дивно, що відповідь полягає в тому, що вам потрібно лише домогтися точної рівності нулю. Помилки скасовуються біля нуля. У мене немає посилання.

Так, ця відповідь була абсолютно помилковою. Я не впевнений, чому це було так схвалено, мабуть, тому, що це було заявлено так авторитетно. Я знайшов посилання, яке я мав на увазі. Це було на математичній зміні stackexhange тут , а не на scicomp stackexchange. expm1-Безкоштовно формула скасування помилки визначається у відповідь по JM і використовує u = exp(x)перетворення.


xdx(edx1)/dx(1+dx1)/dx1

1
dx1+dx=1

0

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


Це цікавий зв’язок, дякую, що вказав на це. На жаль, я вважаю, що потрійна сума зробить це надзвичайно дорогим. Більше того, не відразу зрозуміло, куди обрізати кожну суму, щоб отримати бажану точність.
анонімний

@anonymous: Яку тройну суму ви маєте на увазі? Вам не потрібні поліноми Бернуллі, лише числа Бернуллі, і ви можете перелічити їх заздалегідь. Але так, все одно не бути кращим, ніж серія Тейлора.
Микола-К

Ви можете обчислити їх заздалегідь, якщо зрозуміло, що вам потрібно лише фіксоване кінцеве число лише для будь-якого введення.
анонімний

@anonymous: Ну так, як і ви заздалегідь перерахували коефіцієнти Тейлора.
Микола-К
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.