簡體   English   中英

Scipy.integrate浮動錯誤

[英]Scipy.integrate float error

我正在嘗試集成由幾個函數組成的討厭的積分。

import matplotlib.pyplot as plt
import numpy as np
import os
import scipy.integrate as integrate

path = '/users/username/Desktop/untitled folder/python files/document/'

os.chdir( path )
data = np.load('msii_phasespace.npy',mmap_mode='r')
# data.size: 167197
# data.shape: (167197,)
# data.dtype: dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4'),
  # ('velx', '<f4'), ('vely', '<f4'), ('velz', '<f4'), ('m200', '<f4')])

## Constant
rho_m = 3.3e-14
M = data['x'] Mass of dark matter haloes
R = ((3*M)/(rho_m*4*(3.14)))**(1.0/3.0) # Km // Radius of sphere 
k = 0.001 # Mpc h^-1 // Wave Dispersion relation 
delt_c = 1.686 
h = 0.73 # km s^-1 Mpc^-1 
e = 2.718281 # Eulers number
T_CMB = 2.725   
Omega_m = 0.27 
kR = k*R


def T(k): 
    q = k/((Omega_m)*h**2)*((T_CMB)/27)**2
    L = np.log(e+1.84*q)
    C = 14.4 + 325/(1+60.5*q**1.11)
    return L/(L+C*q**2)

def P(k): 
    A = 0.75 
    n = 0.95 
    return A*k**n*T(k)**2

def W(kR): # Fourier Transfrom in the top hat function
    return 3*(np.sin(k*R)-k*R*np.cos(k*R))/(k*R)**3

def sig(R): 
    def integrand(k,P,W):
        return k**2*P(k)*W(kR)**2
I1 = integrate.quad(integrand, lambda k: 0.0, lambda k: np.Inf, args=(k,))
return ((1.0/(2.0*np.pi**2)) * I1)**0.5

打印出sig(R)給我TypeError: a float is require

我需要注意的是,R是物體的半徑,它與物體的質量成正比。 質量由結構化數組給出。 我不確定我是否使用正確的積分命令來評估所有質量。 只有數組具有一組值。

如果您需要更多信息,請告訴我,我將很樂意分享我所能提供的一切。 任何建議將被認真考慮。

1.使用integrand.quad()計算積分

閱讀文檔

  • integrand.quad返回長度為2的元組,第一個值保存積分的估計值。 確保只得到第一個元素而不是整個元組

  • 您不需要lambda即可通過限制。 lambda代替了積分函數,沒有限制。

  • args參數用於將其他參數傳遞給被積分,因此您無需傳遞k因為在該參數上進行積分。 您將需要通過w ,我將在下面顯示。

2. TypeError:需要浮點數

  • 您需要函數W(kR)返回浮點數才能使集成工作。 讓我們遍歷每個值並計算積分。
  • 請記住,您只需要傳遞函數將使用的參數。 sig(R)不使用RW(kR)不使用kR
  • 只需計算並存儲一次傅立葉變換,因為它不依賴於積分。 無需每次都調用W()
  • 為了解決類型錯誤,我們將遍歷傅立葉變換中的數組並計算積分。

     fourier_transform = 3*(np.sin(k*R)-k*R*np.cos(k*R))/(k*R)**3 def sig(): I_one = np.zeros(len(fourier_transform)) def integrand(k, w): return k**2*p_func(k)*w for i, w in enumerate(fourier_transform): I_one[i], err = integrate.quad(integrand, 0.0, np.inf, args = w) print I_one[i] return ((1.0/(2.0*np.pi**2)) * I_one)**0.5 

3.變量和函數的命名約定

這里看看答案。 嘗試使用有意義的變量和函數名稱,以最大程度地減少錯誤和混亂。 所有局部變量和函數均應小寫。 常量的全局變量應為大寫。 這是我的嘗試,但是您將更好地了解這些變量和函數的含義。

#global constants should be capitalized
RHO_M = 3.3e-14
H = 0.73 # km s^-1 Mpc^-1 
EULERS_NUM = 2.718281 # Eulers number
T_CMB = 2.725   
OMEGA_M = 0.27 

#nonconstant variables should be lower case 
mass = data['x'] #Mass of dark matter haloes
radius = ((3*mass)/(RHO_M*4*(3.14)))**(1.0/3.0) # Km // Radius of sphere 
#not sure if this is a constant???
mpc_h = 0.001 # Mpc h^-1 // Wave Dispersion relation 
mpc_radius = mpc_h*radius

#this stays constant for all integrations so let's just compute it once
fourier_transform = 3*(np.sin(mpc_h*radius)*mpc_h*radius*np.cos(mpc_h*radius))/(mpc_h*radius)**3

def t_calc(k): 
    q = k/((OMEGA_M)*H**2)*((T_CMB)/27)**2
#I didn't change this because lower case L creates confusion
    L = np.log(EULERS_NUM+1.84*q)
    c = 14.4 + 325/(1+60.5*q**1.11)
    return L/(L+c*q**2)

def p_calc(k): 
    a = 0.75 
    n = 0.95 
    return a*k**n*t_calc(k)**2

def sig():
    I_one = np.zeros(len(fourier_transform))
    def integrand(k, w):
        return k**2*p_func(k)*w
    for i, w in enumerate(fourier_transform):
        I_one[i], err = integrate.quad(integrand, 0.0, np.inf, args = w)
        print I_one[i]
    return ((1.0/(2.0*np.pi**2)) * I_one)**0.5

5.定義def integrand(k, P)

盡管integrand()是嵌套的,但它仍可以在全局名稱空間中搜索函數P ,因此不要傳遞它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM