我是 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)
我建议使用 Numba 来加快速度,并更改检查条件的顺序。这足以在一秒钟内解决此问题。
例如,您对
p1
的条件不涉及变量 n
或 k
,因此您无需循环遍历这些变量的所有组合来检查它们。
同样,
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