Выполнение интеграла на бесконечности с числами, превышающими 10^1000

Я пытаюсь выполнить интеграл от -бесконечности до бесконечности, используя уравнение, содержащее член, возведенный в степень M. При очень высоких (5000+) значениях M это значение этого члена может превышать 10 ^ 100.

У меня есть программа на Python (3.10), которая работает для M = 1000, но ничего особенного.

import numpy as np
from scipy import integrate, special

def integrand(u, M, Z, r):
    sqrt_r = np.sqrt(r)
    sqrt_term = np.sqrt(2 * (1 - r))
    arg1 = (Z + sqrt_r * u) / sqrt_term
    arg2 = (-Z + sqrt_r * u) / sqrt_term
    erf_term = special.erf(arg1) - special.erf(arg2)
    return np.exp(-u**2 / 2) / np.sqrt(2 * np.pi) * erf_term**M

def evaluate_integral(M, Z, r):
    result, _ = integrate.quad(integrand, -np.inf, np.inf, args=(M, Z, r))
    return 1 / (2**M) * result

# Example usage:
M = 1000
Z = 5
r = 0.6



integral_value = evaluate_integral(M, Z, r)

Я получаю следующую ошибку:

IntegrationWarning: The occurrence of roundoff error is detected, which prevents 
  the requested tolerance from being achieved.  The error may be 
  underestimated.
  result, _ = integrate.quad(integrand, -np.inf, np.inf, args=(M, Z, r))

и результат для Integral_value равен nan.

Есть ли способ выполнить этот интеграл с помощью Python, который был бы удобен, поскольку позволил бы мне включиться в остальную часть моей программы, или мне придется использовать другой инструмент?

Вам придется изменить способ вычислений integrand. Работа с логарифмами может помочь.

user2357112 10.07.2024 01:06

Ничего не меняя, значения функции превышают 1e300. Наверняка что-то не так в формулировке.

Reinderien 10.07.2024 02:48

Кроме того, интеграл от бесконечности на практике гораздо уже. Функция для |u| > 6,5 фактически равно 0.

Reinderien 10.07.2024 02:55

Если значения являются числами с плавающей запятой, «float64» имеет максимальный размер и конечную точность.

hpaulj 10.07.2024 06:06

Рассмотрите возможность аналитического решения, либо на бумаге, либо с помощью Wolfram Alpha или Sympy.

Mad Physicist 10.07.2024 09:29

Подсказка в том, что вы ищете не интеграл, а интеграл/2**M. Поместите это /2 внутрь оскорбительного члена интеграла.

lastchance 10.07.2024 09:31
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
6
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

def integrand_log(u, M: float, Z: float, r: float):
    sqrt_r = np.sqrt(r)
    sqrt_term = np.sqrt(2*(1 - r))
    arg1 = (sqrt_r*u + Z)/sqrt_term
    arg2 = (sqrt_r*u - Z)/sqrt_term
    erf_term = special.erf(arg1) - special.erf(arg2)
    return (
        M*np.log(erf_term)
        - 0.5 * (u**2 + np.log(2 * np.pi))
    )

Это лог-идентичность

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

Ответ принят как подходящий

Нет, ваша единственная проблема в том, что вы взяли множитель 1/2**M за пределы интеграла. Если вы положите его обратно внутрь, у вас будет

(erf_term/2)**M

и это не произойдет, потому что разница двух функций ошибок не может превышать 2, поэтому новый коэффициент в квадратных скобках меньше 1.

Я... Оглядываясь назад, это была самая очевидная вещь на свете. Спасибо.

user107900 10.07.2024 09:44

Другие вопросы по теме