I recently asked about trying to optimise a Python loop for a scientific application, और मेरे लिए an excellent, smart way of recoding it within NumPy which reduced execution time by a factor of around 100 प्राप्त हुआ!निष्पादन समय कम करने के लिए शुद्ध NumPy में लूप के लिए एक रिवाइटिंग
हालांकि, B
मूल्य की गणना वास्तव में, कुछ अन्य छोरों के भीतर नेस्ट क्योंकि यह पदों की एक नियमित ग्रिड पर मूल्यांकन किया जाता है है। क्या इस प्रक्रिया को बंद करने के लिए एक समान स्मार्ट NumPy पुनर्लेख है?
मुझे संदेह है कि इस भाग के प्रदर्शन लाभ को कम चिह्नित किया जाएगा, और नुकसान संभवतः यह होगा कि गणना की प्रगति पर उपयोगकर्ता को वापस रिपोर्ट करना संभव नहीं होगा, परिणाम न लिखे जा सकते हैं गणना फ़ाइल के अंत तक आउटपुट फ़ाइल, और संभवतः एक बड़े कदम में ऐसा करने से स्मृति प्रभाव पड़ता है? क्या इनमें से किसी को बाधित करना संभव है?
import numpy as np
import time
def reshape_vector(v):
b = np.empty((3,1))
for i in range(3):
b[i][0] = v[i]
return b
def unit_vectors(r):
return r/np.sqrt((r*r).sum(0))
def calculate_dipole(mu, r_i, mom_i):
relative = mu - r_i
r_unit = unit_vectors(relative)
A = 1e-7
num = A*(3*np.sum(mom_i*r_unit, 0)*r_unit - mom_i)
den = np.sqrt(np.sum(relative*relative, 0))**3
B = np.sum(num/den, 1)
return B
N = 20000 # number of dipoles
r_i = np.random.random((3,N)) # positions of dipoles
mom_i = np.random.random((3,N)) # moments of dipoles
a = np.random.random((3,3)) # three basis vectors for this crystal
n = [10,10,10] # points at which to evaluate sum
gamma_mu = 135.5 # a constant
t_start = time.clock()
for i in range(n[0]):
r_frac_x = np.float(i)/np.float(n[0])
r_test_x = r_frac_x * a[0]
for j in range(n[1]):
r_frac_y = np.float(j)/np.float(n[1])
r_test_y = r_frac_y * a[1]
for k in range(n[2]):
r_frac_z = np.float(k)/np.float(n[2])
r_test = r_test_x +r_test_y + r_frac_z * a[2]
r_test_fast = reshape_vector(r_test)
B = calculate_dipole(r_test_fast, r_i, mom_i)
omega = gamma_mu*np.sqrt(np.dot(B,B))
# write r_test, B and omega to a file
frac_done = np.float(i+1)/(n[0]+1)
t_elapsed = (time.clock()-t_start)
t_remain = (1-frac_done)*t_elapsed/frac_done
print frac_done*100,'% done in',t_elapsed/60.,'minutes...approximately',t_remain/60.,'minutes remaining'
मुझे लगता है कि प्रोफाइल के लिए जस्टिन का सुझाव शायद बुद्धिमान था, लेकिन इसके लिए बहुत बहुत धन्यवाद ... हालांकि मुझे यकीन नहीं है कि मैं इसका उपयोग करूंगा, मुझे लगता है कि यह समझने की कोशिश करना संभवतः सीखने का एक बहुत अच्छा तरीका है। :) – Statto