मैं जिस तरह से matlab संख्यात्मक एकीकरण बनाम Scipy संभालता है पर कुछ निराशा का अनुभव कर रहा हूँ। मैं अपने परीक्षण कोड में निम्नलिखित अंतरों का पालन करता हूं:
- मतलाब का संस्करण मेरे अजगर के मुकाबले औसतन 24 गुना तेज चलता है !
- मैथलैब का संस्करण बिना किसी चेतावनी के अभिन्न की गणना करने में सक्षम है, जबकि अजगर रिटर्न करता है
nan+nanj
मैं यह सुनिश्चित करने के लिए क्या कर सकता हूं कि मुझे वर्णित दो बिंदुओं के संबंध में अजगर में समान प्रदर्शन मिले? दस्तावेज़ीकरण के अनुसार दोनों विधियों को अभिन्न को अनुमानित करने के लिए "वैश्विक अनुकूली चतुर्थांश" का उपयोग करना चाहिए।
नीचे दो संस्करणों में कोड है (हालांकि समान रूप से अजगर को यह आवश्यक है कि एक अभिन्न फ़ंक्शन बनाया जाए ताकि यह जटिल पूर्णांक को संभाल सके।)
अजगर
import numpy as np
from scipy import integrate
import time
def integral(integrand, a, b, arg):
def real_func(x,arg):
return np.real(integrand(x,arg))
def imag_func(x,arg):
return np.imag(integrand(x,arg))
real_integral = integrate.quad(real_func, a, b, args=(arg))
imag_integral = integrate.quad(imag_func, a, b, args=(arg))
return real_integral[0] + 1j*imag_integral[0]
vintegral = np.vectorize(integral)
def f_integrand(s, omega):
sigma = np.pi/(np.pi+2)
xs = np.exp(-np.pi*s/(2*sigma))
x1 = -2*sigma/np.pi*(np.log(xs/(1+np.sqrt(1-xs**2)))+np.sqrt(1-xs**2))
x2 = 1-2*sigma/np.pi*(1-xs)
zeta = x2+x1*1j
Vc = 1/(2*sigma)
theta = -1*np.arcsin(np.exp(-np.pi/(2.0*sigma)*s))
t1 = 1/np.sqrt(1+np.tan(theta)**2)
t2 = -1/np.sqrt(1+1/np.tan(theta)**2)
return np.real((t1-1j*t2)/np.sqrt(zeta**2-1))*np.exp(1j*omega*s/Vc);
t0 = time.time()
omega = 10
result = integral(f_integrand, 0, np.inf, omega)
print time.time()-t0
print result
Matlab
function [ out ] = f_integrand( s, omega )
sigma = pi/(pi+2);
xs = exp(-pi.*s./(2*sigma));
x1 = -2*sigma./pi.*(log(xs./(1+sqrt(1-xs.^2)))+sqrt(1-xs.^2));
x2 = 1-2*sigma./pi.*(1-xs);
zeta = x2+x1*1j;
Vc = 1/(2*sigma);
theta = -1*asin(exp(-pi./(2.0.*sigma).*s));
t1 = 1./sqrt(1+tan(theta).^2);
t2 = -1./sqrt(1+1./tan(theta).^2);
out = real((t1-1j.*t2)./sqrt(zeta.^2-1)).*exp(1j.*omega.*s./Vc);
end
t=cputime;
omega = 10;
result = integral(@(s) f_integrand(s,omega),0,Inf)
time_taken = cputime-t
np.vectorize
)। एक बार में पूरे सरणी पर गणना करने का प्रयास करें। यह संभव नहीं है, सुंबा या साइथन पर भी एक नज़र है, लेकिन मुझे आशा है कि उत्तरार्द्ध आवश्यक नहीं है।
integral
डिफ़ॉल्ट पूर्ण और सापेक्ष सहिष्णुता हैं 1e-10
और 1e-6
। integrate.quad
इन दोनों को निर्दिष्ट करता है 1.49e-8
। मैं यह नहीं देखता कि integrate.quad
एक "वैश्विक अनुकूली" विधि के रूप में कहां वर्णित है और यह निश्चित रूप से (अनुकूली गॉस-क्रोन्रोड, मेरा मानना है) विधि से भिन्न है integral
। मुझे यकीन नहीं है कि "वैश्विक" भाग का क्या मतलब है, खुद। इसके अलावा, यह / या के cputime
बजाय का उपयोग करने के लिए एक अच्छा विचार नहीं है । tic
toc
time it