0

I'm having some computational problems with the following code:

import numpy as np
from numpy import arange
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from scipy.integrate import quad
import matplotlib as mpl
mpl.rcParams['agg.path.chunksize'] = 10000

# parameters

Ms = 100                                #GeV  Singlet Mass
Me = 0.511e-3                           #Gev Electron Mass
Mp = 1.22e19                            #GeV Planck Mass                                   
gs = 106.75                             # Entropy dof
H0 = 2.133*(0.7)*1e-42                  # GeV Hubble parameter (unused)
gx = 2                                  # WIMP's dof
g = 100                                 # total dof
sigmav=[1e-25,1e-11,1e-12]              # cross section's order of magnitude 

xi=1e-2
xe=1e2
npts=int(1e5)
x = np.linspace(xi, xe, npts)

def fMB(p,x,m):
    return np.exp(-x*np.sqrt(1+p*p/(m*m)))*p*p
def neq(x,m):
    return (gx/(2*np.pi*np.pi))*quad(fMB, 0, np.inf, args=(x,m))[0]
def neq_nr(x,m):
    return 2*(m**2/(2*np.pi*x))**(3/2)*np.exp(-x)
def stot(x):
    return (2*np.pi*np.pi/45)*gs*Ms*Ms*Ms/(x*x*x)
def Yeq(x,m):
    return neq(x,m)/stot(x)
Yeq2=np.vectorize(Yeq)
def Yeq_nr(x):
    return 0.145*(gx/gs)*(x)**(3/2)*np.exp(-x)
def Yeq_r(x):
    return 0.278*(3*gx/4)/gs
def Ytot(x):
    if np.any(x<=1):
        return Yeq_r(x)
    else:
        return Yeq_nr(x)

def eqd(yl,x,Ms,σv):
    '''
    Ms  [GeV]     : Singlet Mass
    σv: [1/GeV^2] : ⟨σv⟩
    '''                           
    H = 1.67*g**(1/2)*Ms**2/Mp
    dyl = -neq(x,Ms)*σv*(yl**2-Yeq(x,Ms)**2)/(x**(-2)*H*x*Yeq(x,Ms)) #occorre ancora dividere per Yeq_nr(x) oppure Yeq(x)
    return dyl


y0=1e-15
yl0 =  odeint( eqd, y0, x,args=(Ms,sigmav[0]), full_output=True)
yl1 =  odeint( eqd, y0, x,args=(Ms,sigmav[1]), full_output=True)
yl2 =  odeint( eqd, y0, x,args=(Ms,sigmav[2]), full_output=True)

fig = plt.figure(figsize=(11,8))
plt.loglog(x,yl0[0],  label = r'$\langle σ v\rangle = %s {\rm GeV}^{-2}$'%(sigmav[0]))
plt.loglog(x,yl1[0],  label = r'$\langle σ v\rangle = %s {\rm GeV}^{-2}$'%(sigmav[1]))
plt.loglog(x,yl2[0],  label = r'$\langle σ v\rangle = %s {\rm GeV}^{-2}$'%(sigmav[2]))
plt.loglog(x,Yeq_nr(x), '--', label = '$Y_{EQ}^{nr}$')
plt.loglog(x,Yeq2(x,Ms), '--', label = '$Y_{EQ}$')
plt.ylim(ymax=0.1,ymin=y0)
plt.xlim(xmax=xe,xmin=xi)
plt.xlabel('$x = m_χ/T$', size= 15)
plt.ylabel('$Y$', size= 15)
plt.title('$m_χ = %s$ GeV'%(Ms), size= 15)
plt.legend(loc='best',fontsize=12)
plt.grid(True)
plt.savefig('abundance.jpg',bbox_inches='tight', dpi=150)

In particular, as soon as I use little values of sigmav (ranging from 10^-12 to 10^-25) the solution is well displayed, but making use of bigger values (starting from 10^-11) I obtain problems and I guess is a order of magnitudes problem, but I don't know how to handle it!

Thanks to everyone!

Edit 1: I'm uploading a plot making use of three different values of sigmav and as you may see the bigger one (1e-10) is showing (I guess) precision problems plot_1

Fredrigo6
  • 1
  • 4
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Progman Apr 27 '22 at 18:33
  • "I obtain problems" is not very descriptive. What happens? I changed your first `sigmav` to `1e-10` and it did create a graph. – Tim Roberts Apr 27 '22 at 18:54
  • Also relevant: [Why should I use normalised units in numerical integration?](https://stackoverflow.com/q/68500704/2127008) – Wrzlprmft Apr 28 '22 at 05:57
  • @TimRoberts I'm sorry for being unclear, I meant that the graph I obtain isn't well behaved as the one with sigmav = 1e-12, 1e-14 etc. To give you an example, I edited the post with a plot making use of a sigmav = 1e-10. As you can see, something is wrong (and I guess is related with precision) in the 1e-10 plot with respect to the others. – Fredrigo6 Apr 28 '22 at 07:21
  • @TimRoberts P.S. if 1e-10 is working for you, is this just a problem of mine? What can cause it then? – Fredrigo6 Apr 28 '22 at 08:13
  • That's exactly the same plot I got. You didn't describe what the problem was, so I didn't realize it was bad. – Tim Roberts Apr 28 '22 at 16:20
  • It would take a fair amount of time to analyze this. I suspect you're seeing accumulated round-off errors due to very small numbers, or maybe subtracting numbers very close to each other. Doubles only keep about 16 digits of precision. Did you notice the warning that the integration does not converge in the `quad` function for the first value? – Tim Roberts Apr 28 '22 at 16:37
  • Yeah I noticed it, but I also plotted the same function I integrate and get the error for and It's perfectly smooth and regular, so I decided to ignore it after all. Is there a way to get around these precision problems? Maybe keeping more digits of precision? To be honest, I'm lost and I don't know how to solve this problem – Fredrigo6 Apr 29 '22 at 07:44

0 Answers0