首页 文章

在2D阵列上的三个嵌套循环

提问于
浏览
0

我有一个2D数组,它基本上代表一个函数 F ,它取决于两个变量: F(V,T) .

F(V,T) is a 2D array, represented as F_VT:
F_VT   = [[F(V1), F(V2), F3(V3), ..., F(V11)], -> values for T1
          [F(V1), F(V2), F(V3)], ..., F(V11)], -> values for T2

          ...
          [F(V1), F(V2), F(V3)], ..., F(V11)] -> values for T4

V is a 1D array, V = [V1, V2, V3 ... V11]
T is a 1D array, T = [T1, T2, T3, T4]
P is a 1D array, P = [P1, P2, P3, P4]

对于给定的 F(V,T) ,可以计算新函数 Fb(V,T)

Fb(V,T) = F(V,T) + P*V

对于T和P的固定值,我想绘制Fb,并整理出Fb达到最小值的V坐标 . 例如对于那个固定的T和P,Fb在V = ......时达到最小值

我推出了以下三个嵌套循环:

for index_T, Ts in enumerate(T):
 for Ps in P:
  aux_P = []
  for Vs in V:
    Fb_VT = F_VT[index_T][:] + (2.293710449E+17)*(1E-21) * Ps * Vs

    p1 = plt.scatter(V, Fb_VT, color='red', marker="^", s=100)

    plt.pause(0.05)

但是曲线没有考虑 P 上的循环 . 任何帮助深表感谢 .

码:

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

F_VT = [np.array([-941.57370763, -941.57401198, -941.57415914, -941.5741743 ,
       -941.57418547, -941.57409029, -941.57384471, -941.57349143,
       -941.57299666, -941.57242367, -941.57172351]), np.array([-941.59428621, -941.59452901, -941.59467455, -941.59470002,
       -941.59475968, -941.59472847, -941.59457033, -941.59432064,
       -941.5939331 , -941.59347988, -941.59293092]), np.array([-941.64179308, -941.64203825, -941.64223508, -941.642278  ,
       -941.64245276, -941.64254897, -941.6425414 , -941.64245835,
       -941.64223967, -941.64196782, -941.641634  ]), np.array([-941.70391106, -941.70416543, -941.70441939, -941.70448022,
       -941.70477693, -941.70500704, -941.70515626, -941.70524589,
       -941.70520195, -941.70511723, -941.70500381])]

V = np.array([ 60.208589,   60.8721745,  61.4382305,  61.515143,   62.2128025,  62.888581,
               63.567809,   64.250832,   64.937775,   65.6287725,  66.3238705])

T = np.linspace(10.00, 2000.00, 4)
P = np.linspace(1., 10., 4)

plt.figure()

for index_T, Ts in enumerate(T):
    for Ps in P:
        aux_P = []
        for Vs in V:
            Fb_VT = F_VT[index_T][:] + (2.293710449E+17)*(1E-21) * Ps * Vs

            p1 = plt.scatter(V, Fb_VT, color='red', marker="^", label='Calcite I', s=100)
            plt.pause(0.05)


plt.show()

1 回答

  • 0

    你有数学问题

    你没有代码问题,你有数学问题 . 您可以使用以下数组操作获取完整的 P*V 值集:

    ((2.293710449E+17)*(1E-21) * P * V[:,None]).reshape(-1)
    

    输出:

    [0.01381011 0.05524043 0.09667075 0.13810107 0.01396231 0.05584926
     0.0977362  0.13962314 0.01409215 0.0563686  0.09864506 0.14092151
     0.01410979 0.05643917 0.09876855 0.14109793 0.01426982 0.05707926
     0.09988871 0.14269816 0.01442482 0.05769928 0.10097374 0.1442482
     0.01458061 0.05832246 0.1020643  0.14580615 0.01473728 0.05894912
     0.10316096 0.1473728  0.01489485 0.05957938 0.10426392 0.14894845
     0.01505334 0.06021336 0.10537338 0.1505334  0.01521278 0.0608511
     0.10648943 0.15212775]
    

    注意所有这些值有多小 . 现在将它们与 F_VT 中的值进行比较 . P * V 的值实际上大约比 F_VT 中的值小4个数量级 . 这是有道理的,因为您将所有 P * V 值乘以 1e-4 的常量因子 .

    我唯一能建议的是增加你的 VP 值 . 也许像 P = np.linspace(1, 1000, 4)

    通过矢量化删除循环并加速代码

    这基本上与代码中的实际问题无关,但是您可以通过使用两个向量化操作替换三重循环来加快速度:

    import numpy as np
    from scipy.optimize import curve_fit
    import matplotlib.pyplot as plt
    
    F_VT = np.array([[-941.57370763, -941.57401198, -941.57415914, -941.5741743 , -941.57418547, -941.57409029, -941.57384471, -941.57349143, -941.57299666, -941.57242367, -941.57172351], 
                     [-941.59428621, -941.59452901, -941.59467455, -941.59470002, -941.59475968, -941.59472847, -941.59457033, -941.59432064, -941.5939331 , -941.59347988, -941.59293092], 
                     [-941.64179308, -941.64203825, -941.64223508, -941.642278  , -941.64245276, -941.64254897, -941.6425414 , -941.64245835, -941.64223967, -941.64196782, -941.641634  ], 
                     [-941.70391106, -941.70416543, -941.70441939, -941.70448022, -941.70477693, -941.70500704, -941.70515626, -941.70524589, -941.70520195, -941.70511723, -941.70500381]])
    
    V = np.array([ 60.208589,   60.8721745,  61.4382305,  61.515143,   62.2128025,  62.888581, 63.567809,   64.250832,   64.937775,   65.6287725,  66.3238705])
    
    T = np.linspace(10.00, 2000.00, 4)
    P = np.linspace(1., 10., 4)
    
    fig = plt.figure()
    ax = fig.gca()
    
    PV = ((2.293710449E+17)*(1E-21) * P * V[:,None]).reshape(-1)
    Fb_VT = (F_VT[..., None, :] + PV[None, ..., None]).reshape(-1, F_VT.shape[1])
    
    # looping over the rows of Fb_VT will give results equivalent to the triple loop in the old code
    for fbvt in Fb_VT:
        ax.scatter(V, fbvt, color='red', marker="^", label='Calcite I', s=100)
    
    fig.show()
    

    这将产生与旧代码相同的输出(尽管为了简洁起见,我已经在单个数字上绘制了所有输出):

相关问题