Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python坐标变换下的montecarlo积分_Python_Montecarlo - Fatal编程技术网

Python坐标变换下的montecarlo积分

Python坐标变换下的montecarlo积分,python,montecarlo,Python,Montecarlo,我试图用蒙特卡罗方法计算积分,其中被积函数经历了从柱坐标到笛卡尔坐标的转换。被积函数本身非常简单,可以使用scipy.integrate.quad进行计算,但我需要它位于笛卡尔坐标系中,以便以后用于特定用途 这就是被积函数:rho*k_-r**2*(k_-r**2*kn(0,k_-r*rho)**2+k_-n**2*kn(1,k_-r*rho)**2)d rho 这里的kn(i,rho)是第二类贝塞尔函数的修正 使用quad求解它会得到以下结果: from scipy.special impor

我试图用蒙特卡罗方法计算积分,其中被积函数经历了从柱坐标到笛卡尔坐标的转换。被积函数本身非常简单,可以使用
scipy.integrate.quad
进行计算,但我需要它位于笛卡尔坐标系中,以便以后用于特定用途

这就是被积函数:
rho*k_-r**2*(k_-r**2*kn(0,k_-r*rho)**2+k_-n**2*kn(1,k_-r*rho)**2)d rho

这里的
kn(i,rho)
是第二类贝塞尔函数的修正

使用
quad
求解它会得到以下结果:

from scipy.special import kn
from scipy.integrate import quad
import random
k_r        = 6.2e-2
k_n        = k_r/1.05
C_factor   = 2*np.pi*1e5
lmax,lmin  = 80,50

def integration_polar():
    def K_int(rho):
        return rho*k_r**2*(k_r**2*kn(0,k_r*rho)**2+k_n**2*kn(1,k_r*rho)**2)
   
    rho = np.linspace(lmin,lmax,200)
    I,_ = quad(K_int,lmin,lmax)
    Gamma = I*C_factor
    print("expected=",Gamma)
输出:
Expected=7.641648442007296

现在,使用蒙特卡罗法(点击或未点击法)的相同积分给出了几乎相同的结果:

def integration_polar_MC():    
    random.seed(1)
    n = 100000
    def K_int(rho):
        return rho*k_r**2*(k_r**2*kn(0,k_r*rho)**2+k_n**2*kn(1,k_r*rho)**2)
    def sampler():
        x = random.uniform(lmin,lmax)
        y = random.uniform(0,c_lim)
        return x,y

    c_lim = 2*K_int(50) #Upper limit of integrand
    sum_I = 0
    for i in range(n):
        x,y = sampler()
        func_Int = K_int(x)
        if y>func_Int:
            I = 0
        elif y<=func_Int:
            I = 1
        sum_I += I
     Gamma = C_factor*(lmax-lmin)*c_lim*sum_I/n
     print("MC_integral_polar:",Gamma)
以下是我的尝试:

def integration_cartesian_MCtry():          
    random.seed(1)
    lmin,lmax = -100,100
    n = 100000
    def K_int(x,y):  
        rho = np.sqrt(x**2+y**2)
        if rho>=50 and rho<=80:
            return k_r**2*(k_r**2*kn(0,k_r*rho)**2+k_n**2*kn(1,k_r*rho)**2)
        else:
            return 0
    def sampler():
        x = random.uniform(lmin,lmax)
        y = random.uniform(lmin,lmax)
        z = random.uniform(0,c_lim)
        return x,y,z

    c_lim = K_int(50,0)
    sum_I = 0
    for i in range(n):
        x,y,z = sampler()
        func_Int = K_int(x,y)
        if z>func_Int:
            I = 0
        elif z<=func_Int:
            I = 1
        sum_I += I

    Gamma  = C_factor*(lmax-lmin)**2*c_lim*sum_I/n
    print("MC_integral_cartesian:",Gamma)
def集成\u笛卡尔\u MCtry():
随机种子(1)
lmin,lmax=-100100
n=100000
定义K_int(x,y):
rho=np.sqrt(x**2+y**2)
如果rho>=50且rhofunc_Int:
I=0

Elifz正如我所说,问题在于雅可比矩阵。如果是polar,则需要对其进行积分

f(ρ)*ρ*dρ*dφ
对dφ进行解析积分(f(ρ)与φ无关),得到2π

在笛卡尔坐标的情况下,没有解析积分,所以它超过dx*dy,没有因子 2π。Python 3.9.1、Windows 10 x64的代码对此进行了说明,它给出了几乎相同的答案

import numpy as np
from scipy.special import kn

k_r        = 6.2e-2
k_n        = k_r/1.05
C_factor   = 2*np.pi*1e5

lmin       = 50
lmax       = 80

