numpy Python效率-矩阵嵌套循环结构

cwxwcias  于 11个月前  发布在  Python
关注(0)|答案(1)|浏览(121)

我是一个Python新手,但已经在MATLAB中编码多年。我一直致力于编码一个特定的问题,它需要多个矩阵的嵌套for循环来解决一系列方程。我知道如何在MATLAB中编码,然后使用chatGPT来帮助转换为Python语法。我使用Spyder接口和Python 3.9。下面显示了这里描述的相关代码,我想了解使这个运行更有效的具体方法。我已经阅读了以前使用itertools对类似问题的回答,但当应用时,它们似乎不起作用。

import numpy as np

R1init=[]
R2init=[]
L1init=[]
L2init=[]
p1init=[]
p2init=[]
m1init=[]
m2init=[]
dVrinit=[]
dVlinit=[]

R1 = np.arange(50, 200.001, 2)
R2 = R1  # Since R1 and R2 are identical
L1 = -1*R1
L2 = np.arange(-50,-300.001,-10)

#converted values to be thousands, assuming this would help with matrix sizes.
dVl = 194329/1000  
dVr = 51936/1000  
dVg = 188384/1000  
DR = 0. 
DB = 0.

m1 = np.abs(dVl / R1) 
m2 = np.abs(dVr / L2)

j1 = 0
j2 = 0

for i in R1:
    for j in R2:
        for k in L1:
            for m in L2:
                for n in m1:
                    for q in m2:
                        p1 = ((j2*(1+q)-q)*m+j+dVr)/i
                        p2 = 1-j2*(1+q)+q-(i/m)*(1-j1*(1+n)+n-p1)+dVg/m
                        dVrchk = (q-(j2*q)-q)*m+(p1*i)-j+DR+DB
                        dVlchk =(j1-n+(j1*n))*i+k-(p2*m)
                        dVgchk = (1-j1-p1+n-j1*n)*i-(1-j2-p2+q-j2*q)*m
                        if 0<p2<1.05 and 0<p1<1.05 and dVl-100<dVlchk<dVl+100 and dVr-  100<dVrchk<dVr+100:
                            R1init.append(i)
                            R2init.append(j)
                            L1init.append(k)
                            L2init.append(m)
                            p1init.append(p1)
                            p2init.append(p2)
                            m1init.append(n)
                            m2init.append(q)
                            dVrinit.append(dVrchk)
                            dVlinit.append(dVlchk)

字符串

fdbelqdn

fdbelqdn1#

我建议使用Numba来加速这个过程,并改变你检查条件的顺序。这足以在一秒钟内解决这个问题。
例如,p1上的条件不涉及变量nk,因此不需要循环遍历这些变量的所有组合来检查它们。
类似地,p2不依赖于k,所以它可以在k循环之外完成。
这确实有一个缺点,它改变了解决方案的顺序,但我猜你并不关心它们以什么顺序返回。
这些优化允许在一秒钟内完成。

import numba as nb
from numba.typed import List

@nb.njit()
def search_inner(R1, R2, L1, L2, m1, m2):
    dVl = 194329/1000
    dVr = 51936/1000
    dVg = 188384/1000
    DR = 0. 
    DB = 0.

    R1init = List()
    R2init = List()
    L1init = List()
    L2init = List()
    p1init = List()
    p2init = List()
    m1init = List()
    m2init = List()
    dVrinit = List()
    dVlinit = List()
    j1 = 0
    j2 = 0

    for i in R1:
        for j in R2:
            for q in m2:
                for m in L2:
                    # i j q m
                    p1 = ((j2*(1+q)-q)*m+j+dVr)/i
                    if not (0 < p1 < 1.05):
                        continue
                    for n in m1:
                        # q i m n p1
                        p2 = 1-j2*(1+q)+q-(i/m)*(1-j1*(1+n)+n-p1)+dVg/m
                        if not (0 < p2 < 1.05):
                            continue
                        for k in L1:
                            # i j q m p1
                            dVrchk = (q-(j2*q)-q)*m+(p1*i)-j+DR+DB
                            if not (dVr - 100 < dVrchk < dVr + 100):
                                continue
                            # n i k m p2
                            dVlchk =(j1-n+(j1*n))*i+k-(p2*m)
                            if not (dVl - 100 < dVlchk < dVl + 100):
                                continue
                            dVgchk = (1-j1-p1+n-j1*n)*i-(1-j2-p2+q-j2*q)*m
                            # dVgchk is ignored here - Bug?
                            R1init.append(i)
                            R2init.append(j)
                            L1init.append(k)
                            L2init.append(m)
                            p1init.append(p1)
                            p2init.append(p2)
                            m1init.append(n)
                            m2init.append(q)
                            dVrinit.append(dVrchk)
                            dVlinit.append(dVlchk)

    ret = {
        'R1init': R1init,
        'R2init': R2init,
        'L1init': L1init,
        'L2init': L2init,
        'p1init': p1init,
        'p2init': p2init,
        'm1init': m1init,
        'm2init': m2init,
        'dVrinit': dVrinit,
        'dVlinit': dVlinit,
    }
    return ret
def search():
    #converted values to be thousands, assuming this would help with matrix sizes.
    dVl = 194329/1000
    dVr = 51936/1000

    R1 = np.arange(50, 200.001, 2)
    R2 = R1  # Since R1 and R2 are identical
    L1 = -1*R1
    L2 = np.arange(-50,-300.001,-10)

    m1 = np.abs(dVl / R1)
    m2 = np.abs(dVr / L2)

    ret = search_inner(R1, R2, L1, L2, m1, m2)
    # Unwrap typed lists into arrays
    ret = {k: np.array(v, dtype='float64') for k, v in ret.items()}
    return ret

字符串

相关问题