python - 三重嵌套和 Numpy

标签 python numpy physics

我正在尝试对一个物理问题进行集成,而我编写的代码给了我大约 10 倍的结果。我想知道是否有人可以为我指出正确的方向,无论是我可怕的三重 for 循环还是其他出错的地方。

我正在尝试做这个计算。 ( It's from this paper about calculating the ground state energy of a Lithium atom using Hylleraas co-ordinates if you're interested !! )

这是论文的相关部分,我将在下面解释我是如何分解它的。

First Part of Theory

Second Theory: W integral and T(q) function

长话短说,为了获得积分值,无限和 (5) 在 q 的 10 个值之后被截断。公式 T (q) 在 (6) 中给出,并且是三个值的三重嵌套和本身:k_1_2、k_2_3 和 k_3_1。

这是我的 T(q) 代码:

def T_q(j1, j2, j3, j_1_2, j_2_3, j_3_1, alpha, beta, gamma,q):

    '''
    T_q formula for I integral summation 

    '''
    #print("q", q )
    L_1_2 = 1/2 * (j_1_2 +1) #sets adjusted values of j12 etc.  
    #print(L_1_2, "L12")
    L_2_3 = 1/2 * (j_2_3 +1)
    #print(L_2_3, "l23")
    L_3_1 = 1/2 * (j_3_1 +1)
    #print(L_3_1, "L31")

    j_1 = j1 +2
    j_2 = j2 +2
    j_3 = j3 +2



    t_q = 0


    for k_1_2 in np.arange(L_1_2 + 1):  # Triple for loop for the triple sum 
        #print("k_1_2", k_1_2)
        for k_2_3 in np.arange(L_2_3 + 1):
        #    print("k_2_3", k_2_3)
            for k_3_1 in np.arange(L_3_1 + 1):
            #    print("new loop")
                #print("k_3_1", k_3_1)

                W_mess = (W_integral((j_1 + 2*q + 2*k_1_2 + 2*k_3_1), (j_2 + j_1_2 - 2*k_1_2 + 2*k_2_3), (j_3 + j_2_3 -2*q -2*k_2_3 + j_3_1 - 2*k_3_1),alpha, beta, gamma) +
                W_integral((j_1 + 2*q + 2*k_1_2 + 2*k_3_1), (j_3 + j_3_1 - 2*k_3_1 + 2*k_2_3), (j_2 + j_1_2 -2*q -2*k_1_2 + j_2_3 - 2*k_2_3),alpha, gamma, beta) +
                W_integral((j_2 + 2*q + 2*k_1_2 + 2*k_2_3), (j_1 + j_1_2 - 2*k_1_2 + 2*k_3_1), (j_3 + j_2_3 -2*q -2*k_2_3 + j_3_1 - 2*k_3_1),beta, alpha, gamma) +
                W_integral((j_2 + 2*q + 2*k_1_2 + 2*k_2_3), (j_3 + j_2_3 - 2*k_2_3 + 2*k_3_1), (j_1 + j_1_2 -2*q -2*k_1_2 + j_3_1 - 2*k_3_1),beta, gamma, alpha) +
                W_integral((j_3 + 2*q + 2*k_2_3 + 2*k_3_1), (j_1 + j_3_1 - 2*k_3_1 + 2*k_1_2), (j_2 + j_1_2 -2*q -2*k_1_2 + j_2_3 - 2*k_2_3),gamma, alpha, beta) +
                W_integral((j_3 + 2*q + 2*k_2_3 + 2*k_3_1), (j_2 + j_2_3 - 2*k_2_3 + 2*k_1_2), (j_1 + j_1_2 -2*q -2*k_1_2 + j_3_1 - 2*k_3_1),gamma, beta, alpha))

                t_q +=   (1/((2*q+1)**2)) * C_constant(j_1_2,q,k_1_2) * C_constant(j_2_3,q,k_2_3) * C_constant(j_3_1,q,k_3_1) * W_mess
                #print("t_q, ",t_q)
    #print("t_q final",t_q)
    return t_q


(请原谅打印功能,我正在使用这些功能来尝试确保每次迭代的正确值都在触发-就我所见)

每个都有一个常数值,其公式由(4)给出,我使用这个python函数计算:

def C_constant(j,q,k):

    '''

    Calculates C constant

    '''


    S_q_j = np.minimum( (q-1), (j+1)/2 )  # takes minimum

    constant_term = (2*q+1)/(j+2)

    binomial_term = sc.binom(j+2,(2*k+1))

    product = mp.nprod(lambda t: ((2*k + 2*t -j )/(2*k +2*q - 2*t +1)), [0,S_q_j] )

    numpy_product = np.double(product)
    C = constant_term * binomial_term * numpy_product
    return C


它依赖于资本 pi 乘积、二项式系数和乘积,但相当简单,我无法发现任何错误。