def integration_polar_MC(rng, n):

    def K_int(rho):
        if rho>=50 and rho<=80:
            return rho*k_r**2*(k_r**2*kn(0, k_r*rho)**2 + k_n**2*kn(1, k_r*rho)**2)
        return 0.0

    def sampler():
        x = rng.uniform(lmin, lmax)
        y = rng.uniform(0.0, c_lim)
        return x,y

    c_lim = 2*K_int(50) # Upper limit of integrand
    sum_I = 0
    for i in range(n):
        x,y = sampler()
        func_Int = K_int(x)
        I = 1
        if y>func_Int:
            I = 0

        sum_I += I

    Gamma = C_factor*(lmax-lmin)*c_lim*sum_I/n
    return Gamma


def integration_cartesian_MC(rng, n):

    def K_int(x,y):
        rho = np.hypot(x, y)
        if rho>=50 and rho<=80:
            return k_r**2*(k_r**2*kn(0,k_r*rho)**2+k_n**2*kn(1,k_r*rho)**2)

        return 0.0

    def sampler():
        x = rng.uniform(lmin,lmax)
        y = rng.uniform(lmin,lmax)
        z = rng.uniform(0,c_lim)
        return x,y,z

    lmin,lmax = -100,100
    c_lim = K_int(50, 0)
    sum_I = 0
    for i in range(n):
        x,y,z = sampler()
        func_Int = K_int(x,y)
        I = 1
        if z>func_Int:
            I = 0
        sum_I += I

    Gamma  = C_factor*(lmax-lmin)**2*c_lim*sum_I/n
    return Gamma/(2.0*np.pi) # to compensate for 2π in the constant

rng = np.random.default_rng()
q = integration_polar_MC(rng, 100000)

print("MC_integral_polar:", q)

q = integration_cartesian_MC(rng, 100000)
print("MC_integral_cart:", q)
将numpy导入为np
来自scipy.special进口kn
k_r=6.2e-2
k_n=k_r/1.05
C_系数=2*np.pi*1e5
lmin=50
lmax=80
def集成\u polar\u MC(rng,n):
定义K_int(rho):
如果rho>=50且rhofunc_Int:
I=0
和I+=I
Gamma=C_系数*(lmax lmin)*C_lim*总和I/n
返回伽马
def集成\u笛卡尔\u MC(rng,n):
定义K_int(x,y):
rho=np.hypot(x,y)
如果rho>=50且rhofunc_Int:
I=0
和I+=I
Gamma=C_系数*(lmax-lmin)**2*C_-lim*总和I/n
返回伽马/(2.0*np.pi)#以补偿常数中的2π
rng=np.random.default\u rng()
q=集成度、极性、最大连续性(rng,100000)
打印(“MC_积分_极坐标:”,q)
q=积分笛卡尔矩阵(rng,100000)
打印(“MC_积分车:”,q)

Jacobian?这将导致不同的采样密度谢谢!显然,我已经在常数中加入了2*pi,并且完全忘记了它来自于圆上的dñ积分。
import numpy as np
from scipy.special import kn

k_r        = 6.2e-2
k_n        = k_r/1.05
C_factor   = 2*np.pi*1e5

lmin       = 50
lmax       = 80

def integration_polar_MC(rng, n):

    def K_int(rho):
        if rho>=50 and rho<=80:
            return rho*k_r**2*(k_r**2*kn(0, k_r*rho)**2 + k_n**2*kn(1, k_r*rho)**2)
        return 0.0

    def sampler():
        x = rng.uniform(lmin, lmax)
        y = rng.uniform(0.0, c_lim)
        return x,y

    c_lim = 2*K_int(50) # Upper limit of integrand
    sum_I = 0
    for i in range(n):
        x,y = sampler()
        func_Int = K_int(x)
        I = 1
        if y>func_Int:
            I = 0

        sum_I += I

    Gamma = C_factor*(lmax-lmin)*c_lim*sum_I/n
    return Gamma


def integration_cartesian_MC(rng, n):

    def K_int(x,y):
        rho = np.hypot(x, y)
        if rho>=50 and rho<=80:
            return k_r**2*(k_r**2*kn(0,k_r*rho)**2+k_n**2*kn(1,k_r*rho)**2)

        return 0.0

    def sampler():
        x = rng.uniform(lmin,lmax)
        y = rng.uniform(lmin,lmax)
        z = rng.uniform(0,c_lim)
        return x,y,z

    lmin,lmax = -100,100
    c_lim = K_int(50, 0)
    sum_I = 0
    for i in range(n):
        x,y,z = sampler()
        func_Int = K_int(x,y)
        I = 1
        if z>func_Int:
            I = 0
        sum_I += I

    Gamma  = C_factor*(lmax-lmin)**2*c_lim*sum_I/n
    return Gamma/(2.0*np.pi) # to compensate for 2π in the constant

rng = np.random.default_rng()
q = integration_polar_MC(rng, 100000)

print("MC_integral_polar:", q)

q = integration_cartesian_MC(rng, 100000)
print("MC_integral_cart:", q)