Matplotlib не будет оживлять функцию - PullRequest
0 голосов
/ 11 ноября 2018

Я пытаюсь сделать анимацию следующей волновой функции:

Wavefunction

По какой-то причине мой код работает для n = 0, но не для других n. Я проверил значения функции для различных n, x и t, и она, кажется, работает нормально, но по какой-то причине matplotlib не анимирует. Вот код:

%matplotlib qt

import numpy as np
from sympy import hermite
from scipy.special import gamma
import matplotlib.pyplot as plt
from matplotlib import animation


def psi(n, x, t):
    A = (np.pi ** -0.25) * (1 / np.sqrt((2 ** n) * gamma(n + 1)))
    E = n + 0.5
    f = A * hermite(n, x) * np.exp(-(x ** 2) / 2) * np.cos(E * t)
    return f


def animar(f, x0=0, xf=1, dx=0.01, t0=0, tf=1, dt=0.01, ym=-2, yM=2):
    nf = int((xf - x0) / dx + 1)
    nt = int((tf - t0) / dt + 1)
    x = np.linspace(x0, xf, nf)
    t = np.linspace(t0, tf, nt)

    fig, ax = plt.subplots()

    ax.set_xlim((x0, xf))
    ax.set_ylim((ym, yM))

    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return line,

    def animate(i):
        y = f(x, i)
        line.set_data(x, y)
        return line,

    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=5 * t, interval=20, blit=True)
    plt.show()
    return anim


F = lambda x,t: psi(1, x, t)
anim = animar(F, x0=-3, xf=3, tf=3, ym=-1, yM=1)

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Не думаю, что вы хотите символически оценивать полиномы Эрмита. Вместо этого, почему бы не использовать numpy.polynomial.hermite.hermval? Также возможно использовать scipy.special.factorial для расчета факториала.

import numpy as np
from numpy.polynomial.hermite import hermval
from scipy.special import factorial
import matplotlib.pyplot as plt
from matplotlib import animation


def psi(n, x, t):
    A = (np.pi ** -0.25) * (1 / np.sqrt((2 ** n) * factorial(n)))
    E = n + 0.5
    nar = np.zeros(n+1)
    nar[-1] = 1
    f = A * hermval(x,nar) * np.exp(-(x ** 2) / 2) * np.cos(E * t)
    return f


def animar(f, x0=0, xf=1, dx=0.01, t0=0, tf=1, dt=0.01, ym=-2, yM=2):
    nf = int((xf - x0) / dx + 1)
    nt = int((tf - t0) / dt + 1)
    x = np.linspace(x0, xf, nf)
    t = np.linspace(t0, tf, nt)

    fig, ax = plt.subplots()

    ax.set_xlim((x0, xf))
    ax.set_ylim((ym, yM))

    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return line,

    def animate(i):
        y = f(x, i)
        line.set_data(x, y)
        return line,

    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=5 * t, interval=20, blit=True)
    plt.show()
    return anim


F = lambda x,t: psi(3, x, t)
anim = animar(F, x0=-3, xf=3, tf=3, ym=-1, yM=1)
0 голосов
/ 11 ноября 2018

Вот исправление. Переопределите вашу psi функцию так:

def psi(n, x, t):
    A = (np.pi ** -0.25) * (1 / np.sqrt((2 ** n) * gamma(n + 1)))
    E = n + 0.5
    herms = np.array([hermite(n, xelem) for xelem in x])
    f = A * herms * np.exp(-(x ** 2) / 2) * np.cos(E * t)
    return f

По сути, hermite кажется немного странным / глючным. Если x, если массив NumPy, то hermite(n=0, x) работает просто отлично. Однако, если n>0, то hermite будет горько жаловаться, если x - это что-то отличное от одного значения. Таким образом, мы обходим это путем ввода значений от x до hermite по одному, а затем создаем массив herms из этих результатов.

Квантовая механика появилась много лет назад, поэтому я не могу сказать вам, есть ли обоснованная причина для несогласованности hermite в отношении входных данных массива. Я предполагаю, что это просто слегка ошибочная реализация в sympy. В любом случае, как только вы исправите эти две строки в psi, анимация, кажется, будет работать нормально.

...