英文:
How to resolve zero division error for the following code which uses scipy?
问题
这是我的Python代码:
import numpy as np
from scipy.integrate import quad
a = 0.15
def A(z):
return -a * z**2
def integrand(x, z, B):
return np.sqrt(-(2/x)*(3*x*A(x).derivative(n=2) - 3*x*(A(x).derivative(n=1))**2 + 6*A(x).derivative(n=1) + 2*B**4*x**3 + 2*B**2*x))
def Phi(z, B):
result, _ = quad(integrand, 0, z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
我遇到了"ZeroDivisionError: float division by zero"的错误。如何解决这个问题?我尝试使用sympy,但没有成功。
英文:
Here's my python code:
import numpy as np
from scipy.integrate import quad
a = 0.15
def A(z):
return -a * z**2
def integrand(x, z, B):
return np.sqrt(-(2/x)*(3*x*A(x).derivative(n=2) - 3*x*(A(x).derivative(n=1))**2 + 6*A(x).derivative(n=1) + 2*B**4*x**3 + 2*B**2*x))
def Phi(z, B):
result, _ = quad(integrand, 0, z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
I am getting a "ZeroDivisionError: float division by zero"
How to resolve this issue?
I tried using sympy but to no avail.
答案1
得分: 1
在修复了其他可能存在的问题并进行了一些猜测后,同时将 epsilon 添加为积分下界,
import numpy as np
from scipy.integrate import quad
a = 0.15
# def A(z: float) -> float:
# return -a * z**2
A = np.poly1d((-a, 0, 0))
Ad1 = A.deriv(m=1)
Ad2 = A.deriv(m=2)
def integrand(x: float, z: float, B: float) -> float:
return np.sqrt(
-(2/x)*(
3*x*Ad2(x)
- 3*x*Ad1(x)**2
+ 6*Ad1(x)
+ 2*B**4*x**3
+ 2*B**2*x
)
)
def Phi(z: float, B: float):
epsilon = 1e-6
result, _ = quad(func=integrand, a=epsilon, b=z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
print(np.array(phi_values))
[-2.32379001e-06 2.36195636e+00 4.94106004e+00 7.90800675e+00
1.13771987e+01 1.54207025e+01 2.00839857e+01 2.53965776e+01
...
3.40309939e+03 3.47405018e+03 3.54573543e+03 3.61815514e+03
3.69130933e+03]
但更明智的做法是在积分之前对 x
进行解析分离:
import numpy as np
from numpy.polynomial import Polynomial
from scipy.integrate import quad
a = 0.15
# def A(z: float) -> float:
# return -a * z**2
A = Polynomial((0, 0, -a))
Ad1 = A.deriv(m=1)
Ad2 = A.deriv(m=2)
# Divide by x prior to integrand
Ad1ox = Ad1 // Polynomial((0, 1))
def integrand(x: float, z: float, B: float) -> float:
return np.sqrt(
-2*(
3*Ad2(x)
- 3*Ad1(x)**2
+ 6*Ad1ox(x) # 6/x*Ad1(x)
+ 2*B**4*x**2
+ 2*B**2
)
)
def Phi(z: float, B: float):
result, _ = quad(func=integrand, a=0, b=z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
print(np.array(phi_values))
这将产生相同的结果。
英文:
Fixing your other breakage re. derivatives with some wild guessing, and adding an epsilon as your lower integration bound,
import numpy as np
from scipy.integrate import quad
a = 0.15
# def A(z: float) -> float:
# return -a * z**2
A = np.poly1d((-a, 0, 0))
Ad1 = A.deriv(m=1)
Ad2 = A.deriv(m=2)
def integrand(x: float, z: float, B: float) -> float:
return np.sqrt(
-(2/x)*(
3*x*Ad2(x)
- 3*x*Ad1(x)**2
+ 6*Ad1(x)
+ 2*B**4*x**3
+ 2*B**2*x
)
)
def Phi(z: float, B: float):
epsilon = 1e-6
result, _ = quad(func=integrand, a=epsilon, b=z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
print(np.array(phi_values))
[-2.32379001e-06 2.36195636e+00 4.94106004e+00 7.90800675e+00
1.13771987e+01 1.54207025e+01 2.00839857e+01 2.53965776e+01
...
3.40309939e+03 3.47405018e+03 3.54573543e+03 3.61815514e+03
3.69130933e+03]
But the saner thing to do is analytically divide out x
:
import numpy as np
from numpy.polynomial import Polynomial
from scipy.integrate import quad
a = 0.15
# def A(z: float) -> float:
# return -a * z**2
A = Polynomial((0, 0, -a))
Ad1 = A.deriv(m=1)
Ad2 = A.deriv(m=2)
# Divide by x prior to integrand
Ad1ox = Ad1 // Polynomial((0, 1))
def integrand(x: float, z: float, B: float) -> float:
return np.sqrt(
-2*(
3*Ad2(x)
- 3*Ad1(x)**2
+ 6*Ad1ox(x) # 6/x*Ad1(x)
+ 2*B**4*x**2
+ 2*B**2
)
)
def Phi(z: float, B: float):
result, _ = quad(func=integrand, a=0, b=z, args=(z, B))
return result
phi_values = [Phi(z, 0) for z in range(101)]
print(np.array(phi_values))
which yields the same results.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论