用非解析积分求解超越方程的数值解

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

Numerical solutions to transcendental equation with nonanalytic integral

问题

I want to find solutions y to the equation

用非解析积分求解超越方程的数值解,

for every value in C = np.linspace(0, 1000, 100). I wrote the following code but it does not work.

  1. import numpy as np
  2. import scipy.integrate as integrate
  3. from scipy.optimize import root
  4. import matplotlib.pyplot as plt
  5. n_0 = 1
  6. k = 5
  7. A = np.deg2rad(30)
  8. def n(y):
  9. return k*y + n_0
  10. def f(y):
  11. f = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  12. result, error = integrate.quad(f, 0, y)
  13. return result
  14. In the above section, I have defined my function `f(y)`. Here is the rest of my code.
  15. C = np.linspace(0, 1000, 1000)
  16. dy = np.array([])
  17. for arg in C:
  18. def integral(y):
  19. return f(y) - arg
  20. dy = np.append(dy, root(integral, 1).x)
  21. plt.plot(C, dy)
  22. plt.show()

I get the message

  1. d:\FMF\MAF2\simulacija.py:14: RuntimeWarning: invalid value encountered in double_scalars
  2. f = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  3. d:\FMF\MAF2\simulacija.py:15: IntegrationWarning: The occurrence of roundoff error is detected, which prevents
  4. the requested tolerance from being achieved. The error may be
  5. underestimated.
  6. result, error = integrate.quad(f, 0, y)
  7. d:\FMF\MAF2\simulacija.py:15: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.
  8. If increasing the limit yields no improvement it is advised to analyze
  9. the integrand in order to determine the difficulties. If the position of a
  10. local difficulty can be determined (singularity, discontinuity) one will
  11. probably gain from splitting up the interval and calling the integrator
  12. on the subranges. Perhaps a special-purpose integrator should be used.
  13. result, error = integrate.quad(f, 0, y)
英文:

I want to find solutions y to the equation

用非解析积分求解超越方程的数值解,

for every value in C = np.linspace(0, 1000, 100). I wrote the following code but it does not work.

  1. import numpy as np
  2. import scipy.integrate as integrate
  3. from scipy.optimize import root
  4. import matplotlib.pyplot as plt
  5. n_0 = 1
  6. k = 5
  7. A = np.deg2rad(30)
  8. def n(y):
  9. return k*y + n_0
  10. def f(y):
  11. f = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  12. result, error = integrate.quad(f, 0, y)
  13. return result

In the above section, I have defined my function f(y). Here is the rest of my code.

  1. C = np.linspace(0, 1000, 1000)
  2. dy = np.array([])
  3. for arg in C:
  4. def integral(y):
  5. return f(y) - arg
  6. dy = np.append(dy, root(integral, 1).x)
  7. plt.plot(C, dy)
  8. plt.show()

I get the message

  1. d:\FMF\MAF2\simulacija.py:14: RuntimeWarning: invalid value encountered in double_scalars
  2. f = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  3. d:\FMF\MAF2\simulacija.py:15: IntegrationWarning: The occurrence of roundoff error is detected, which prevents
  4. the requested tolerance from being achieved. The error may be
  5. underestimated.
  6. result, error = integrate.quad(f, 0, y)
  7. d:\FMF\MAF2\simulacija.py:15: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.
  8. If increasing the limit yields no improvement it is advised to analyze
  9. the integrand in order to determine the difficulties. If the position of a
  10. local difficulty can be determined (singularity, discontinuity) one will
  11. probably gain from splitting up the interval and calling the integrator
  12. on the subranges. Perhaps a special-purpose integrator should be used.
  13. result, error = integrate.quad(f, 0, y)

答案1

得分: 2

