def P_BTZn(n,R,rh,l,pm1,Om,lam,sig): b = fp.sqrt(R**2-rh**2)/l lim = 20*sig*rh/b/l**2 print('limit: ',lim) Zm = fp.mpf(1) #rh**2/(R**2-rh**2)*(R**2/rh**2 * fp.cosh(2*fp.pi*rh/l * n) - 1) Zp = rh**2/(R**2-rh**2)*(R**2/rh**2 * fp.cosh(2*fp.pi*rh/l * n) + 1) print('Zm: ',Zm, 'Zp: ',Zp, 'acosh(Zp): ', fp.mpf(mp.acosh(Zp))) #print(Zm,fp.acosh(Zm)) # plt.figure() # xaxis = fp.linspace(0,lim/5,50) # yaxis = [f02(x,n,R,rh,l,pm1,Om,lam,sig) for x in xaxis] # plt.plot(xaxis,yaxis) # plt.show() if pm1==-1 or pm1==1 or pm1==0: if n==0: return 0\ - fp.quad(lambda x: f02(x,n,R,rh,l,pm1,Om,lam,sig),[0,fp.mpf(mp.acosh(Zp))])\ - fp.quad(lambda x: f02(x,n,R,rh,l,pm1,Om,lam,sig),[fp.mpf(mp.acosh(Zp)),lim]) #fp.quad(lambda x: f01(x,n,R,rh,l,pm1,Om,lam,sig),[-fp.inf,fp.inf]) # else: # if fp.cosh(lim) < Zm or Zm < 1: # return fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ # - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[0,lim]) # else: # return fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ # - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[0,fp.mpf(mp.acosh(Zm))])\ # - fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ # - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[fp.mpf(mp.acosh(Zm)),lim]) else: print("Please enter a value of 1, -1, or 0 for pm1.")
def discrete_util(self, tick, elapsed=0.0): lower = Time.tick2min(tick) - Time.TIMEUNIT/2.0 upper = lower + Time.TIMEUNIT if tick == 0: util = fp.quad(self._marginal_util, [0.0, Time.TIMEUNIT/2.0]) + \ fp.quad(self._marginal_util, [Time.TIMELENG-Time.TIMEUNIT/2.0, Time.TIMELENG]) else: util = fp.quad(self._marginal_util, [lower, upper]) return util
def discrete_util(self, tick, elapsed=0.0): lower = Time.tick2min(tick) - Time.TIMEUNIT / 2.0 upper = lower + Time.TIMEUNIT if tick == 0: util = fp.quad(self._marginal_util, [0.0, Time.TIMEUNIT/2.0]) + \ fp.quad(self._marginal_util, [Time.TIMELENG-Time.TIMEUNIT/2.0, Time.TIMELENG]) else: util = fp.quad(self._marginal_util, [lower, upper]) return util
def integrand_btz_n(u, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0): s_int_fnc = lambda s: lam**2 * fp.exp(-s**2/4/sig**2)\ * (fp.exp(-fp.j*Om*s) * wightman_btz_n(s,n,R,rh,l,pm1,Om,lam,sig)) if n != 0 or deltaphi != 0: pt1 = fp.mpf( mp.acosh(rh**2 / (R**2 - rh**2) * (R**2 / rh**2 * fp.cosh(rh / l * (deltaphi - 2 * fp.pi * n)) - 1))) pt2 = fp.mpf( mp.acosh(rh**2 / (R**2 - rh**2) * (R**2 / rh**2 * fp.cosh(rh / l * (deltaphi - 2 * fp.pi * n)) + 1))) uplim = 2 * tau - u if n == 0: if uplim < pt2: output = fp.quad(s_int_fnc, [0, uplim]) else: output = fp.quad(s_int_fnc, [0, pt2]) + fp.quad( s_int_fnc, [pt2, uplim]) else: if uplim < pt1: output = fp.quad(s_int_fnc, [0, uplim]) elif uplim < pt2: output = fp.quad(s_int_fnc, [0, pt1]) + fp.quad( s_int_fnc, [pt1, uplim]) else: output = fp.quad(s_int_fnc,[0,pt1]) + fp.quad(s_int_fnc,[pt1,pt2])\ + fp.quad(s_int_fnc,[pt2,uplim]) output *= fp.exp(-u**2 / 4 / sig**2) return output
def Xn_plus(n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi, isP): intlim2 = l**2/rh * mp.acosh( (RA*RB/rh**2 * fp.mpf( mp.cosh(rh/l * (deltaphi-2*fp.pi*n)) ) + 1)\ / fp.sqrt(RA**2-rh**2)/fp.sqrt(RB**2-rh**2)*rh**2) #print('plus, %.4f ;'%intlim2) f = lambda y: integrandof_Xn_plus(y, n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi, isP) if intlim2 < width: return fp.quad(f, [0, intlim2]) + fp.quad(f, [intlim2, width]) else: return fp.quad(f, [0, width])
def XG_plusBA(n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi, isP): bA = mp.sqrt(RA**2 - rh**2) / l bB = mp.sqrt(RB**2 - rh**2) / l f = lambda y: 2/Om/(bB-bA) * fp.exp(-fp.j*Om/2*(bB+bA)*y)\ * h_n2(y,n,RA,RB,rh,l,pm1,deltaphi,isP)\ * fp.sin( Om/2*(bB-bA)*(2*(tau0+width)-y)) return fp.quad(f, [2 * tau0 + width, 2 * (tau0 + width)])
def XG_minusAB(n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi, isP): bA = mp.sqrt(RA**2 - rh**2) / l bB = mp.sqrt(RB**2 - rh**2) / l f = lambda y: 2/Om/(bB-bA) * fp.exp(-fp.j*Om/2*(bB+bA)*y)\ * h_n1(y,n,RA,RB,rh,l,pm1,deltaphi,isP)\ * fp.sin( Om/2*(bB-bA)*(y-2*tau0)) return fp.quad(f, [2 * tau0, 2 * tau0 + width])
def PGEON_n(n, R, rh, l, pm1, Om, lam, sig): """ Om = energy difference lam = coupling constant """ if pm1 == -1 or pm1 == 1 or pm1 == 0: return lam**2*sig*fp.sqrt(fp.pi) * fp.mpf(mp.exp(-sig**2 * Om**2)) *\ fp.quad(lambda x: h_n(x,n,R,rh,l,pm1) * PGEON_gaussian(x,sig), [-fp.inf, fp.inf]) else: print("Please enter a value of 1, -1, or 0 for pm1.")
def P_BTZn(n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi=0, eps=1e-8, isP=True): f = lambda y: integrandof_P_BTZn(y, n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi, isP) if n == 0 and deltaphi == 0 and RA == RB: # P0m P0m = 2 * fp.quad( lambda x: integrandPBTZ_0m(x, RA, rh, l, pm1, Om, lam, tau0, width, eps), [0, width]) intlim = l**2/rh * mp.acosh( (RA*RB/rh**2 * fp.mpf( mp.cosh(rh/l * (deltaphi-2*fp.pi*n)) ) + 1)\ / fp.sqrt(RA**2-rh**2)/fp.sqrt(RB**2-rh**2)*rh**2) if intlim < width: return fp.quad(f, [0, intlim]) + fp.quad(f, [intlim, width]) + P0m else: return fp.quad(f, [0, width]) + P0m else: intlim1 = l**2/rh * mp.acosh( (RA*RB/rh**2 * fp.mpf( mp.cosh(rh/l * (deltaphi-2*fp.pi*n)) ) - 1)\ / fp.sqrt(RA**2-rh**2)/fp.sqrt(RB**2-rh**2)*rh**2) intlim2 = l**2/rh * mp.acosh( (RA*RB/rh**2 * fp.mpf( mp.cosh(rh/l * (deltaphi-2*fp.pi*n)) ) + 1)\ / fp.sqrt(RA**2-rh**2)/fp.sqrt(RB**2-rh**2)*rh**2) #print('%.4f, %.4f'%(intlim1,intlim2)) if intlim2 < width: return fp.quad(f, [0, intlim1]) + fp.quad( f, [intlim1, intlim2]) + fp.quad(f, [intlim2, width]) elif intlim1 < width: return fp.quad(f, [0, intlim1]) + fp.quad(f, [intlim1, width]) else: return fp.quad(f, [0, width])
def P_BTZn(n, R, rh, l, pm1, Om, lam, sig): b = fp.sqrt(R**2 - rh**2) / l lim = 20 * sig * rh / b / l**2 #Zp = mp.mpf(rh**2/(R**2-rh**2)*(R**2/rh**2 * fp.cosh(2*fp.pi*rh/l * n) + 1)) #print('Zm: ',Zm, 'Zp: ',Zp) #print(Zm,fp.acosh(Zm)) if pm1 == -1 or pm1 == 1 or pm1 == 0: if n == 0: return fp.quad(lambda x: f01(x, n, R, rh, l, pm1, Om, lam, sig), [-fp.inf, fp.inf]) else: Zm = rh**2 / (R**2 - rh**2) * ( R**2 / rh**2 * fp.cosh(2 * fp.pi * rh / l * n) - 1) if fp.cosh(lim) < Zm or Zm < 1: return fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[0,lim]) else: return fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[0,fp.mpf(mp.acosh(Zm))])\ - fp.quad(lambda x: fn1(x,n,R,rh,l,pm1,Om,lam,sig)\ - fn2(x,n,R,rh,l,pm1,Om,lam,sig),[fp.mpf(mp.acosh(Zm)),lim]) else: print("Please enter a value of 1, -1, or 0 for pm1.")
def T_PGEON_n(tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0): return fp.quad( lambda x: T_P_int_geon( x, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0), [-10 * sig, 2 * tau])
def P_BTZ_n_tau(tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0): return fp.quad( lambda u: integrand_btz_n( u, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0), [-10 * sig, 2 * tau])
def integral1(a): return fp.quad(lambda x: integrand1(x, a), [-fp.inf, a])
def Pdot_n(tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0, eps=1e-6): if n == 0: if deltaphi == 0: lim2 = fp.mpf(mp.acosh(mp.mpf(rh**2/(R**2-rh**2)\ *(R**2/rh**2 * fp.cosh(rh/l * (deltaphi - 2*fp.pi*n)) + 1)))) #print(lim2) fmins = lambda s: integrand_Pdotm_n(s, tau, 0, R, rh, l, pm1, Om, lam, sig, deltaphi, eps).real fplus = lambda s: integrand_Pdotp_n(s, tau, 0, R, rh, l, pm1, Om, lam, sig, deltaphi, eps).real return fp.quad(fmins, [0, tau + 10 * sig]) + fp.quad( fplus, [0, lim2]) + fp.quad(fplus, [lim2, tau + 10 * sig]) else: lim1 = fp.mpf(mp.acosh(mp.mpf(rh**2/(R**2-rh**2)\ *(R**2/rh**2 * fp.cosh(rh/l * (deltaphi - 2*fp.pi*n)) - 1)))) lim2 = fp.mpf(mp.acosh(mp.mpf(rh**2/(R**2-rh**2)\ *(R**2/rh**2 * fp.cosh(rh/l * (deltaphi - 2*fp.pi*n)) + 1)))) fmins = lambda s: integrand_Pdotm_n(s, tau, 0, R, rh, l, pm1, Om, lam, sig, deltaphi, 0).real fplus = lambda s: integrand_Pdotp_n(s, tau, 0, R, rh, l, pm1, Om, lam, sig, deltaphi, 0).real return fp.quad(fmins,[0,lim1]) + fp.quad(fmins,[lim1,tau+10*sig])\ + fp.quad(fplus,[0,lim2]) + fp.quad(fplus,[lim2,tau+10*sig]) else: lim1 = fp.mpf(mp.acosh(mp.mpf(rh**2/(R**2-rh**2)\ *(R**2/rh**2 * fp.cosh(rh/l * (deltaphi - 2*fp.pi*n)) - 1)))) lim2 = fp.mpf(mp.acosh(mp.mpf(rh**2/(R**2-rh**2)\ *(R**2/rh**2 * fp.cosh(rh/l * (deltaphi - 2*fp.pi*n)) + 1)))) fmins = lambda s: integrand_Pdotm_n(s, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi, 0).real fplus = lambda s: integrand_Pdotp_n(s, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi, 0).real return fp.quad(fmins,[0,lim1]) + fp.quad(fmins,[lim1,tau+10*sig])\ + fp.quad(fplus,[0,lim2]) + fp.quad(fplus,[lim2,tau+10*sig])
def DeltaPdot_n(tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi=0): f = lambda s: integrand_deltaPdot_n(s, tau, n, R, rh, l, pm1, Om, lam, sig, deltaphi) return fp.quad(f, [0, tau + 10 * sig])
counter += 1 value = integrand_Pdotm_n(si, t, n, R, rh, l, pm1, Om[0], lam, sig, 0, eps) integrandminus_re.append(value.real) #integrandminus_im.append(value.imag) plt.plot(s, integrandminus_re, label='tau = ' + str(t)) integrandminus_re = [] #plt.plot(s,integrandminus_im,label='imag') plt.legend() plt.xlabel('integration variable') plt.ylabel('integrand') plt.title('n=0') f = lambda x: integrand_Pdotm_n(x, tau, n, R, rh, l, pm1, Om, lam, sig, 0, 0) print('\nintegral is: ', fp.quad(f, [0, tau + 10 * sig])) #%% check for En in Om: for ii in range(len(M)): nmax = converge_cutoff(M[ii], 0.002) print('nmax =', nmax) tau = np.linspace(-5, 5, num=81) tr_rate = 0 * tau tr_rate_geon = 0 * tau for n in range(nmax + 1): print('n =', n) print('i =', end='')
def integrand2(u, a): f = lambda s: fp.exp(-s**2) * (fp.exp(fp.j*(s+u)) * fp.mpf(mp.exp(-np.abs(u)))\ + fp.exp(fp.j*u) * fp.mpf(mp.exp(-np.abs(s+u))) ) return fp.quad(f, [0, fp.inf])
def integrand1(x, a): f = lambda x2: fp.exp(-(x - x2)**2) * fp.exp(-fp.j * x) * fp.exp(-np.abs(x2 )) return fp.quad(f, [-fp.inf, a])
def integral2(a): return fp.quad(lambda u: integrand2(u, a), [-fp.inf, a])
################################ y = np.linspace(-0.5, 4, num=101) th_re, th_im, gau_re, gau_im = [], [], [], [] for yi in y: th = integrandPBTZ_0m(yi, RA, rh, l, pm1, Om, lam, 0, width, eps) th_re.append(th.real) th_im.append(th.imag) gau = integrandPBTZ_0m_GAUSS(yi, RA, rh, l, pm1, Om, lam, sig, eps) gau_re.append(gau.real) gau_im.append(gau.imag) gau_integral = fp.quad( lambda y: integrandPBTZ_0m_GAUSS(y, RA, rh, l, pm1, Om, lam, sig, eps), [0, 10]) th_integral = fp.quad( lambda y: integrandPBTZ_0m(y, RA, rh, l, pm1, Om, lam, tau0, width, eps), [0, width]) ### fig2 = plt.figure(figsize=(5, 4)) plt.plot(y, th_im, label='top hat imaginary') plt.plot(y, gau_im, label='gaussian imaginary') plt.legend() ### fig = plt.figure(figsize=(9, 5)) plt.plot(y, th_re, label='top hat') plt.plot(y, gau_re, label='gaussian')
def PGEON_n(n, RA, RB, rh, l, pm1, Om, lam, tau0, width, deltaphi=0, isP=True): return fp.quad(lambda y: integrandof_PGEON_n(y,n,RA,RB,rh,l,pm1,Om,lam,tau0,width,deltaphi,isP)\ , [0,width])
def P0m_GAUSS(R, rh, l, pm1, Om, lam, sig, eps=1e-8): f = lambda y: integrandPBTZ_0m_GAUSS(y, R, rh, l, pm1, Om, lam, sig, eps) return fp.quad(f, [0, fp.inf])
def integrate(f, limx, limy, limz, method): if method == "mp-gl": if limz != 0: return mp.quad(f, limx, limy, limz, method="gauss-legendre") else: if limy != 0: return mp.quad(f, limx, limy, method="gauss-legendre") else: return mp.quad(f, limx, method="gauss-legendre") elif method == "mp-ts": if limz != 0: return mp.quad(f, limx, limy, limz, method="tanh-sinh") else: if limy != 0: return mp.quad(f, limx, limy, method="tanh-sinh") else: return mp.quad(f, limx, method="tanh-sinh") elif method == "fp-gl": if limz != 0: return fp.quad(f, limx, limy, limz, method="gauss-legendre") else: if limy != 0: return fp.quad(f, limx, limy, method="gauss-legendre") else: return fp.quad(f, limx, method="gauss-legendre") elif method == "fp-ts": if limz != 0: return fp.quad(f, limx, limy, limz, method="tanh-sinh") else: if limy != 0: return fp.quad(f, limx, limy, method="tanh-sinh") else: return fp.quad(f, limx, method="tanh-sinh") elif method == "sp-quad": if limz != 0: return spint.tplquad(f, limz[0], limz[1], limy[0], limy[1], limx[0], limx[1])[0] else: if limy != 0: return spint.dblquad(f, limy[0], limy[1], limx[0], limx[1])[0] else: return spint.quad(f, limx[0], limx[1])[0] elif method == "romberg": if not np.ndim(limx) == 0: limx = [float(limx[0]), float(limx[1])] if not np.ndim(limy) == 0: limy = [float(limy[0]), float(limy[1])] if not np.ndim(limz) == 0: limz = [float(limz[0]), float(limz[1])] reltol = 1e-16 abstol = 1e-16 if limz != 0: return spint.romberg(lambda z: spint.romberg( lambda y: spint.romberg(lambda x: float(f(x, y, z)), limx[0], limx[1], tol=abstol, rtol=reltol), limy[0], limy[1], tol=abstol, rtol=reltol), limz[0], limz[1], tol=abstol, rtol=reltol) else: if limy != 0: return spint.romberg( lambda y: spint.romberg(lambda x: float(f(x, y)), limx[0], limy[1], tol=abstol, rtol=reltol), limy[0], limy[1], tol=abstol, rtol=reltol) else: return spint.romberg(lambda x: float(f(x)), limx[0], limx[1], tol=abstol, rtol=reltol) #currently broken, but slow so unused elif method == "sp-gauss": if not np.ndim(limx) == 0: limx = [float(limx[0]), float(limx[1])] if not np.ndim(limy) == 0: limy = [float(limy[0]), float(limy[1])] if not np.ndim(limz) == 0: limz = [float(limz[0]), float(limz[1])] order = 7 if limz != 0: return spint.fixed_quad( lambda z: spint.fixed_quad(lambda y: spint.fixed_quad( lambda x: f(x, y, z), limx[0], limx[1], n=order)[0], limy[0], limy[1], n=order)[0], limz[0], limz[1], n=order)[0] else: if limy != 0: return spint.fixed_quad(lambda y: spint.romberg( lambda x: f(x, y), limx[0], limy[1], n=order)[0], limy[0], limy[1], n=order)[0] else: return spint.fixed_quad(lambda x: f(x), limx[0], limx[1], n=order)[0] elif method == "w-cumsum": if not np.ndim(limx) == 0: limx = [float(limx[0]), float(limx[1])] if not np.ndim(limy) == 0: limy = [float(limy[0]), float(limy[1])] if not np.ndim(limz) == 0: limz = [float(limz[0]), float(limz[1])] if limz != 0: dx = (limx[1] - limx[0]) / def_nodes dy = (limy[1] - limy[0]) / def_nodes dz = (limz[1] - limz[0]) / def_nodes loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) yl = np.arange(limy[0], limy[1], dy) zl = np.arange(limz[0], limz[1], dz) X, Y, Z = np.meshgrid(xl, yl, zl) fx = [] for i in range(0, len(X)): fy = [] for j in range(0, len(Y)): fz = [] for k in range(0, len(Z)): fz.append(f(X[i][j][k], Y[i][j][k], zl[k])) fy.append(spint.simps(fz, dx=dz)) fx.append(spint.simps(fy, dx=dy)) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad dy = dy * ad dz = dz * ad lastres = res if loop > maxloop: break loop += 1 else: if limy != 0: dx = def_dx dy = def_dx loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) yl = np.arange(limy[0], limy[1], dy) X, Y = np.meshgrid(xl, yl) fx = [] for i in range(0, len(X)): fy = [] for j in range(0, len(Y)): fy.append(f(X[i][j], yl[j])) fx.append(spint.simps(fy, dx=dy)) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad dy = dy * ad lastres = res if loop > maxloop: break loop += 1 else: dx = def_dx loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) fx = [] for i in range(0, len(X)): fx.append(f(xl[i])) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad lastres = res if loop > maxloop: break loop += 1 #still a bit broken but proved slower than mp-gl elif method == "monte-carlo": N = int(1e6) if limz != 0: N = int(round(N**(1 / 3))) x = np.random.rand(N) * (limx[1] - limx[0]) + limx[0] y = np.random.rand(N) * (limy[1] - limy[0]) + limy[0] z = np.random.rand(N) * (limz[1] - limy[0]) + limz[0] X, Y, Z = np.meshgrid(x, y, z) fxyz = [] for i in range(0, len(X)): fxy = [] for j in range(0, len(Y)): fx = [] for k in range(0, len(Z)): fx.append(f(X[i][j][k], Y[i][j][k], Z[i][j][k])) fxy.append(fx) fxyz.append(fxy) wmax = np.max(fxyz) wmin = np.min(fxyz) W = np.random.rand(N, N, N) * (wmax - wmin) + wmin est = 0 for i in range(0, len(fxyz)): for j in range(0, len(fxyz[i])): for k in range(0, len(fxyz[i][j])): if W[i][j][k] > 0 and W[i][j][k] < fxyz[i][j][k]: est = est + fxyz[i][j][k] elif W[i][j][k] < 0 and W[i][j][k] > fxyz[i][j][k]: est = est + fxyz[i][j][k] return (est / (N**3)) * (limx[1] - limx[0]) * ( limy[1] - limy[0]) * (limz[1] - limz[0]) * (wmax - wmin) else: if limy != 0: N = int(round(N**(1 / 2))) x = np.random.rand(N) * (limx[1] - limx[0]) + limx[0] y = np.random.rand(N) * (limy[1] - limy[0]) + limy[0] X, Y = np.meshgrid(x, y) fxy = [] for i in range(0, len(X)): fx = [] for j in range(0, len(Y)): fx.append(f(X[i][j], Y[i][j])) fxy.append(fx) zmax = np.max(fxy) zmin = np.min(fxy) Z = np.random.rand(N, N) * (zmax - zmin) + zmin est = 0 for i in range(0, len(fxy)): for j in range(0, len(fxy[i])): if Z[i][j] > 0 and Z[i][j] < fxy[i][j]: est = est + fxy[i][j] elif Z[i][j] < 0 and Z[i][j] > fxy[i][j]: est = est + fxy[i][j] return (est / (N**2)) * (limx[1] - limx[0]) * ( limy[1] - limy[0]) * (zmax - zmin) else: X = np.random.rand(N) * (limx[1] - limx[0]) + limx[0] fx = [] for i in range(0, len(X)): fx.append(f(X[i])) ymax = np.max(fx) ymin = np.min(fx) Y = np.random.rand(N) * (ymax - ymin) + ymin est = 0 for i in range(0, len(fx)): if Y[i] > 0 and Y[i] < fx[i]: est = est + fx[i] elif Y[i] < 0 and Y[i] > fx[i]: est = est + fx[i] return (est / N) * (limx[1] - limx[0]) * (ymax - ymin) #preallocated, expected to be slow elif method == "sp-simps": if limz != 0: dx = (limx[1] - limx[0]) / def_nodes dy = (limy[1] - limy[0]) / def_nodes dz = (limz[1] - limz[0]) / def_nodes loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) yl = np.arange(limy[0], limy[1], dy) zl = np.arange(limz[0], limz[1], dz) X, Y, Z = np.meshgrid(xl, yl, zl) fx = [] for i in range(0, len(X)): fy = [] for j in range(0, len(Y)): fz = [] for k in range(0, len(Z)): fz.append(f(X[i][j][k], Y[i][j][k], zl[k])) fy.append(spint.simps(fz, dx=dz)) fx.append(spint.simps(fy, dx=dy)) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad dy = dy * ad dz = dz * ad lastres = res if loop > maxloop: break loop += 1 else: if limy != 0: dx = def_dx dy = def_dx loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) yl = np.arange(limy[0], limy[1], dy) X, Y = np.meshgrid(xl, yl) fx = [] for i in range(0, len(X)): fy = [] for j in range(0, len(Y)): fy.append(f(X[i][j], yl[j])) fx.append(spint.simps(fy, dx=dy)) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad dy = dy * ad lastres = res if loop > maxloop: break loop += 1 else: dx = def_dx loop = 0 lastres = 0 while True: xl = np.arange(limx[0], limx[1], dx) fx = [] for i in range(0, len(X)): fx.append(f(xl[i])) res = spint.simps(fx, dx=dx) if loop != 0: if np.abs(res - lastres) / res < err_rel: return res else: ad = (1 / 2)**loop #linear to begin with dx = dx * ad lastres = res if loop > maxloop: break loop += 1 return res