I notice python avoid calculating some extreme value, for example kn(2,x>600) = Nan
, how could force python to provide a value instead of 'Nan'?
import numpy as np
from scipy.special import kn
import matplotlib.pyplot as plt
x = np.logspace(0, 3, 100)
plt.plot(x, kn(2, x), label='$K_2(x)$')
plt.ylim(0, 10)
plt.yscale('log')
plt.xscale('log')
plt.legend()
plt.title(r'Modified Bessel function of the second kind $K_2(x)$')
plt.show()
You're running up against machine precision here. Check out the actual values for a different range:
x = np.logspace(2.5, 3, 100)
y = kn(2, x)
print(y)
yields
array([3.27082355e-139, 8.04765930e-141, 1.89623338e-142, 4.27665221e-144,
9.22749139e-146, 1.90373267e-147, 3.75355921e-149, 7.06911929e-151,
1.27098118e-152, 2.18036409e-154, 3.56694629e-156, 5.56161008e-158,
8.26032006e-160, 1.16798880e-161, 1.57136165e-163, 2.01028012e-165,
2.44412995e-167, 2.82241343e-169, 3.09374066e-171, 3.21698746e-173,
3.17138653e-175, 2.96218619e-177, 2.61977955e-179, 2.19244653e-181,
1.73510013e-183, 1.29767955e-185, 9.16580410e-188, 6.11002951e-190,
3.84141931e-192, 2.27624181e-194, 1.27034732e-196, 6.67266861e-199,
3.29641352e-201, 1.53051400e-203, 6.67376973e-206, 2.73101779e-208,
1.04803219e-210, 3.76873070e-213, 1.26898290e-215, 3.99781360e-218,
1.17749058e-220, 3.23980250e-223, 8.32070057e-226, 1.99311122e-228,
4.44917394e-231, 9.24794484e-234, 1.78840827e-236, 3.21497095e-239,
5.36791283e-242, 8.31718958e-245, 1.19484297e-247, 1.59009856e-250,
1.95851837e-253, 2.23063495e-256, 2.34708527e-259, 2.27943049e-262,
2.04133304e-265, 1.68414524e-268, 1.27881202e-271, 8.92840360e-275,
5.72604000e-278, 3.36989935e-281, 1.81813009e-284, 8.98331910e-288,
4.06074540e-291, 1.67756649e-294, 6.32705298e-298, 2.17624754e-301,
6.81917993e-305, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000])
The smallest floating point number that can be represented is about 2.225e-308 (see here ). So numbers smaller than that are set to identically 0 by python. There is no "forcing python to give solutions". Your NaN issues are coming from trying to take the log of 0 while plotting.
According to the answers in the post Bessel functions in Python that work with large exponents we should have two ways to get Bessel extreme results
scipy.special.kve
mpmath.besselk
for second kind kn
But we can only use logarithm results
import numpy as np
from math import e
from scipy.special import kn,kv,kve
import matplotlib.pyplot as plt
import mpmath
x = np.logspace(0, 3, 100)
y = kn(2,x)
y2 = kv(2,x)
## kve(v, z) = kv(v, z) * exp(z)
y3 = np.log10(kve(2,x)) - x*np.log10(e)
y4 = []
for i in x:
yy = mpmath.besselk(2,i)
yy = mpmath.mp.log10(yy)
y4.append(yy)
x = np.log10(x)
y = np.log10(y)
y2 = np.log10(y2)
plt.plot(x, y, lw = 7, label=r'$K_2(x)$ by kn')
plt.plot(x, y2, lw = 9, ls='--', label=r'$K_v(2,x)$ by kv')
plt.plot(x, y3, lw = 3, ls='--', label=r'$K_v(2,x)$ by kve')
plt.plot(x, y4, ls='-', label=r'$K_2(x)$ by mpmath')
plt.title(r'Modified Bessel function of the second kind $K_2(x)$')
plt.xlabel('log x')
plt.ylabel('log y')
plt.legend()
plt.tight_layout()
plt.savefig('kn.png',format='png')
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.