尝试使用常规列表附加的代码,我得到以下结果:

  1. In [156]: C = np.linspace(0, 1000, 1000)
  2. ...: dy = []
  3. ...:
  4. ...: for arg in C:
  5. ...: def integral(y):
  6. ...: print(y)
  7. ...: return f(y) - arg
  8. ...: dy.append(root(integral, 1).x)
  9. [1]
  10. [1.]
  11. [1.]
  12. [1.00000001]
  13. [-1.46296662]
  14. Traceback (most recent call last):
  15. Cell In[156], line 8
  16. dy.append(root(integral, 1).x)
  17. File ~\miniconda3\lib\site-packages\scipy\optimize\_root.py:235 in root
  18. sol = _root_hybr(fun, x0, args=args, jac=jac, **options)
  19. File ~\miniconda3\lib\site-packages\scipy\optimize\_minpack_py.py:240 in _root_hybr
  20. retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev,
  21. Cell In[156], line 7 in integral
  22. return f(y) - arg
  23. Cell In[147], line 3 in f
  24. result, error = integrate.quad(f, 0, y)
  25. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:463 in quad
  26. retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
  27. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:575 in _quad
  28. return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
  29. TypeError: must be real number, not complex
  30. 尝试特定的 `y`
  31. ```python
  32. In [157]: f(-1.4)
  33. Traceback (most recent call last):
  34. Cell In[157], line 1
  35. f(-1.4)
  36. Cell In[147], line 3 in f
  37. result, error = integrate.quad(f, 0, y)
  38. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:463 in quad
  39. retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
  40. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:575 in _quad
  41. return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
  42. TypeError: must be real number, not complex
  43. `quad` 对象如果其 `func` 返回复数会出错
  44. 让我们修改函数 `f` 的定义以避免函数名称重叠
  45. ```python
  46. In [181]: def f(y):
  47. ...: fnc = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  48. ...: # print(fnc(0), fnc(y))
  49. ...: result, error = integrate.quad(fnc, 0, y)
  50. ...: return result
  51. ...:
  52. In [182]: C = np.linspace(0, 1000, 1000)
  53. ...: dy = []
  54. ...:
  55. ...: for arg in C:
  56. ...: def integral(y):
  57. ...: #print(y)
  58. ...: return f(y) - arg
  59. ...: dy.append(root(integral, 1).x)

现在我得到一些积分运行时错误,而且运行时间很长。

我尚未解决问题,但希望这些信息能够帮助您调试此类代码。

英文:

Trying your code with a regular list append, I get:

  1. In [156]: C = np.linspace(0, 1000, 1000)
  2. ...: dy = []
  3. ...:
  4. ...: for arg in C:
  5. ...: def integral(y):
  6. ...: print(y)
  7. ...: return f(y) - arg
  8. ...: dy.append(root(integral, 1).x)
  9. [1]
  10. [1.]
  11. [1.]
  12. [1.00000001]
  13. [-1.46296662]
  14. Traceback (most recent call last):
  15. Cell In[156], line 8
  16. dy.append(root(integral, 1).x)
  17. File ~\miniconda3\lib\site-packages\scipy\optimize\_root.py:235 in root
  18. sol = _root_hybr(fun, x0, args=args, jac=jac, **options)
  19. File ~\miniconda3\lib\site-packages\scipy\optimize\_minpack_py.py:240 in _root_hybr
  20. retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev,
  21. Cell In[156], line 7 in integral
  22. return f(y) - arg
  23. Cell In[147], line 3 in f
  24. result, error = integrate.quad(f, 0, y)
  25. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:463 in quad
  26. retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
  27. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:575 in _quad
  28. return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
  29. TypeError: must be real number, not complex

So trying a specific y

  1. In [157]: f(-1.4)
  2. Traceback (most recent call last):
  3. Cell In[157], line 1
  4. f(-1.4)
  5. Cell In[147], line 3 in f
  6. result, error = integrate.quad(f, 0, y)
  7. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:463 in quad
  8. retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
  9. File ~\miniconda3\lib\site-packages\scipy\integrate\_quadpack_py.py:575 in _quad
  10. return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
  11. TypeError: must be real number, not complex

quad objects if its func returns a complex.

Let's change the f def, to avoid function names over lap

  1. In [181]: def f(y):
  2. ...: fnc = lambda i: (((n(i)) / (n(0) * np.cos(A)))**2 - 1)**(-0.5)
  3. ...: # print(fnc(0), fnc(y))
  4. ...: result, error = integrate.quad(fnc, 0, y)
  5. ...: return result
  6. ...:
  7. In [182]: C = np.linspace(0, 1000, 1000)
  8. ...: dy = []
  9. ...:
  10. ...: for arg in C:
  11. ...: def integral(y):
  12. ...: #print(y)
  13. ...: return f(y) - arg
  14. ...: dy.append(root(integral, 1).x)

Now I get some integration run time errors, and very long runs.

I haven't solved the problem, but hopefully this gives some ideas on how to debug code like this.

huangapple
  • 本文由 发表于 2023年6月15日 03:48:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477075.html
匿名

发表评论

匿名网友

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

确定