它还依赖于加在一起的大量 W_integrals。我相信它会为输入的任何值计算正确的值:我不太确定正确的值会进入它(因此打印语句)!

这是W代码
def W_integral(l,m,n,alpha,beta,gamma):

    '''
    W integral taken from this paper https://journals.aps.org/pra/abstract/10.1103/PhysRevA.52.3681
    Asks for l m n values + alpha beta gamma  and returns equation (7), in said paper
    Checked against Matlab code
    '''

    constant = np.math.factorial(l)/((alpha +beta +gamma)**(l+m+n+3))
    W_sum  =  mp.nsum(lambda p: ((np.math.factorial(l+m+n+p+2))/((l+m+2+p)*np.math.factorial(l+1+p))  * ((alpha/(alpha +beta +gamma))**p)) *  constant * mp.hyp2f1(1,l+m+n+p+3,l+m+p+3,(alpha+beta)/(alpha +beta +gamma)) ,[0,mp.inf])
    numpy_W= np.double(W_sum)
    return numpy_W

然后将每个 T(q) 值相加以给出此函数中的最终结果:
def I_integral(j1, j2, j3, j_1_2, j_2_3, j_3_1, alpha, beta, gamma):

    '''
    Takes values for power of electron co-ordinates and returns the value of  I "
    '''


    N = 10


    I_0_N =  ((4*np.pi)**3)  * np.array([T_q(j1, j2, j3, j_1_2, j_2_3, j_3_1, alpha, beta, gamma,q) for q in np.arange(N+1)]).sum()
    #print("I_0_N before constant")

    return I_0_N


问题是,目前,与此表相比,我的值 I_integral(0,0,0,-1,-1,1,1,1,1)大约是下表给出的值的 10 倍:
Table of Values: The Relevant Column is the first left one. The value of I(0,0,0,-1,-1,1,1,1,1) converges to ~684, whereas mine gives a value of 5887 !

完成的 T(q) 总和最后乘以 (64*pi^3) (~2000)。当我一直在调查输出时,错误的值似乎是第一个。

Output of the very first iteration

这是因为我的范围错误吗?

我意识到这是一个相当多的问题,但我将非常感谢您的帮助!

最佳答案

您是否尝试过使用一些数值方法,例如欧拉的前向和后向方法?

用欧拉反向方法推导:

让我们考虑 Ts我们的采样时间。然后,导数的近似值是:
dX(t) / dt = [x(t) - x(t-Ts)] / Ts
如果我们将连续时间平面映射到离散时间 z 平面(即 s = e(s * Ts)),我们得到:
dX[k] = [x[k] - x[k-1]] / Ts ,其中 k 是离散时刻。

让我们以以下信号为例:

X = np.linspace(0,100,100000)
y = np.sin(X*0.1)

然后,在 python 中,我们可以构建这样的函数:
def euler_backard_method(X, Ts):
    """
    Computes the Euler's Backwards Method Numerical Derivative.

    Arguments:
        X: an input array
        Ts: the sampling time

    Output:
        the derivative of X
    """
    return [(X[idx]-X[idx-1])/Ts for idx in range(1,len(X))]

对于 Ts = 0.001(高频),我们得到 X ( euler_backard_method(X=y, Ts=1) ) 的以下输出:

衍生示例

image

我们可以以同样的方式构建集成!

集成
  • 转发方法:s <- (z-1) / Ts
  • 反向方法:s <- (z-1) / Ts * z
  • 梯形法:s <- 2 * (z-1) / Ts * (z+1)

  • 向后方法将变为:u[k] = u[k-1] + Ts * x[k] ,其中 u[k]X的综合输出.相应的功能是:
    def backward_integration(X, Ts):
        """
        Numerical Integration using backward method.
    
        Arguments:
            X: the input data
            Ts: the sampling period
    
        Output:
            The derivative of X
        """
        U = []
        u = 0
        for idx in range(len(X)):
            u+=Ts*X[idx]
            U.append(u)
        return U
    

    通知:结果受采样时间的影响很大,正如您指出的那样,您可能会得到大约 10 倍大的导数。

    关于python - 三重嵌套和 Numpy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60602649/

    相关文章:

    python - Qt setStyleSheet 我可以使用哪种字体?

    Python/Numpy - 计算相等数组元素的总和

    python - 对 pandas 数据帧重新采样并插入时间序列数据的缺失值

    java - 有效地计算物体的位置、速度和其他运动导数

    ios - 快速从 ccPhysicsCollisionBegin 返回 bool 时崩溃

    python - 如何将具有 NULL 值的 panda 列转换为 int?

    python - 基本美汤 helper - 格拉斯顿伯里阵容

    python - 在Python中计算二维随机游走的均方位移

    flash - 防止box2d播放器在半空中压在墙上

    python - 使用 Yield 并返回错误列表