Рубрики
Без рубрики

Как вычислить произвольную точность трансцендентальных чисел

Прочитайте оригинал в Kodumaro, подпишитесь на Patreon. Трансцендентные числа, вероятно, самые … Tagged с Python, Math.

Прочитайте оригинал в Kodumaro , подписаться на Patreon Анкет

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

Например, Личность Эйлера считается самой красивой математической формулой (возможно, я собираюсь исследовать ее в будущем):

Он раскрывает связь между двумя наиболее важными трансцендентными числами, комплексными числами, единицей и нулевым/ноль. Он используется в основном в вращении над реальными 𝑣𝑠 воображаемыми осями, на сложных экспоненциальных, корнях и других полезных операциях.

Тем не менее, это бесполезно, если не знает, как получить 𝑒 и π в необходимой точности.

Константа Эйлера

Константа Эйлера или число Эйлера, для краткости, является соотношение, описывающее любой постоянный рост. Это определено как:

Это около 2,71828…. 𝑒 Это своего рода волшебное число, появляющее во многих математических проблемах, предлагая хорошие и простые решения, поскольку комплексные численные операции для логарифма, экспоненциального и других видов роста.

Но как добраться до желаемой точности?

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

К счастью, другой Эйлер Формула дает нам лучшее решение:

Эта формула очень удобна, потому что она повышает точность каждого шага вскоре предсказуемо:

1/0! = 1/1 = 1
1 + 1/1! = 1 + 1/1 = 2
2 + 1/2! = 2 + 1/2 = 2.5
2.5 + 1/3! = 2.5 + 1/6 2.6667
2.6667 + 1/4! 2.6666 + 1/24 2.7083
2.7083 + 1/5! 2.7083 + 1/120 2.7167
2.7167 + 1/6! 2.7177 + 1/720 2.7180
предыдущий + 1/∞! = 𝑒

Это легко предсказуемо, потому что точность равна log₁₀ (n!) :

log₁₀ (0!) = log₁₀ (1) = 0
log₁₀ (1!) = log₁₀ (1) = 0
log₁₀ (2!) = log₁₀ (2) 0.3010
log₁₀ (3!) = log₁₀ (6) 0.7782
log₁₀ (4!) = log₁₀ (24) 1.3802
log₁₀ (5!) = log₁₀ (120) 2.0792
log₁₀ (1000!) 2’567.6046

Это становится большим очень быстро.

Больше повседневного случая

Изображение нужно рассчитать 𝑒 до 80-битной точности. Это не отличается от раньше. Биты представляют собой бинарные цифры, то есть числа 2 базы. Итак, вместо log₁₀ , нужно использовать log₂ :

  • log₂ (n!) ≈ 80
  • 2 log₂ (n!) ≈ 2 80
  • n! ≈ 2⁸⁰
  • 25! <2⁸⁰ <26!
  • 25!
  • 25

Итак, 26 шагов достаточно хороши.

Давайте реализуем это с помощью Python :

from numbers import Integral, Rational
from typing import Callable

# Lazy factorial implementation
fact: Callable[[Integral], Integral] = lambda n: prod(range(1, n+1))

# An LRU cached version, if you prefer:
#
# from functools import lru_cache
#
# fact: Callable[[Integral], Integral] = lambda n: lru_cache(
#     1 if n <= 0 else (n * fact(n - 1))
# )

def steps(prec: Integral) -> Integral:
    res = 1
    while fact(res) >> prec == 0:
        res += 1
    return res

Правый сдвиг ( >> ) возвращает ноль до тех пор, пока значение меньше, чем точность.

Теперь давайте вычислим 𝑒 сам:

compute_e: Callable[[Integral], Rational] = lambda prec: sum(
    1./fact(x) for x in range(prec)
)

Решения, выходящие из этого:

>>> calculate_e(steps(64))  # Python uses 64-bit floats
2.7182818284590455
>>> math.e
2.718281828459045

Совсем неплохо. На самом деле, мы достигаем 64-битной точности с 18 итерациями.

Спектакль

Мы не беспокоимся о производительности здесь, это не сфера действия этого поста. Мы просто показываем, как это работает и как вы можете реализовать и использовать его.

А как насчет π?

π – это отношение периметра любого круга (окружности) к его диаметру. Это очень определение.

Тем не менее, это трансцендентное число и требует вычисленной серии бесконечности. Лейбниц дал нам аккуратное решение:

Процесс совсем тот же, который используется для 𝑒, возьмите формулу:

Затем получите точность:

compute_pi: Callable[[Integral], Rational] = lambda prec: 4. * sum(
    (1./(4*n+1) - 1./(4*n+3)) for n in range(prec)
)

Совет: точность log₂ (4n) , так n PREC-2 , который можно получить с помощью левого переключения. Обратите внимание, что мы получили точно обратный предыдущий расчет: здесь необходимое количество шагов растет очень быстро с небольшим усилением.

Так Вы можете разочароваться при беге:

>>> compute_pi(1 << (64 - 2))

Это вычисление гораздо более неэффективно, чем предыдущий-Python не настолько хорош в работе с операцией с плавающей точкой, и необходимо огромное количество шагов для достижения цели. Я рекомендую 5 метров шагов:

>>> compute_pi(5000000)
3.141592553588895
>>> math.pi
3.141592653589793

Для этой задачи нужно будет понадобиться более жесткий инструмент, как C и многопоточный. Снова производительность не является масштабами этого поста. Вероятно, это требует использования некоторых заклинаний C, чтобы оптимизировать вычисление.

Или вы можете пройти через Wolfram Mathworld’s или Wolfram Alpha’s π -ссылки на страницу в поисках лучшего формула. Я сделал это, и я могу гарантировать, что они есть, включая представления серии.

Резюме

>> это хорошо, << плохо (очень общим и мелким образом).

Оригинал: “https://dev.to/cacilhas/how-to-compute-arbitrary-precision-transcendental-numbers-59lc”