Нахождение 4-мерного минимума (a, b, c, d) интеграла от функции I (a, b, c, d) - PullRequest
0 голосов
/ 21 февраля 2012

У меня неприятный прерывистый 2-мерный интеграл I(k,k''; J,Jp,a,b,c,d), который имеет 4 вариационных параметра (a,b,c,d) и 2 фиксированных константы (J,Jp). Процедура нахождения интеграла не проста и имеет первый шаг.

  1. Мне нужно найти корень (mu) для одномерного интеграла от -pi до pi

    A = Integrate [ 1/(exp(E(k; a,b,c,d)-mu)+1 ] dk/2pi = 0.5

    , где E - сложная функция, состоящая из квадратных корней и косинусов.

  2. Найдя mu, мне нужно найти 4D (глобальные) минимальные значения (a,b,c,d) для этого двумерного интеграла (с теми же пределами от 1022 * до pi) с J, Jp .

    result(J,Jp) = Minimum[ Integrate [ I(J,Jp;k,k''; a,b,c,d,mu) ] dk/2pi dk''/2pi ]

Сложная функция I в основном выглядит как

I(J,Jp;k,k''; a,b,c,d,mu) = A(k)*A(k'')*f(a,b,c,d)*[J cos(k+k'') + Jp cos(k-k'')]

Я сделал первый шаг к нахождению mu с предполагаемыми значениями a,b,c,d, но не уверен, как поступить с произвольными значениями из них. Есть ли другой способ, кроме вложенности всех лямбда-функций? Тем не менее, как мне вложить лямбда-функции для выполнения того, что мне нужно?

beta=100.0
a=1.2
b=1.5
c=0.1
d=0.5
findmu = lambda mu: integrate.quad(lambda k:1.0/(2.0*pi)*1.0/(exp(beta*(0.5*(c+d-2.0*(1.0+b)*cos(k)-sqrt(32.0*(b*cos(k/2.0))**2.0+(c-d-2.0*(1-b)*cos(k))**2.0))-mu))+1.0)-0.5/(2.0*pi), -pi,pi)
mu0 = optimize.fsolve(findmu,0.0)

У меня есть процедура, написанная в Mathematica, но она занимает слишком много времени, чтобы получить минимум, а иногда и ошибочна. Я хотел бы попробовать перенести его на Python, который я сейчас изучаю. Спасибо!

РЕДАКТИРОВАТЬ: Больше информации о физической системе: Первый шаг - это найти уровень Ферми квантовой системы, наложив заполнение системы. На уровне Ферми можно найти, какие вариационные параметры минимизируют энергию основного состояния этой системы Хартри-Фока.

1 Ответ

0 голосов
/ 21 февраля 2012

Я вообще не смотрел на ваше уравнение, но могу дать вам информацию о том, как вкладывать лямбды.Вы можете просто добавить lambda a, b, c, d: в начало вашей текущей лямбды, тогда findmu(a, b, c, d) вернет функцию, которую вы передадите в optimize.fsolve(), например:

beta=100.0
findmu = lambda a, b, c, d: lambda mu: integrate.quad(lambda k:1.0/(2.0*pi)*1.0/(exp(beta*(0.5*(c+d-2.0*(1.0+b)*cos(k)-sqrt(32.0*(b*cos(k/2.0))**2.0+(c-d-2.0*(1-b)*cos(k))**2.0))-mu))+1.0)-0.5/(2.0*pi), -pi,pi)
mu0 = optimize.fsolve(findmu(1.2, 1.5, 0.1, 0.5),0.0)
# now just tweak the values for the arguments to findmu in subsequent calls

Это закрытие длязначения a, b, c и d, которые вы передаете в findmu(), может иметь смысл переименовать findmu в make_findmu или что-то подобное.

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

def make_findmu(a, b, c, d):
    beta = 100.0
    return lambda mu: integrate.quad(lambda k:1.0/(2.0*pi)*1.0/(exp(beta*(0.5*(c+d-2.0*(1.0+b)*cos(k)-sqrt(32.0*(b*cos(k/2.0))**2.0+(c-d-2.0*(1-b)*cos(k))**2.0))-mu))+1.0)-0.5/(2.0*pi), -pi,pi)

mu0 = optimize.fsolve(make_findmu(1.2, 1.5, 0.1, 0.5),0.0)
...