You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

相同Python代码、机器与数据运行结果不一致的技术求助

曲线拟合结果不一致问题求助

我编写了一段基于numpy和math库的Python代码,用于读取文本文件中的多列数据并执行曲线拟合。首次运行该代码时,机器同时在运行另一段Python分析代码,得到了一组结果;再次单独运行时,结果却差异巨大。为验证结果正确性,我在MATLAB中重复计算,成功复现了Python第二次运行的结果。恳请各位提供导致该问题的原因线索,如需测试我可私下分享数据与代码。

代码实现

import  pandas  as  pd
import  numpy   as  np
import  typing  as  tp
import  math    as  mt
import  matplotlib.pyplot as plt

def curveFitting(energyData: tp.Dict[float, float], order: int) -> None:
    pesDataFrame    =   pd.DataFrame(columns = ["Distance", "Energy"])
    for key in energyData:
        pesDataFrame.loc[len(pesDataFrame)] = [key, energyData[key]]    #   Create a DataFrame to drop all energy values above 0 cm-1
    pesDataFrame    =   pesDataFrame[pesDataFrame["Energy"] <= 0]        #   Drop all energies greater than 0 cm-1
#    pesDataFrame    =   pesDataFrame[pesDataFrame["Distance"] > 1.4]
    distances       =   pesDataFrame["Distance"].to_numpy()
    energies        =   pesDataFrame["Energy"].to_numpy()
    rEquilibrium    =   distances[energies.argmin()]
    
    distances       =   np.delete(distances, energies.argmin())
    energies        =   np.delete(energies, energies.argmin())
    xRvalues        =   np.zeros(distances.size)
    print(rEquilibrium)

    for index, value in enumerate(distances):
        xRvalues[index] =   (pow(value, 3) - pow(rEquilibrium, 3)) / (pow(value, 3) + pow(rEquilibrium, 3)) # Calculate x(r) values according to Eq 14

    xMatrix         =   np.zeros((distances.size, order+1))
    for row, value in enumerate(xRvalues):
        for ordercount in range(0, order+1):
            xMatrix[row][ordercount] = pow(value, ordercount)           #   Calculate xMatrix according to Eq 19
    print(xMatrix.shape)
    
#    term1           =   np.zeros(distances.size)
    term2           =   np.zeros(distances.size)
    rescaledEnergy  =   np.zeros(distances.size)
    minEnergy       =   energies[energies.argmin()]
    dissocEnergy    =   0 - minEnergy               #   Calculate dissociation energy as difference between minimum and zero energy.
    for index, value in enumerate(energies):
        rescaledEnergy[index]   =   (value - minEnergy) / dissocEnergy
   
    for index, value in enumerate(distances):
#        term1[index]            =   np.emath.log(1 - mt.sqrt(rescaledEnergy[index]))    #   Eq 11
        term2[index]            =   np.emath.log(1 - mt.sqrt(rescaledEnergy[index]))    #   Eq 12
        
#        term1[index]            =   term1[index] / (rEquilibrium - value)
        term2[index]            =   term2[index] / (rEquilibrium - value)

    # First calculate beta from Eq 11
    beta, _, _, _   =   np.linalg.lstsq(xMatrix, term2, rcond = None)
    print(beta.shape)

    calculateBetas  =   np.dot(xMatrix, beta)
    errorVector     =   term2 - calculateBetas
    print(np.linalg.norm(errorVector))
#    calculateBetas      =   np.zeros(distances.shape)
#    for row in range(xMatrix.shape[0]):
#        calculateBetas[row] =   np.dot(xMatrix[row], beta)

    calculateEnergies1  =   np.zeros(distances.shape)
#    errorVector         =   np.zeros(distances.shape)

    for index, value in enumerate(distances):
        distance    =   value - rEquilibrium
        betaterm    =   mt.exp(-1*calculateBetas[index]*distance)
        nextterm    =   pow(1-betaterm, 2) * dissocEnergy
        calculateEnergies1[index]   =   nextterm + minEnergy
#        errorVector[index]          =   energies[index] - calculateEnergies1[index]
    error   =   np.linalg.norm(errorVector)
    plt.plot(distances, energies, "-r", label = "UCCSD(T) Energy")
    plt.plot(distances, calculateEnergies1, "-b", label = "Fitted Energies")
    plt.title("Fitting Order : {} and Error : {:10.5f}".format(order, error))
    plt.xlabel("Interatomic Distance")
    plt.ylabel("Energy (cm-1)")
    plt.legend()
    plt.savefig("uccsdt_fitting_order_{}.png".format(order), dpi = 600)

with open("energies_neutral_631g.dat") as energyFile:
    uhfEnergy       =   {}
    uccsdEnergy     =   {}
    uccsdtEnergy    =   {}

    for line in energyFile:
        line    =   line.split()
        dist    =   float(line[0])  #   Distance
        uhf     =   float(line[1])  #   UHF Energy
        uccsd   =   float(line[2])  #   UCCSD Energy
        uccsdt  =   float(line[3])  #   UCCSD Energy with UCCSD(T) corrections
        uhfEnergy[dist]     =   uhf
        uccsdEnergy[dist]   =   uccsd
        uccsdtEnergy[dist]  =   uccsdt

for order in range(0,20):
    curveFitting(energyData = uccsdtEnergy, order = order)
    plt.clf()  

可能的原因线索

  • 字典遍历顺序不稳定:Python 3.7之前的字典不保证遍历顺序固定,你通过for key in energyData生成DataFrame时,不同运行场景下(比如系统负载波动)可能导致DataFrame的行顺序变化。后续删除能量最小值对应的索引、构建拟合矩阵等步骤都会受此影响,最终引发拟合结果的巨大差异。
  • 资源竞争引发计算异常:首次运行时机器同时执行其他分析代码,可能出现内存不足、CPU调度异常,导致numpy的最小二乘计算(np.linalg.lstsq)出现精度丢失或计算偏差,比如浮点数运算的中间结果被干扰。
  • 拟合逻辑对数据顺序敏感:代码中涉及多次幂运算、对数运算、除法操作,这些步骤对输入数据的顺序和微小数值变化高度敏感。一旦数据顺序因字典遍历改变,后续所有计算都会产生连锁反应,最终导致结果偏差显著。

内容的提问来源于stack exchange,提问作者Hemanth Haridas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:55:01