如何解决以下使用scipy的代码中的零除错误?

huangapple go评论77阅读模式
英文:

How to resolve zero division error for the following code which uses scipy?

问题

这是我的Python代码:

  1. import numpy as np
  2. from scipy.integrate import quad
  3. a = 0.15
  4. def A(z):
  5. return -a * z**2
  6. def integrand(x, z, B):
  7. 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))
  8. def Phi(z, B):
  9. result, _ = quad(integrand, 0, z, args=(z, B))
  10. return result
  11. phi_values = [Phi(z, 0) for z in range(101)]

我遇到了"ZeroDivisionError: float division by zero"的错误。如何解决这个问题?我尝试使用sympy,但没有成功。

英文:

Here's my python code:

  1. import numpy as np
  2. from scipy.integrate import quad
  3. a = 0.15
  4. def A(z):
  5. return -a * z**2
  6. def integrand(x, z, B):
  7. 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))
  8. def Phi(z, B):
  9. result, _ = quad(integrand, 0, z, args=(z, B))
  10. return result
  11. 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 添加为积分下界,

  1. import numpy as np
  2. from scipy.integrate import quad
  3. a = 0.15
  4. # def A(z: float) -> float:
  5. # return -a * z**2
  6. A = np.poly1d((-a, 0, 0))
  7. Ad1 = A.deriv(m=1)
  8. Ad2 = A.deriv(m=2)
  9. def integrand(x: float, z: float, B: float) -> float:
  10. return np.sqrt(
  11. -(2/x)*(
  12. 3*x*Ad2(x)
  13. - 3*x*Ad1(x)**2
  14. + 6*Ad1(x)
  15. + 2*B**4*x**3
  16. + 2*B**2*x
  17. )
  18. )
  19. def Phi(z: float, B: float):
  20. epsilon = 1e-6
  21. result, _ = quad(func=integrand, a=epsilon, b=z, args=(z, B))
  22. return result
  23. phi_values = [Phi(z, 0) for z in range(101)]
  24. print(np.array(phi_values))
  1. [-2.32379001e-06 2.36195636e+00 4.94106004e+00 7.90800675e+00
  2. 1.13771987e+01 1.54207025e+01 2.00839857e+01 2.53965776e+01
  3. ...
  4. 3.40309939e+03 3.47405018e+03 3.54573543e+03 3.61815514e+03
  5. 3.69130933e+03]

但更明智的做法是在积分之前对 x 进行解析分离:

  1. import numpy as np
  2. from numpy.polynomial import Polynomial
  3. from scipy.integrate import quad
  4. a = 0.15
  5. # def A(z: float) -> float:
  6. # return -a * z**2
  7. A = Polynomial((0, 0, -a))
  8. Ad1 = A.deriv(m=1)
  9. Ad2 = A.deriv(m=2)
  10. # Divide by x prior to integrand
  11. Ad1ox = Ad1 // Polynomial((0, 1))
  12. def integrand(x: float, z: float, B: float) -> float:
  13. return np.sqrt(
  14. -2*(
  15. 3*Ad2(x)
  16. - 3*Ad1(x)**2
  17. + 6*Ad1ox(x) # 6/x*Ad1(x)
  18. + 2*B**4*x**2
  19. + 2*B**2
  20. )
  21. )
  22. def Phi(z: float, B: float):
  23. result, _ = quad(func=integrand, a=0, b=z, args=(z, B))
  24. return result
  25. phi_values = [Phi(z, 0) for z in range(101)]
  26. print(np.array(phi_values))

这将产生相同的结果。

英文:

Fixing your other breakage re. derivatives with some wild guessing, and adding an epsilon as your lower integration bound,

  1. import numpy as np
  2. from scipy.integrate import quad
  3. a = 0.15
  4. # def A(z: float) -> float:
  5. # return -a * z**2
  6. A = np.poly1d((-a, 0, 0))
  7. Ad1 = A.deriv(m=1)
  8. Ad2 = A.deriv(m=2)
  9. def integrand(x: float, z: float, B: float) -> float:
  10. return np.sqrt(
  11. -(2/x)*(
  12. 3*x*Ad2(x)
  13. - 3*x*Ad1(x)**2
  14. + 6*Ad1(x)
  15. + 2*B**4*x**3
  16. + 2*B**2*x
  17. )
  18. )
  19. def Phi(z: float, B: float):
  20. epsilon = 1e-6
  21. result, _ = quad(func=integrand, a=epsilon, b=z, args=(z, B))
  22. return result
  23. phi_values = [Phi(z, 0) for z in range(101)]
  24. print(np.array(phi_values))
  1. [-2.32379001e-06 2.36195636e+00 4.94106004e+00 7.90800675e+00
  2. 1.13771987e+01 1.54207025e+01 2.00839857e+01 2.53965776e+01
  3. ...
  4. 3.40309939e+03 3.47405018e+03 3.54573543e+03 3.61815514e+03
  5. 3.69130933e+03]

But the saner thing to do is analytically divide out x:

  1. import numpy as np
  2. from numpy.polynomial import Polynomial
  3. from scipy.integrate import quad
  4. a = 0.15
  5. # def A(z: float) -> float:
  6. # return -a * z**2
  7. A = Polynomial((0, 0, -a))
  8. Ad1 = A.deriv(m=1)
  9. Ad2 = A.deriv(m=2)
  10. # Divide by x prior to integrand
  11. Ad1ox = Ad1 // Polynomial((0, 1))
  12. def integrand(x: float, z: float, B: float) -> float:
  13. return np.sqrt(
  14. -2*(
  15. 3*Ad2(x)
  16. - 3*Ad1(x)**2
  17. + 6*Ad1ox(x) # 6/x*Ad1(x)
  18. + 2*B**4*x**2
  19. + 2*B**2
  20. )
  21. )
  22. def Phi(z: float, B: float):
  23. result, _ = quad(func=integrand, a=0, b=z, args=(z, B))
  24. return result
  25. phi_values = [Phi(z, 0) for z in range(101)]
  26. print(np.array(phi_values))

which yields the same results.

huangapple
  • 本文由 发表于 2023年3月31日 22:08:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定