def m_D(a_x,a_y,a_z): '''calculates the dynamic geometrical tensor of the ellipsoid: to be computed once for every geometry Parameters ---------- 'a_x,a_y,a_z' = three axes of the ellipsoid (in nm) Returns ------- 'D' = dynamic geometrical tensor of the ellipsoid''' D_x_int,err = sp_i.nquad(lambda t,z: f_Dx(t,z,a_x,a_y,a_z), [[0,2.0*np.pi],[0.0,1.0]]) D_y_int,err = sp_i.nquad(lambda t,z: f_Dy(t,z,a_x,a_y,a_z), [[0,2.0*np.pi],[0.0,1.0]]) D_z_int,err = sp_i.nquad(lambda t,z: f_Dz(t,z,a_x,a_y,a_z), [[0,2.0*np.pi],[0.0,1.0]]) D_y = (0.75/np.pi)*D_y_int D_x = (0.75/np.pi)*D_x_int D_z = (0.75/np.pi)*D_z_int D = np.array([[D_x,0.0,0.0],[0.0,D_y,0.0],[0.0,0.0,D_z]]) return D
def Integrandlosv(r): #It's using r, because I define below has limits in r, not x xi = r/rs def sigr(vt,vr): return f(xi, vr, vt, param) * vt * (vr*vr) * 2*np.pi def sigt(vt,vr): return f(xi, vr, vt, param) * vt * (vt*vt) * 2*np.pi def rhofunc2(vt,vr): return f(xi, vr, vt, param) * vt * 2*np.pi vmax = vesc(xi,[rlim, Vmax, rmax, alpha, beta, gamma]) def bounds_vr(): return [0, vmax] #should be +/-vmax, but the function is symmetric, so. def bounds_vt(vr): lim = (vmax*vmax - vr*vr)**0.5 return [0, lim] rhosigr2 = integrate.nquad(sigr, [bounds_vt, bounds_vr])[0] rhosigt2 = integrate.nquad(sigt, [bounds_vt, bounds_vr])[0] rhor = integrate.nquad(rhofunc2, [bounds_vt, bounds_vr])[0] zz = (xi*xi - Xi*Xi) dz = rs*xi / np.sqrt(zz) result = ( zz*rhosigr2 + 0.5*Xi*Xi*rhosigt2 ) * dz / (xi*xi) #!!! 0.5 or no??? return 2*result
def expected_value( self, x): """ Currently, this does the whole sum/integral over the cube support of Z. We may be able to improve this by taking into account how the joint and conditionals factorize, and/or finding a more efficient support. This should be reasonably fast for |Z| <= 2 or 3, and small enough discrete variable cardinalities. It runs in O(n_1 n_2 ... n_k) in the cardinality of the discrete variables, |Z_1| = n_1, etc. It likewise runs in O(V^n) for n continuous Z variables. Factorizing the joint/conditional distributions in the sum could linearize the runtime. """ causal_effect = 0. x = x[self.causes] if self.discrete_Z: discrete_variable_ranges = [ xrange(*(int(self.support[variable][0]), int(self.support[variable][1])+1)) for variable in self.discrete_Z] for z_vals in itertools.product(*discrete_variable_ranges): z_discrete = pd.DataFrame({k : [v] for k, v in zip(self.discrete_Z, z_vals)}) if self.continuous_Z: continuous_Z_ranges = [self.support[variable] for variable in self.continuous_Z] args = z_discrete.join(x).values[0] causal_effect += nquad(self.expectation_integration_function,continuous_Z_ranges,args=args)[0] else: z_discrete = z_discrete[self.admissable_set] exog_predictors = x.join(z_discrete)[self.conditional_density_vars] causal_effect += self.conditional_expectation.fit(data_predict=exog_predictors.values)[0] * self.density.pdf(data_predict=z_discrete.values) return causal_effect elif self.continuous_Z: continuous_Z_ranges = [self.support[var] for var in self.continuous_Z] causal_effect, error = nquad(self.expectation_integration_function,continuous_Z_ranges,args=tuple(x.values[0])) return causal_effect else: return self.conditional_expectation.fit(data_predict=x[self.causes])[0]
def main(): n=6 liste=[q for q in xrange(1,n+1)] func= lambda x1,x2,x3: function([x1,x2,x3]) print integrate.nquad(func,[[0,1],[0,1],[0,1]], opts=[{"epsabs": 1.49e-20},{"epsabs": 1.49e-20},{"epsabs": 1.49e-20}]) func2= lambda y1,y2,y3: another_function(**{"eins": y1,"zwei": y2,"drei": y3}) print integrate.nquad(func2,[[0,1],[0,1],[0,1]], opts=[{"epsabs": 1.49e-20},{"epsabs": 1.49e-20},{"epsabs": 1.49e-20}])
def testZernikeAnnularEval(self): # Obscuration e = 0.61 # Calculate the radius dd = np.sqrt(self.xx**2 + self.yy**2) # Define the invalid range idx = (dd > 1) | (dd < e) # Create the Zernike terms Z = np.zeros(22) # Generate the map of Z12 Z[11] = 1 # Calculate the map of Zernike polynomial Zmap = ZernikeAnnularEval(Z, self.xx, self.yy, e) Zmap[idx] = np.nan # Put the elements to be 0 in the invalid region Zmap[np.isnan(Zmap)] = 0 # Check the normalization for Z1 - Z28 e = 0.61 ansValue = np.pi*(1-e**2) for ii in range(28): Z = np.zeros(28) Z[ii] = 1 normalization = nquad(self._genNormalizedFunc, [[e, 1], [0, 2*np.pi]], args=(Z, e))[0] self.assertAlmostEqual(normalization, ansValue) # Check the orthogonality for Z1 - Z28 for jj in range(28): Z1 = np.zeros(28) Z1[jj] = 1 for ii in range(28): if (ii != jj): Z2 = np.zeros(28) Z2[ii] = 1 orthogonality = nquad(self._genOrthogonalFunc, [[e, 1], [0, 2*np.pi]], args=(Z1, Z2, e))[0] self.assertAlmostEqual(orthogonality, 0)
def simu_YC(Alpha,beta,Z,U,V1,V2,T,Sigma): N=len(T) D=len(U[0]) Y=np.zeros(N,float) for i in range(N): Y[i]=Z[i].dot(Alpha) for j in range(D): def Fbeta(t): return U[i,j]+np.sum(V1[i,j,:]*np.sin( (np.arange(10)+1.)*2.*ma.pi*t/100.)+V2[i,j,:]*np.cos((np.arange(10)+1.)*2.*ma.pi*t/100.))*beta.val([t,T[i]]); Y[i]= Y[i] + integrate.nquad(Fbeta,[[0,T[i]]],opts=[{'epsabs':5e-04}])[0] / T[i] # Erreur sur le label if Sigma>0: Y = Y + np.random.normal(0,Sigma,N) # Labels censurés et temps de censures C=np.random.normal(np.mean(Y)+np.std(Y)/2,np.sqrt(np.std(Y)),N) Yc=np.zeros(N,float) Delta=np.zeros(N) for i in range(N): if C[i]==min(C[i],Y[i]): Yc[i]=C[i] Delta[i]=0 else: Yc[i]=Y[i] Delta[i]=1 return (Y,C,Yc,Delta);
def f_int(): y = 0 if (delta != 0): y, err = integrate.nquad(f, [[-delta, delta], [-delta, delta], [-delta, delta], [-delta, delta]]) else: y = f(0) return 1 / 16.0 / delta**4 * y
def test_matching_tplquad(self): def func3d(x0, x1, x2, c0, c1): return x0 ** 2 + c0 * x1 ** 3 - x0 * x1 + 1 + c1 * np.sin(x2) res = tplquad(func3d, -1, 2, lambda x: -2, lambda x: 2, lambda x, y: -np.pi, lambda x, y: np.pi, args=(2, 3)) res2 = nquad(func3d, [[-np.pi, np.pi], [-2, 2], (-1, 2)], args=(2, 3)) assert_almost_equal(res, res2)
def test_square_aliased_ranges_and_opts(self): def f(y, x): return 1.0 r = [-1, 1] opt = {} assert_quad(nquad(f, [r, r], opts=[opt, opt]), 4.0)
def test_variable_limits(self): scale = .1 def func2(x0, x1, x2, x3, t0, t1): return x0*x1*x3**2 + np.sin(x2) + 1 + (1 if x0 + t1*x1 - t0 > 0 else 0) def lim0(x1, x2, x3, t0, t1): return [scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) - 1, scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) + 1] def lim1(x2, x3, t0, t1): return [scale * (t0*x2 + t1*x3) - 1, scale * (t0*x2 + t1*x3) + 1] def lim2(x3, t0, t1): return [scale * (x3 + t0**2*t1**3) - 1, scale * (x3 + t0**2*t1**3) + 1] def lim3(t0, t1): return [scale * (t0 + t1) - 1, scale * (t0 + t1) + 1] def opts0(x1, x2, x3, t0, t1): return {'points':[t0 - t1*x1]} def opts1(x2, x3, t0, t1): return {} def opts2(x3, t0, t1): return {} def opts3(t0, t1): return {} res = nquad(func2, [lim0, lim1, lim2, lim3], args=(0,0), opts=[opts0, opts1, opts2, opts3]) assert_quad(res, 25.066666666666663)
def SigR(param): a,d,e, Ec, rlim, b, q, Jb, Vmax, rmax, alpha, beta, gamma = param rs = rmax/2.16 # rmax=2.16*rs xlim = rlim/rs def rhoRI(theta, v, x, X): z = (x*x - X*X +10**-10)**.5 aux = 2 * ftheta(x, v, theta, param) * pow(v,2) * np.sin(theta) * 2 * np.pi * rs return aux * x/z def bounds_theta(v,x): return [0, np.pi] def bounds_v(x): vmax = vesc( x, [rlim, Vmax, rmax, alpha, beta, gamma] ) return [0, vmax] #def bounds_r(X): # return [X, xlim] #def result(Xi): # ans = integrate.nquad(rhoRI, [bounds_theta, bounds_v, bounds_r], args=(Xi,))[0] # return ans Xarr = np.linspace(0, xlim, 10) projlist = [] for Xi in Xarr: def rhoRI2(theta,v,x): return rhoRI(theta,v,x,Xi) ans = integrate.nquad(rhoRI2, [bounds_theta, bounds_v, [Xi,xlim]])[0] projlist.append(ans) print 'SigR Xi: ', Xi proj = np.array(projlist) return Xarr*rs, proj/max(proj)
def selectModel(npafIndepVar, npafData, funErrorPDF, lfunPriorParamPDF, lllfPriorParamBounds, lfunModels, lfPriorOdds=[]): ''' Select between two models using a naive quadrature method for integration of probability distributions. Inputs are the data to model, the error pdf for the data, the parameter probability density, a list of 2 element lists of the [lower bound, upper bound] of the arguments of parameter distribution, the list of models to select from and a list of lists of 2 element lists of the model parameter bounds. For discrete parameters, select between functions defined with the different values of the discrete parameters. The outputs are the index of the best model and a list of the odds ratios for each model relative to the best model. ''' from scipy.integrate import nquad import numpy as np npaOR = [] if lfPriorOdds == []: lfPriorOdds = np.ones(len(lfunModels)) nIdx = 0 for funParamPDF, llfParamBounds, funModel in zip(lfunPriorParamPDF, lllfPriorParamBounds, lfunModels): funIntegrand = lambda *x: (funParamPDF(x) * funErrorPDF(npafData - funModel(npafIndepVar, x))) npaOR.append(nquad(funIntegrand, llfParamBounds)*lfPriorOdds[nIdx]) nIdx += 1 npaOR = np.array(npaOR) npaOR = npaOR/np.max(npaOR) nBestModel = np.argmin(npaOR) return nBestModel, npaOR
def _calc_spec_pgamma(self, Eeminus): Eeminus = Eeminus.to('eV').value x_range = [0, 1] eta_range = [0.66982, 31.3] spec_hi = self._mpc2 * nquad(self._H_integrand, [x_range, eta_range], args=[Eeminus], )[0] return spec_hi.value
def integral(self, f): """ Returns the integral of `f` with respect to the currwnt measure over the support. """ from types import FunctionType m = 0 if self.DomType == "set": if type(f) not in [dict, FunctionType]: raise Exception( "The integrand must be a `function` or a `dict`") if type(f) == dict: for p in self.supp: if p in f: m += self.weight[p] * f[p] else: for p in self.supp: try: m += self.weight[p] * f(p) except: pass else: if type(f) != FunctionType: raise Exception("The integrand must be a `function`") from scipy import integrate fw = lambda *x: f(*x) * self.weight(*x) m = integrate.nquad(fw, self.supp)[0] return m
def test_matching_quad(self): def func(x): return x**2 + 1 res, reserr = quad(func, 0, 4) res2, reserr2 = nquad(func, ranges=[[0, 4]]) assert_almost_equal(res, res2) assert_almost_equal(reserr, reserr2)
def Posterior(): func= lambda s,b,mumu: norm.pdf(s,mean_s,sigma_s)*norm.pdf(b,mean_b,sigma_b)*ExtendedPoisson(N,mumu*s+b) func2= lambda mumumu: integrate.nquad(func,[[mean_s - 5*sigma_s,mean_s + 5*sigma_s],[mean_b - 5*sigma_b,mean_b + 5*sigma_b]],[mumumu])[0]#/integrate.nquad(func,[[mean_s - 5*sigma_s,mean_s + 5*sigma_s],[mean_b - 5*sigma_b,mean_b + 5*sigma_b],[1e-15,10]])[0] x=arange(0,5.0,0.2) y=map(func2,x) plt.plot(x,y) plt.show()
def test_densities(self): causes = ['c'] effects = ['d'] admissable_set = ['a'] variable_types={'a': 'c','b': 'c','c': 'c','d' : 'c'} effect = CausalEffect(self.X,causes,effects,admissable_set,variable_types) density = lambda x: effect.density.pdf( data_predict=[x]) integral = nquad( density, [effect.support[d_var] for d_var in admissable_set])[0] print integral assert(abs(integral - 1.) < TOL) x_vals = [np.mean(effect.support[var]) for var in causes] z_vals = [np.mean(effect.support[var]) for var in admissable_set] density = lambda x: effect.conditional_density.pdf(endog_predict=[x], exog_predict=x_vals + z_vals) integral = nquad(density, [effect.support[d_var] for d_var in effects])[0] print x_vals, z_vals,integral assert(abs(integral - 1.) < TOL)
def multi_integrate(func, options): r = c.parse_range(options['range']) try: result = i.nquad(func, r) return c.clean_integrate(result) except Exception as e: return str(e)
def test_matching_dblquad(self): def func2d(x0, x1): return x0**2 + x1**3 - x0 * x1 + 1 res, reserr = dblquad(func2d, -2, 2, lambda x:-3, lambda x:3) res2, reserr2 = nquad(func2d, [[-3, 3], (-2, 2)]) assert_almost_equal(res, res2) assert_almost_equal(reserr, reserr2)
def psi_Kolonderski_full(lp,ls,li,wp,ws,wi,axp,axs,axi): # Integrale come somma; non funziona # (ksx,dksx) = (ksy,dksy) = (kix,dkix) = (kiy,dkiy) = np.linspace(-1000000,1000000,50,retstep=True) # # f = func_Kolonderski(ksx[:,None,None,None],ksy[None,:,None,None],kix[None,None,:,None],kiy[None,None,None,:],lp,ls,li,wp,ws,wi,axp,axs,axi) # return np.sum(np.sum(np.sum(np.sum(f))))*dksx*dksy*dkix*dkiy # Integrale usando le funzioni di scipy: eterno return integ.nquad(func_Kolonderski,[[-np.inf,np.inf],[-np.inf,np.inf],[-np.inf,np.inf],[-np.inf,np.inf]],args=(lp,ls,li,wp,ws,wi,axp,axs,axi))
def com(mass): # must corespond with variables used for integration lol = integrate.nquad(lambda o,m,i: h(o,m,i) * o,\ [bounds_i, bounds_m, bounds_o]) lml = integrade.nquad(lambda o,m,i: h(o,m,i) * m,\ [bounds_i, bounds_m, bounds_o]) lil = integrade.nquad(lambda o,m,i: h(o,m,i) * i,\ [bounds_i, bounds_m, bounds_o]) return lol/mass2, lml/mass2, lil/mass2
def test_fixed_limits(self): def func1(x0, x1, x2, x3): return x0 ** 2 + x1 * x2 - x3 ** 3 + np.sin(x0) + (1 if (x0 - 0.2 * x3 - 0.5 - 0.25 * x1 > 0) else 0) def opts_basic(*args): return {"points": [0.2 * args[2] + 0.5 + 0.25 * args[0]]} res = nquad(func1, [[0, 1], [-1, 1], [0.13, 0.8], [-0.15, 1]], opts=[opts_basic, {}, {}, {}]) assert_quad(res, 1.5267454070738635)
def rhosigrt2theta(r, param = [2.0, -5.3, 2.5, 0.16, 1.5, -9.0, 6.9, 0.086, 21.0, 1.5,1,3,1]): a,d,e, Ec, rlim, b, q, Jb, Vmax, rmax, alpha, beta, gamma = param rs = rmax/2.16 # rmax=2.16*rs xi = r/rs def sigrI(theta, v): return ftheta(xi, v, theta, param) * pow(v,4) * pow( np.cos(theta), 2) * np.sin(theta) def sigtI(theta, v): return ftheta(xi, v, theta, param) * pow(v,4) * pow( np.sin(theta) , 3) vmax = vesc(xi,[rlim, Vmax, rmax, alpha, beta, gamma]) bounds_theta = [0, np.pi] bounds_v = [0, vmax] rhosigr2 = integrate.nquad(sigrI, [bounds_theta, bounds_v])[0] rhosigt2 = integrate.nquad(sigtI, [bounds_theta, bounds_v])[0] return rhosigr2, rhosigt2
def multivariate_gaussian_integration(sigma, lower_limits, upper_limits, mu): n = len(sigma) inv_sigma = np.linalg.inv(sigma) det_sigma = np.linalg.det(sigma) coeff_denominator = (2*np.pi)**(n/2.0)*np.sqrt(abs(det_sigma)) coeff = 1.0/coeff_denominator f = lambda *x : np.exp(-0.5*np.dot(np.dot((np.array(x)-mu), inv_sigma), (np.array(x)-mu).T)) ranges = make_ranges(n, lower_limits, upper_limits) return coeff*integ.nquad(f, ranges)[0]
def compute_expectation(model, fun): # Computes the expectation of fun(th) wrt the posterior distribution, # given by exp(model.log_p_marg(th)) th_shape = model.th_shape L = np.prod(th_shape) lims = [[-np.inf, np.inf]] * L def integrand(*args): th = np.array(args).reshape(th_shape) return np.exp(model.log_p_marg(th)) * fun(th) return integrate.nquad(integrand, lims)[0]
def test_gauss2darea(self): p = numpy.copy(self.p2d) p[2] = self.sigma p[3] = (numpy.random.rand() + 0.1) * self.sigma area = xu.math.Gauss2dArea(*p) (numarea, err) = nquad(xu.math.Gauss2d, [[-numpy.inf, numpy.inf], [-numpy.inf, numpy.inf]], args=tuple(p)) digits = int(numpy.abs(numpy.log10(err))) - 3 self.assertTrue(digits >= 3) self.assertAlmostEqual(area, numarea, places=digits)
def return_occurrence_samples(self, samplechain, sampsize, planetradius, planetperiod): samp = np.zeros(sampsize) for i,x in enumerate( np.random.choice(range(len(samplechain)), size=sampsize)): samp[i] = nquad(self.population_model2, [[planetperiod[0],planetperiod[1]], [planetradius[0], planetradius[1]]], args=[samplechain[x]])[0] self.samp = samp return samp
def test_square_aliased_fn_ranges_and_opts(self): def f(y, x): return 1.0 def fn_range(*args): return (-1, 1) def fn_opt(*args): return {} ranges = [fn_range, fn_range] opts = [fn_opt, fn_opt] assert_quad(nquad(f, ranges, opts=opts), 4.0)
def projecteddensity(param=[2.0, -5.3, 2.5, 0.16, 1.5, -9.0, 6.9, 0.086, 21.0, 1.5, 1,3,1]): a,d,e, Ec, rlim, b, q, Jb, Vmax, rmax, alpha, beta, gamma = param rs = rmax/2.16 # rmax=2.16*rs Ps = (Vmax/0.465)**2.0 # Vmax=0.465*sqrt(Ps) xlim = rlim/rs #in unit of rs dx = 0.001 #*.7kpc * 10 dX = 0.1 projrholist = [] Xlist = [] Xi = 0.00 while Xi<xlim: Integrantlist = [] IntegrantNormlist = [] xlist = [] xi = Xi+0.00001 while xi<xlim: #loop through r/rs def rhofunc(vr,vt): return f(xi, vr, vt, param) * vt vmax = vesc(xi,[rlim, Vmax, rmax, alpha, beta, gamma]) def bounds_vt(): return [0, vmax] def bounds_vr(vt): lim = (vmax*vmax - vt*vt)**0.5 return [0, lim] #marginalize over theta and velocity, as a function of x rho = integrate.nquad(rhofunc, [bounds_vr, bounds_vt])[0] #integrants to be integrated over x, as a function of X (or R/rs), zz = (xi*xi - Xi*Xi) dz = rs*xi / np.sqrt(zz) Integrant = rho*dz Integrantlist.append(Integrant) xlist.append(xi) xi = xi + dx #integrate over X as a function of X #print 'time: ', (time.time() - start_time)/60.0 projrho = integrate.trapz(Integrantlist,xlist) projrholist.append( projrho ) Xlist.append(Xi) print Xi, projrho Xi = Xi + dX return np.asarray(Xlist) * rs, np.asarray(projrholist)/max(projrholist)
def _integrate_nquad(func, bounds): """ Converting the arguments to nquad style :param func: function to integrate :type func: function with parameter x (iterable of length n) :param bounds: bounds for the integration :type bounds: iterable of pairs of length n :return: value of the integral """ f = lambda *x: func(x) return nquad(f,bounds)[0]
def coupled_probability(density_func: Callable[..., np.ndarray], kappa: float = 0.0, alpha: int = 2, dim: int = 1, support: list = [[-np.inf, np.inf]] ) -> Callable[..., np.ndarray]: """ Add description here. Parameters ---------- dist : TYPE DESCRIPTION. dx : float The distance between realizations of the densities. kappa : float, optional Coupling parameter. The default is 0.0. alpha : float, optional DESCRIPTION. The default is 1.0. dim : int, optional The dimension of x, or rank if x is a tensor. The default is 1. Returns ------- [float, np.ndarray] DESCRIPTION. """ # Calculate the risk-bias. kMult = (-alpha * kappa) / (1 + dim*kappa) def raised_density_func(x): return density_func(x) ** (1-kMult) def raised_density_func_integration(*args): if dim == 1: x = np.array(args) else: x = np.array([args]).reshape(1, dim) return density_func(x) ** (1-kMult) # Calculate the normalization factor to the coupled CDF equals 1. division_factor = nquad(raised_density_func_integration, support)[0] # Define a function to calculate coupled densities def coupled_prob(values): return raised_density_func(values) / division_factor # Return the new functions that calculates the coupled density of a value. return coupled_prob
def test_matching_tplquad(self): def func3d(x0, x1, x2, c0, c1): return x0**2 + c0 * x1**3 - x0 * x1 + 1 + c1 * np.sin(x2) res = tplquad(func3d, -1, 2, lambda x: -2, lambda x: 2, lambda x, y: -np.pi, lambda x, y: np.pi, args=(2, 3)) res2 = nquad(func3d, [[-np.pi, np.pi], [-2, 2], (-1, 2)], args=(2, 3)) assert_almost_equal(res, res2)
def alpha1_burket(M_0, r_s): GRADPOT1 = np.zeros((len(theta1)), float) def POTDEF1(z, TheTa1): TheTa = np.sqrt(TheTa1**2 + theta2[l]**2) R = D_d * TheTa Burket_p = BurkertPotential(amp=M_0, a=r_s, normalize=False) Sigma = Burket_p.dens(R, z) kappa = Sigma / SIGMA_CRIT return (4 / theta1[l]) * TheTa1 * kappa / SIGMA_CRIT**2 for l in range(len(theta1)): GRADPOT1[l] = nquad(POTDEF1, [[0, np.inf], [0, theta1[l]]])[0] return GRADPOT1 * SIGMA_CRIT**2
def test_fixed_limits(self): def func1(x0, x1, x2, x3): val = (x0**2 + x1 * x2 - x3**3 + np.sin(x0) + (1 if (x0 - 0.2 * x3 - 0.5 - 0.25 * x1 > 0) else 0)) return val def opts_basic(*args): return {'points': [0.2 * args[2] + 0.5 + 0.25 * args[0]]} res = nquad(func1, [[0, 1], [-1, 1], [.13, .8], [-.15, 1]], opts=[opts_basic, {}, {}, {}], full_output=True) assert_quad(res[:-1], 1.5267454070738635) assert_(res[-1]['neval'] > 0 and res[-1]['neval'] < 4e5)
def integrate_evidence(prior_logp_expr, datum_logp_expr, data_syms, theta_syms, data_values, theta0, theta_bounds): """ Generic function for computing Model Evidence by numerical integration of the posterior distribution, based on a symbolicly-expressed probability model for the data and parameters along with observed data. Returns an (logev, logerr) tuple, where logev is the natural logarithm of the computed Model Evidence, and logerr the natural logarithm of the absolute error bound in the integration. Implementation note: calls `find_map` in order to find the mode and characteristic lengthscales of the posterior distribution, so as to assist the integration algorithm by highlighting the small high-density region around the mode. """ std_dev_multiples = [-10, 0, 10] map_optres = find_map(prior_logp_expr, datum_logp_expr, data_syms, theta_syms, data_values, theta0, theta_bounds) all_syms = [list(data_syms), list(theta_syms)] lam_f_n = lambdify(all_syms, datum_logp_expr) lam_f_prior = lambdify(all_syms, prior_logp_expr) pvalues = [] + list(data_values) def f(*theta): ## NOTE we're normalizing such that the density is 1 at the mode of the distribution. return np.exp( np.sum(lam_f_n(pvalues, theta)) + lam_f_prior(pvalues, theta) + map_optres.fun) cov = np_linalg.inv(map_optres.hess) def intgr_points(i_var): low, high = theta_bounds[i_var] mode = map_optres.x[i_var] std_dev = cov[i_var, i_var]**0.5 ret = [] for k in std_dev_multiples: p = mode + (k * std_dev) if (low < p < high): ret += [p] return ret v, err = intgr.nquad( f, theta_bounds, ## NOTE we're marking the region surrounding the mode as requiring extra attention from the integration algorithm, ## as the distribution will be extremely peaked around it; ## we use the Hessian to find the characteristic variation lengths around that mode. opts=[{ 'points': intgr_points(i_var) } for i_var in range(len(theta_syms))]) return (np.log(v) - map_optres.fun, np.log(err) - map_optres.fun)
def complex_nquad(integrand, ranges, **kwargs) -> Tuple[complex, tuple, tuple]: """ As :func:`scipy.integrate.nquad`, but works with complex integrands. Parameters ---------- integrand The function to integrate. a The lower limit of integration. b The upper limit of integration. kwargs Additional keyword arguments are passed to :func:`scipy.integrate.nquad`. Returns ------- (result, real_extras, imag_extras) A tuple containing the result, as well as the other things returned by :func:`scipy.integrate.nquad` for the real and imaginary parts separately. """ def real_func(y, x): return np.real(integrand(y, x)) def imag_func(y, x): return np.imag(integrand(y, x)) real_integral = integ.nquad(real_func, ranges, **kwargs) imag_integral = integ.nquad(imag_func, ranges, **kwargs) return ( real_integral[0] + (1j * imag_integral[0]), real_integral[1:], imag_integral[1:], )
def rho(s): ran = [[s.H.min(), s.H.max()], [s.T.min(), s.T.max()]] print('------------------------------------------') print('calculando media H') s.mh = nquad(lambda h, t: h * s.pdf(h, t), ran)[0] if s.H.mean() - s.mh > 1 or s.H.mean() - s.mh < -1: return 'erro no calculo de mh = %.6f' % s.mh print('calculando media H = %.6f' % s.mh) print('calculando media**2 H') s.m2h = nquad(lambda h, t: h**2 * s.pdf(h, t), ran)[0] print('calculando media**2 H = %.6f' % s.m2h) print('calculando media T') s.mt = nquad(lambda h, t: t * s.pdf(h, t), ran)[0] print('calculando media T = %.6f' % s.mt) print('calculando media **T') s.m2t = nquad(lambda h, t: t**2 * s.pdf(h, t), ran)[0] print('calculando media **T = %.6f' % s.m2t) print('calculando E') s.mht = nquad(lambda h, t: h * t * s.pdf(h, t), ran)[0] print('calculando mht = %.6f' % s.mht) print('calculando desvio padrao H') s.dph = np.sqrt(s.m2h - s.mh**2) #desvio padrao print('calculando desvio padrao H = %.6f' % s.dph) print('calculando desvio padrao de T') s.dpt = np.sqrt(s.m2t - s.mt**2) print('calculando desvio padrao de T = %.6f' % s.dpt) s.rhomdc = (s.mht - s.mh * s.mt) / (s.dph * s.dpt) print('calculo rho terminado = ', s.rhomdc) print('------------------------------------------') return s.rhomdc
def C(self, *xs): """ Args: value: the points where you want to calculate the gaussian copula Returns: the copula in tab, with a precision of quadstep. """ bounds = [] for x in xs: # specific case where 0 is an argument, so the result is 0. if x <= 0: return 0 bounds.append([0, x]) res, _ = spi.nquad(self.c, bounds, opts={'epsabs': 1e-3}) return res
def IntegrateOnSphere(self): raggio = self.raggio; def dFx(theta,phi): T_xx,T_xy,T_xz,T_yx,T_yy,T_yz,T_zx,T_zy,T_zz = self.MaxwellTensorDotR(theta,phi,raggio); dF = T_xx*(sin(theta)*cos(phi)) + T_xy*(sin(theta)*sin(phi)) + T_xz*cos(theta); return np.real( dF * sin(theta) * raggio**2 ) def dFy(theta,phi): T_xx,T_xy,T_xz,T_yx,T_yy,T_yz,T_zx,T_zy,T_zz = self.MaxwellTensorDotR(theta,phi,raggio); dF = T_yx*(sin(theta)*cos(phi)) + T_yy*(sin(theta)*sin(phi)) + T_yz*cos(theta); return np.real( dF * sin(theta) * raggio**2 ) def dFz(theta,phi): T_xx,T_xy,T_xz,T_yx,T_yy,T_yz,T_zx,T_zy,T_zz = self.MaxwellTensorDotR(theta,phi,raggio); dF = T_zx*(sin(theta)*cos(phi)) + T_zy*(sin(theta)*sin(phi)) + T_zz*cos(theta); return np.real( dF * sin(theta) * raggio**2 ) F_x = integrate.nquad(dFx, [[0,pi],[0,2*pi]]); F_y = integrate.nquad(dFy, [[0,pi],[0,2*pi]]); F_z = integrate.nquad(dFz, [[0,pi],[0,2*pi]]); return F_x,F_y,F_z
def main(): print(quad(lambda x: np.exp(-x), 0, np.inf)) # 一元积分,生成两个数,第二个数是误差范围 print(dblquad(lambda t, x: np.exp(-x * t) / t ** 3, 0, np.inf, lambda x: 1, lambda x: np.inf)) # 二元积分 def f(x, y): return x * y # 定义x,y的边界: def bound_y(): return [0, 0.5] def bound_x(y): return [0, 1 - 2 * y] print(nquad(f, [bound_x, bound_y]))
def get_ref(phase_angle, i=None, e=None): omega = 0.042 g = -0.37 b0_s = 2.5 h_s = 0.079 b0_c = 0.188 h_c = 0.017 theta = 15. r = [] r_err = [] if type(phase_angle) is np.ndarray: if i is not None and e is not None: for alpha, ii, ee in zip(phase_angle, i, e): r_i = hapke_int(ii, ee, alpha, omega, theta, h_s, b0_s, h_c, b0_c, [g], 10) r_err_i = 0 r.append(r_i) r_err.append(r_err_i) else: for alpha in phase_angle: r_i, r_err_i = nquad(hapke_int, [[0, np.pi / 2], [0, np.pi]], args=(alpha, omega, theta, h_s, b0_s, h_c, b0_c, [g], 10)) r.append(r_i) r_err.append(r_err_i) return np.array(r), np.array(r_err) else: if i is not None and e is not None: r_i = hapke_int(i, e, phase_angle, omega, theta, h_s, b0_s, h_c, b0_c, [g], 10) r_err_i = 0 else: r_i, r_err_i = nquad(hapke_int, [[0, np.pi / 2], [0, np.pi]], args=(phase_angle, omega, theta, h_s, b0_s, h_c, b0_c, [g], 10)) return r_i, r_err_i
def from_pdf_2d(pdf: callable, xrange: list, yrange: list, gridsize: list): z = np.empty(gridsize) dx, dy = (xrange[1] - xrange[0]) / gridsize[0], (yrange[1] - yrange[0]) / gridsize[1] for i in range(gridsize[0]): for j in range(gridsize[1]): z[i, j] = integrate.nquad(pdf, ranges=( (xrange[0] + dx * i, xrange[0] + dx * (i + 1)), (yrange[0] + dy * j, yrange[0] + dy * (j + 1))))[0] / dx / dy x = np.linspace(xrange[0] + dx / 2, xrange[1] - dx / 2, gridsize[0]) y = np.linspace(yrange[0] + dy / 2, yrange[1] - dy / 2, gridsize[1]) return x, y, z
def al_integration_in_direction(f, start_radian, end_radian, bins, bin_width): from scipy import integrate direction_prob = integrate.nquad(f, [[0, inf], [start_radian, end_radian]])[0] density_expected_ = array([ sp.integrate.nquad(f, [[x_, x_ + bin_width], [start_radian, end_radian]]) for x_ in bins[:-1] ])[:, 0] density_expected = density_expected_ / direction_prob / bin_width y_cdf = np.append(0, np.cumsum(density_expected) * bin_width) # y_cdf = array([integrate.nquad(f, [[0, x_val], [start_radian, end_radian]]) # for x_val in bins])[:, 0]/direction_prob # y_cdf = None return bins, density_expected, y_cdf, direction_prob
def SingularityIntegral(integrand): def smooth_integrand(x, y, z): if x**2 + y**2 + z**2 == 0: return 0 else: return integrand(x, y, z) * (1 - BumpFunction(4 * (x**2 + y**2 + z**2))) def singular_integrand(x, y, z): return integrand(x, y, z) * BumpFunction(4 * (x**2 + y**2 + z**2)) SmoothIntegral = integrate.nquad(lambda x, y, z: smooth_integrand(x, y, z), [[-.5, .5], [-.5, .5], [-.5, .5]])[0] SingularIntegral = SphericalCoordinateIntegrate(singular_integrand) return SmoothIntegral + SingularIntegral
def Gauss_integrateA(self, material_fun): # for index in np.ndindex(self.shape): for index in [0, 0], [1, 1]: for ki, kj in itertools.product(np.arange(0, self.N[0]), np.arange(0, self.N[1])): k = [ki, kj] print(k) l_k = lambda x0, x1: material_fun * lagrange_d([x0, x1], self. N, k) int = nquad(l_k, [[-1, 1], [-1, 1]]) print(int) self.val[index[0], index[1], ki, kj] = int[0] print(self.val)
def fmht(obj, ran, mh, m2h, mt, m2t): print('calculando E') mht = nquad(lambda h, t: h * t * obj.pdf(h, t), ran)[0] print('calculando mht = %.6f' % mht) print('calculando desvio padrao H') dph = np.sqrt(m2h - mh**2) #desvio padrao print('calculando desvio padrao H = %.6f' % dph) print('calculando desvio padrao de T') dpt = np.sqrt(m2t - mt**2) print('calculando desvio padrao de T = %.6f' % dpt) rho = (mht - mh * mt) / (dph * dpt) print('calculo rho terminado = ', rho)
def approximate_count_from_to(self, x_min, x_max, x_columnID): start = datetime.now() if self.dimension is 1: # average = self.approximate_ave_from_to(x_min,x_max,x_columnID) def f_p(*args): return np.exp( self.kde.score_samples(np.array(args).reshape(1, -1))) result = integrate.quad( f_p, x_min, x_max, epsabs=epsabs, epsrel=epsrel)[0] * self.num_training_points # return result if self.dimension > 1: data_range_length_half = [ (max(self.training_data.features[:, i]) - min(self.training_data.features[:, i])) * 0.5 for i in range(self.dimension) ] data_range = [[ min(self.training_data.features[:, i]) - data_range_length_half[i], max(self.training_data.features[:, i]) + data_range_length_half[i] ] for i in range(self.dimension)] # generate the integral bounds bounds = [] for i in range(x_columnID): bounds.append(data_range[i]) bounds.append([x_min, x_max]) # print(bounds) for i in range(x_columnID + 1, self.dimension): bounds.append(data_range[i]) def f_p(*args): return np.exp( self.kde.score_samples(np.array(args).reshape(1, -1))) result = integrate.nquad(f_p, bounds, opts=opts)[0] * self.num_training_points end = datetime.now() time_cost = (end - start).total_seconds() if self.b_print_time_cost: self.logger.info("Approximate count: %.4f." % result) self.logger.info("Time spent for approximate COUNT: %.4fs." % time_cost) return int(result), time_cost
def main(): print(quad(lambda x: np.exp(-x), 0, np.inf)) print( dblquad(lambda t, x: np.exp(-x * t) / t**3, 0, np.inf, lambda x: 1, lambda x: np.inf)) def f(x, y): return x * y def bound_y(): return [0, 0.5] def bound_x(y): return [0, 1 - 2 * y] print(nquad(f, [bound_x, bound_y]))
def D_num(m, n, i, j): if (m, n, i, j) in cache: return cache[m, n, i, j] if (n, m, j, i) in cache: return cache[n, m, j, i] if (i, j, m, n) in cache: return cache[i, j, m, n] if (j, i, n, m) in cache: return cache[j, i, n, m] m, n, i, j = map(float, (m, n, i, j)) ranges = [(0, m), (0, n), (m, m+i), (n, n+j)] prec = {'epsrel': 1e-4, 'epsabs': 1e-4} val = nquad(integrand, ranges, opts=prec) result = 1./(m*n*i*j)*val[0] cache[(m, n, i, j)] = result return result
def SphericalCoordinateIntegrate(integrand): def spherical_integrand(r, thet1, thet2, thet3): if r == 0: return 0 else: return integrand( r * np.cos(thet1), r * np.sin(thet1) * np.cos(thet2), r * np.sin(thet1) * np.sin(thet2) * np.cos(thet3), r * np.sin(thet1) * np.sin(thet2) * np.sin(thet3)) * r**3 * np.sin(thet1)**2 * np.sin(thet2) return integrate.nquad( lambda r, thet1, thet2, thet3: spherical_integrand( r, thet1, thet2, thet3), [[0, .5], [0, np.pi], [0, np.pi], [0, 2 * np.pi]])[0]
def compute_norm( X, R_sq, grid_n_samples, offset, integration="adaptative", verbose=False ): dim = X.shape[1] if integration == "adaptative": result = 0 for i in range(R_sq.shape[1]): tidy_data = np.hstack((X, R_sq[:, i].reshape(X.shape[0], 1))) interp = ndsplines.make_interp_spline_from_tidy( tidy_data, range(dim), # columns to use as independent variable data [dim], # columns to use as dependent variable data ) def f(*argv): return interp(argv)[0, 0] if verbose: print("Initiating adaptative integration") result += integrate.nquad( f, [[offset, 1 - offset]] * dim, full_output=False )[0] return np.sqrt(result) reduction_indices = [ range(int(grid_n_samples[i] * offset), int(grid_n_samples[i] * (1 - offset))) for i in range(len(grid_n_samples)) ] X_grid = dataset_to_grid(X, grid_n_samples, dim) X_red_indices = reduction_indices + [range(dim)] X_crop_grid = crop_matrix(X_grid, X_red_indices) R_sq_grid = dataset_to_grid(R_sq, grid_n_samples, R_sq.shape[1]) R_sq_red_indices = reduction_indices + [range(R_sq.shape[1])] R_sq_crop_grid = crop_matrix(R_sq_grid, R_sq_red_indices) n_crop = 1 grid_n_samples_crop = [len(r) for r in reduction_indices] for r in grid_n_samples_crop: n_crop = n_crop * r X_crop = X_crop_grid.reshape(n_crop, X.shape[1]) R_sq_crop = R_sq_crop_grid.reshape(n_crop, R_sq.shape[1]) if verbose: print("Initiating grid integration") return np.sqrt( quadrature_regular_grid(X_crop, R_sq_crop, grid_n_samples_crop).sum() )
def test_normal_simplex(): mult_logit = transform.MultinomialLogitTransform() NormalSimplex = NormalMessage.transformed(mult_logit) message = NormalSimplex([-1, 2], [0.3, 0.3]) check_numerical_gradient_hessians(message, message.sample()) def func(*p): return np.exp(message.factor(p)).prod() def simplex_lims(*args): return [0, 1 - sum(args)] # verify transformation normalises correctly res, err = integrate.nquad(func, [simplex_lims] * message.size) assert res == pytest.approx(1, rel=err)
def _cdf(self, u, v, rotation=0, *theta): """! @brief Default implementation of the cumulative density function. Very slow. Recommended to replace with an analytic CDF if possible. @param theta Copula parameter list @param rotation <b>int</b> copula rotation parameter @param u <b>np_1darray</b> Rank CDF data vector @param v <b>np_1darray</b> Rank CDF data vector """ cdf_vector = np.zeros(np.asarray(u).size) for i, (ui, vi) in enumerate(zip(u, v)): ranges = np.array([[0, ui], [0, vi]]) cdf_vector[i] = spi.nquad(self.pdf, ranges, args=(rotation, theta), opts={'limit': 20})[0] return cdf_vector
def integrate(self, density_matrix, i, j): g_i = self.basis_set[i] g_j = self.basis_set[j] if density_matrix is not self.density_matrix: self.density_matrix = density_matrix self.electron_density = {} def electron_density(x, y, z): if (x, y, z) not in self.electron_density: density = 0 for a, basis_a in enumerate(self.basis_set): for b, basis_b in enumerate(self.basis_set): if a == b: density += density_matrix.item( a, b) * basis_a.value(x, y, z)**2 elif a < b: density += 2 * basis_a.value( x, y, z) * density_matrix.item( a, b) * basis_b.value(x, y, z) self.electron_density[(x, y, z)] = density return self.electron_density[(x, y, z)] def integrand(rho, theta, phi): x = rho * sin(theta) * cos(phi) y = rho * sin(theta) * sin(phi) z = rho * cos(theta) return g_i.value(x, y, z) * (self.exchange_potential.calculate(electron_density(x, y, z)) + self.correlation_potential.calculate(electron_density(x, y, z))) * g_j.value(x, y, z) * rho**2 \ * sin(theta) integral, error = integrate.nquad( integrand, [[0.0, self.int_space], [0.0, np.pi], [0.0, 2 * np.pi]], opts=[{ 'epsabs': self.epsabs, 'epsrel': self.epsrel }, { 'epsabs': self.epsabs, 'epsrel': self.epsrel }, { 'epsabs': self.epsabs, 'epsrel': self.epsrel }]) return integral
def dIdE(self, E): """ Return intensity spectrum of blazars. Since this is only used for sub-bin apportioning of photons, we use a single index approximation (the source count function uses the full form) """ Gamma = 2.37 # Assumed spectral index for mAGN self.dIdEval = integrate.nquad( lambda L, z: self.dVdz(z) * self.phi_gamma(L, z) * self.dFdE( E, z, L, Gamma) * (1 / (np.sqrt(2 * np.pi) * self.Gamma_sigma)) * np.exp(-(Gamma - self.Gamma_mean)**2 / (2 * self.Gamma_sigma**2)) * np.exp(-self.Tau(E, z)), [[self.Lmin, self.Lmax], [self.zmin, self.zmax]], opts=[self.opts0, self.opts0, self.opts0])[0] return self.dIdEval
def tvoPrice_formulaAlternative(S0, sig0, K, T, TV, H, rho, nu): X0 = np.log(S0 / K) M0 = sig0**2 * integrate.quad(lambda x: np.exp(2 * nu**2 * x**(2 * H)), 0, T)[0] I = integrate.nquad(integrandGeneral, [bounds_r, bounds_tau], args=(nu, H, T))[0] C = bs_normalized(X0, M0) d1 = X0 / np.sqrt(M0) + np.sqrt(M0) / 2 d2 = d1 - np.sqrt(M0) Cx = np.exp(X0) * norm.cdf(d1) Cxw = np.exp( -d2**2 / 2) / (2 * np.sqrt(2 * math.pi * M0)) * (1 / 2 - X0 / M0) Fxwh = -Cx / 2 / (M0**(3 / 2)) + Cxw / np.sqrt(M0) price = 2 * nu * rho * Fxwh * (sig0**3) * I + C / np.sqrt(M0) price = price * K * TV * np.sqrt(T) return price
def alpha2_MN(M2, a2, b2): GRADPOT1 = np.zeros((len(theta1)), float) def POTDEF1(z, TheTa2): TheTa = np.sqrt(TheTa2**2 + theta1[l]**2) R = D_d * TheTa MN_Bulge_p = MiyamotoNagaiPotential(amp=M2, a=a2, b=b2, normalize=False) Sigma = MN_Bulge_p.dens(R, z) kappa = Sigma / SIGMA_CRIT return (4 / theta2[l]) * TheTa2 * kappa / SIGMA_CRIT**2 for l in range(len(theta1)): GRADPOT1[l] = nquad(POTDEF1, [[0, np.inf], [0, theta2[l]]])[0] return GRADPOT1 * (SIGMA_CRIT**2)
def example_nquad(): import scipy.integrate as integrate def f(x, y, z): return x * y * z def bounds_z(): return [1, 2] def bounds_y(*args): return [2, 3] def bounds_x(*args): return [0, 1] result = integrate.nquad(f, [bounds_x, bounds_y, bounds_z]) print(result)
def test_variable_limits(self): scale = .1 def func2(x0, x1, x2, x3, t0, t1): val = (x0 * x1 * x3**2 + np.sin(x2) + 1 + (1 if x0 + t1 * x1 - t0 > 0 else 0)) return val def lim0(x1, x2, x3, t0, t1): return [ scale * (x1**2 + x2 + np.cos(x3) * t0 * t1 + 1) - 1, scale * (x1**2 + x2 + np.cos(x3) * t0 * t1 + 1) + 1 ] def lim1(x2, x3, t0, t1): return [ scale * (t0 * x2 + t1 * x3) - 1, scale * (t0 * x2 + t1 * x3) + 1 ] def lim2(x3, t0, t1): return [ scale * (x3 + t0**2 * t1**3) - 1, scale * (x3 + t0**2 * t1**3) + 1 ] def lim3(t0, t1): return [scale * (t0 + t1) - 1, scale * (t0 + t1) + 1] def opts0(x1, x2, x3, t0, t1): return {'points': [t0 - t1 * x1]} def opts1(x2, x3, t0, t1): return {} def opts2(x3, t0, t1): return {} def opts3(t0, t1): return {} res = nquad(func2, [lim0, lim1, lim2, lim3], args=(0, 0), opts=[opts0, opts1, opts2, opts3]) assert_quad(res, 25.066666666666663)
def p_spectrum_hbar(p_0_b_dsnb, b_dsnb_min, b_dsnb_max, p_0_b_ccatmo, b_ccatmo_min, b_ccatmo_max, p_0_b_reactor, b_reactor_min, b_reactor_max, p_0_s, s_min, s_max, fraction_signal, fraction_dsnb, fraction_ccatmo, fraction_reactor, dataset): """ equation 7 of the GERDA paper conditional probabilities to find the observed spectrum given the hypothesis Hbar (signal and background) is true or not true :param p_0_b_dsnb: prior probability for the number of expected DSNB background events (float) :param b_dsnb_min: lower integration limit for the DSNB background (float) :param b_dsnb_max: upper integration limit for the DSNB background (float) :param p_0_b_ccatmo: prior probabilities for the number of expected CC atmospheric background events (float) :param b_ccatmo_min: lower integration limit for the CC atmospheric background (float) :param b_ccatmo_max: upper integration limit for the CC atmospheric background (float) :param p_0_b_reactor: prior probabilities for the number of expected reactor background events (float) :param b_reactor_min: lower integration limit for the reactor background (float) :param b_reactor_max: upper integration limit for the reactor background (float) :param p_0_s: prior probability for the number of expected signal events (float) :param s_min: lower integration limit for the signal events (float) :param s_max: upper integration limit for the signal events (float) :param fraction_signal: normalized shapes of the signal spectra * bin-width for each bin, equivalent to the number of signal events per bin from the theoretical spectrum (np.array of float) :param fraction_dsnb: normalized shapes of the DSNB background spectra * bin-width for each bin, equivalent to the number of DSNB background events per bin from the theoretical spectrum (np.array of float) :param fraction_ccatmo: normalized shapes of the CC atmo. background spectra * bin-width for each bin, equivalent to the number of CC atmo. background events per bin from the theoretical spectrum (np.array of float) :param fraction_reactor: normalized shapes of the reactor background spectra * bin-width for each bin, equivalent to the number of reactor background events per bin from the theoretical spectrum (np.array of float) :param dataset: 'observed' number of events for each bin from the dataset ('observed' spectrum) (np.array of float) :return: conditional probability to find the observed spectrum given the hypothesis Hbar is true or not true (float) """ # calculate integral over log_p_spectrum_sb over s, b_dsnb, b_ccatmo and b_reactor (float): integral = integrate.nquad( p_spectrum_sb, [[b_dsnb_min, b_dsnb_max], [b_ccatmo_min, b_ccatmo_max], [b_reactor_min, b_reactor_max], [s_min, s_max]], args=(fraction_signal, fraction_dsnb, fraction_ccatmo, fraction_reactor, dataset), full_output=True) # print(integral) # multiply the integral with the prior probabilities (float): result = integral[0] * p_0_s * p_0_b_dsnb * p_0_b_ccatmo * p_0_b_reactor return result