admin管理员组文章数量:1394600
I have a 1d function p(r) = 1-r
when r<1
and p(r) = 0
otherwise. Let I1(r) = ∫pdr
where integration starts from 0
. Let's set the constant of integration so that I1(1)=0
. Now, assume r
represents radius from origin on a 2d x-y
grid so that r(x,y) = √(x²+y²)
. If I want to instead compute the integral of p
on the 2d x-y
grid, I can do it in the following manner: I2(x,y) = ∫p (∂r/∂x) dx + ∫p (∂r/∂y) dy
because dr = (∂r/∂x) dx + (∂r/∂y) dy
. The x,y
integral limits can start at any point less than -1
. Set the integration constant so that I2=0
at the contour r=1
. Since I1(r)
is a 1d function and I2(x,y)
is a 2d function, they cannot be directly compared but if I plot them, I should see that their extrema are matching. However, when I wrote a simple code to test it, I noticed that extremum of I2
is about 2
times the extremum of I1
. Following is the Python-3 code to test it
import numpy as np
import scipy.integrate
import matplotlib.pyplot as plt
nr = 101
r = np.linspace(0, 2, nr)
p = 1 - r
p *= (p > 0) # setting p=0 outside r=1
I1 = scipy.integrate.cumulative_simpson(p, x=r, initial=0)
I1 -= I1[-1]
nx, ny = 151, 301
x = np.linspace(-1.5, 1.5, nx)
y = np.linspace(-2.0, 2.0, ny)
ix0 = round((0.0-x[0])/(x[-1]-x[0])*(nx-1)) # index where x=0
ix1 = round((1.0-x[0])/(x[-1]-x[0])*(nx-1)) # index where x=1
iy0 = round((0.0-y[0])/(y[-1]-y[0])*(ny-1)) # index where y=0
x2, y2 = np.meshgrid(x, y, indexing='xy')
r2 = np.sqrt(x2**2 + y2**2)
dr2dx = x2 / r2 # ∂r/∂x
dr2dx[iy0,ix0] = 0.0 # to get rid of nan at (0,0)
dr2dy = y2 / r2 # ∂r/∂y
dr2dy[iy0,ix0] = 0.0 # to get rid of nan at (0,0)
p2 = (1 - r2) # function p on x-y grid
p2 *= (p2 > 0) # setting p=0 outside radius 1
I2 = scipy.integrate.cumulative_simpson(p2 * dr2dx, x=x, axis=1, initial=0)
I2 += scipy.integrate.cumulative_simpson(p2 * dr2dy, x=y, axis=0, initial=0)
I2 -= I2[iy0, ix1]
I2 = I2 * (I2 < 0) # removes some numerical residues
print(f'Minima of I1: {np.min(I1)}\nMinima of I2: {np.min(I2)}')
fig, axs = plt.subplots(1, 3, figsize=(12, 4))
axs[0].plot(r, p, label='p')
axs[0].plot(r, I1, label=r'I1')
axs[0].legend()
axs[0].set_xlabel('r')
c1 = axs[1].contour(x2, y2, p2)
axs[1].set_aspect(1)
axs[1].set_xlabel('x')
axs[1].set_ylabel('y')
axs[1].set_title('p')
c2 = axs[2].contour(x2, y2, I2)
axs[2].set_aspect(1)
axs[2].set_xlabel('x')
axs[2].set_ylabel('y')
axs[2].set_title(r'I2')
fig.colorbar(c1)
fig.colorbar(c2)
plt.tight_layout(); plt.show(); plt.close()
Have I made a mistake somewhere? If not, what is the actual reason behind this and how to properly rectify it. It might appear that 2d integration is somehow happening twice but I don't see that I am doing anything mathematically wrong here. One can also say that integration is happening twice in both x
and y
directions, so why not a factor of 4
? I also tried the 2d integration in a quadrant, upper half and right half but result was same. For these cases, I modified computation of I2
with the following:
I2x = scipy.integrate.cumulative_simpson(p2 * dr2dx, x=x, axis=1, initial=0)
for j in range(ny):
I2x[j,:] -= I2x[j,-1] # to set integration constant at each x
I2y = scipy.integrate.cumulative_simpson(p2 * dr2dy, x=y, axis=0, initial=0)
for i in range(nx):
I2y[:,i] -= I2y[-1,i] # to set integration constant at each y
I2 = I2x + I2y
I2 = I2 * (I2 < 0) # removes some numerical residues
I also tried to do the same in 3d and the answer tripled. So it probably has something to do with dr
. Is it wrong to write dr = (∂r/∂x) dx + (∂r/∂y) dy
?
本文标签: pythonMissing factor of 2 when numerically integrating a 1d function on 2d gridStack Overflow
版权声明:本文标题:python - Missing factor of 2 when numerically integrating a 1d function on 2d grid - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744094709a2590071.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论