How do I fit a function that includes an integral with a variable limit?

淺唱寂寞╮ 提交于 2019-12-11 00:07:30

问题


I'm very new to Python (and also Stack Overflow so sorry if I'm not doing this right!). I'm trying to fit the following equation to some data in order to extract the cosmological parameters ΩM and ΩΛ:

Equation to fit

where

Curly D equation

In my equation, capital curly D=Ho*dl so the Ho has been cancelled out. I'm currently trying to use the ΩM+ΩΛ=1 form. I have the data for m(z) and z, and I know the curly M constant.

This is the code I have at the moment:

import numpy as np
import scipy.integrate as integrate
from scipy.optimize import curve_fit

d=np.loadtxt("data.txt")
z=d[:,0]
m=d[:,7]
c=299792458 #speed of light
M=-18.316469239 #curly M


def fn(Z,OM,OV):
    return np.power((((1+Z)**2)*(1+OM*Z)-Z*(2+Z)*OV),-0.5)

def curve(z,OM,OV):
    return M+5*np.log10(c*(1+z)*integrate.quad(fn,0,z,args=(OM,OV))[0])

parameter = curve_fit(curve,z,m)

When I run this, I get the error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() 
or a.all()

I understand that this is because you can't use an independent array variable as a limit in the quad function, but I'm not sure how I would go about correcting this as nothing I've found or tried to implement has worked. Very much appreciate any help or hints! Thank you in advance.

UPDATE:

here is some example data that I have been using:

z=[0.03, 0.05, 0.026, 0.075, 0.026, 0.014, 0.101, 0.02, 0.036, 0.045, 0.043, 0.018, 0.079, 
0.088, 0.063, 0.071, 0.052, 0.05]
m=[16.26, 17.63, 16.08, 18.43, 16.28, 14.47, 19.16, 15.18, 16.66, 17.61, 17.19, 15.61, 
18.27, 19.28, 18.24, 18.33, 17.54, 17.69]

回答1:


I'm not sure that it is an answer you looking for, but it may help you to find a real solution for your (scientific) problem.

So, on the programming part, the error appears because curve_fit sending a vector of z as a first argument of the function curve However integrate.quad wants two float numbers (integration limits) as the second and third arguments. Well, integrate.quad gets an array in the third argument, and is very upset about this - your strange error message.

NOW I guess you want to integrate from 0 to a biggest z. If so your code should look like this:

import numpy as np
import scipy.integrate as integrate
from scipy.optimize import curve_fit

z=np.array( [0.03, 0.05, 0.026, 0.075, 0.026, 0.014, 0.101, 0.02, 0.036, 0.045, 0.043, 0.018, 0.079, 
0.088, 0.063, 0.071, 0.052, 0.05] )
m=np.array( [16.26, 17.63, 16.08, 18.43, 16.28, 14.47, 19.16, 15.18, 16.66, 17.61, 17.19, 15.61, 
18.27, 19.28, 18.24, 18.33, 17.54, 17.69] )
c=299792458 #speed of light
M=-18.316469239 #curly M


def fn(Z,OM,OV):
    return np.power((((1+Z)**2)*(1+OM*Z)-Z*(2+Z)*OV),-0.5)

def curve(R,OM,OV):
    return M+5*np.log10(c*(1+R)*integrate.quad(fn,0,R[-1],args=(OM,OV))[0])

parameter = curve_fit(curve,z,m)

print parameter

This generates some results:

(array([-61.73621869, -42.41853305]), array([[5.43407019e+15, 2.84207191e+15],
       [2.84207191e+15, 1.48643143e+15]]))

which may or may not be useful numbers. At least now you understand a source of the error and can change your code in such a way, that you will solve the biggest cosmological problem.

Good luck!



来源:https://stackoverflow.com/questions/53400945/how-do-i-fit-a-function-that-includes-an-integral-with-a-variable-limit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!