#python #math #scipy #integral #mismatch
#python #математика #scipy #интеграл #несоответствие
Вопрос:
Первая функция в приведенном ниже коде использует двойное интегрирование с scipy.integrate.dblquad
для вычисления дифференциальной энтропии, c*np.log(c)
, функции плотности связки c
, которая имеет один параметр зависимости, theta
, обычно положительный.
Вторая функция в приведенном ниже коде пытается решить ту же проблему, что и выше, но с использованием решателя с несколькими интегралами scipy.integrate.nquad
from scipy import integrate
import numpy as np
def dblquad_(theta):
"Double integration"
c = lambda v, u: ((1 theta)*(u*v)**(-1-theta)) * (u**(-theta) v**(-theta)-1)**(-1/theta-2)
return -integrate.dblquad(
lambda u,v: c(v,u)*np.log(c(v,u)),
0, 1, lambda u: 0, lambda u: 1
)[0]
def nquad_(n,theta):
"Multiple integration"
c = lambda *us: ((1 theta)*np.prod(us)**(-1-theta)) * (np.sum(np.power(us,-theta))-1)**(-1/theta-2)
return -integrate.nquad(
func = lambda *us : c(*us)*np.log(c(*us)),
ranges = [(0,1) for i in range(n)],
args = (theta,)
)[0]
n=2
theta = 1
print(dblquad_(theta))
print(nquad_(n,theta))
Функция на dblquad
основе выдает ответ -0.7127
, в то время nquad
как выдает -0.5823
и заметно занимает больше времени. Почему решения разные, хотя я установил оба для решения n=2
многомерной задачи?
Ответ №1:
С n
theta
учетом предоставленных вами значений и выходных данных вашего кода:
-0.1931471805597395
0.17055845832017144,
не -0.7127
» и -0.5823
» .
Первое значение ( -0.1931471805597395
) является правильным (вы можете проверить это здесь сами).
Проблема nquad_
заключается в обработке theta
параметра. Спасибо @mikuszefski за объяснение; Я копирую его здесь для ясности:
nquad
переходитlambda
к функции по мере необходимости. Лямбда-выражение запрограммировано таким образом, что оно принимает произвольное количество аргументов, поэтому оно с радостью принимает его и помещает в список степеней и сумм. Следовательно, вы не получаете, например1/u**t 1/v**t -1
, но1/u**t 1/v**t 1/t**t -1
. Вызов функции просто не соответствует предполагаемому использованию функции. Если вы вместо этого напишетеus[0]**() us[1]**() - 1
, это сработает.
Вот измененный код:
from scipy import integrate
import numpy as np
def dblquad_(theta):
"Double integration"
c = lambda v, u: ((1 theta)*(u*v)**(-1-theta)) * (u**(-theta) v**(-theta)-1)**(-1/theta-2)
return -integrate.dblquad(
lambda u,v: c(v,u)*np.log(c(v,u)),
0, 1, lambda u: 0, lambda u: 1
)[0]
def nquad_(n,theta):
"Multiple integration"
c = lambda *us: ((1 theta)*np.prod((us[0], us[1]))**(-1-theta)) * (np.sum(np.power((us[0], us[1]),-theta))-1)**(-1/theta-2)
return -integrate.nquad(
func = lambda *us : c(*us)*np.log(c(*us)),
ranges = [(0,1) for i in range(n)],
args=(theta,)
)[0]
n=2
theta = 1
print(dblquad_(theta))
print(nquad_(n,theta))
Выходной сигнал:
-0.1931471805597395
-0.1931471805597395
Комментарии:
1. Учитывая, что вы обнаружили, что существует определенное решение для двойного интеграла с использованием параметрического ввода
c(theta)
, не могли бы вы сказать, что это указывает на то, что решение в закрытой форме может быть получено для показанной математической формулы?2. Кстати, параметр
theta
не используется неправильно.nquad
передает его в функцию по мере необходимости. Онlambda
запрограммирован таким образом, что принимает произвольное количество аргументов, поэтому с радостью принимает его и помещает в список степеней и сумм. Следовательно, вы не получаете, например1/u**t 1/v**t -1
, но1/u**t 1/v**t 1/t**t -1
. Вызов функции просто не соответствует предполагаемому использованию функции. Если вы вместо этого напишетеus[0]**() us[1]**() - 1
, это сработает.3. @develarist интеграл от
c(u,v)
на самом деле имеет замкнутую форму.c * log c
скорее всего, нет.4. в какой статье вы видели
c
решение в закрытой форме для его интеграла?5. математически, почему
nquad_(n=3,theta)
дает точно такое же решение, что и двумерная связкаnquad_(n=2,theta)
, при этом вычисление занимает в два раза больше времени? Разве на многомерные связки не должен по-разному влиять один и тот же уровеньtheta
? Если нет, означает ли это, что решение для двумерных связок уже даст мне результаты связки более высокого размера?