def intercept(a_x,a_y,b_x,b_y,radio): area = (b_x-a_x)*(b_y-a_y) radio2 =radio**2 if radio2 < a_x**2 + a_y**2: return 0 elif radio2 >= b_x**2 + b_y**2: return area else: if radio2 > a_x**2 + b_y**2: if radio2 > b_x**2 + a_y**2: #Case 1 corte = (radio2 - b_y**2)**0.5 return mpmath.quadts(lambda x: (radio2 - x**2)**0.5 ,corte,b_x) - (b_x-corte)*a_y + (b_y-a_y)*(corte-a_x) else: #Case 3 return mpmath.quadts(lambda x: (radio2 - x**2)**0.5 ,a_y,b_y) - (b_y-a_y)*a_x else: if radio2 > b_x**2 + a_y**2: #Case 2 return mpmath.quadts(lambda x: (radio2 - x**2)**0.5 ,a_x,b_x) - (b_x-a_x)*a_y else: #Case 4 corte = (radio2 - a_y**2)**0.5 return mpmath.quadts(lambda x: (radio2 - x**2)**0.5 ,a_x,corte) - (corte-a_x)*a_y
def test_exp_4t_exp_jw_gamma_t_exp_4t(self): def f(t): return np.exp(4 * t) # amplitude function def g(t): return t + np.exp(4 * t) * gamma(t) # phase function def dg(t): return 1 + (4 + digamma(t)) * np.exp(4 * t) * gamma(t) a = 1 b = 2 omega = 100 def ftot(t): exp4t = mp.exp(4 * t) return exp4t * mp.exp(1j * omega * (t + exp4t * mp.gamma(t))) _true_val, _err = mp.quadts(ftot, [a, (a + b) / 2, b], error=True) true_val = 0.00435354129735323908804 + 0.00202865398517716214366j # quad = AdaptiveLevin(f, g, dg, a=a, b=b, s=1, full_output=True) for quadfun in [EvansWebster, QuadOsc, AdaptiveLevin]: quad = quadfun(f, g, dg, a=a, b=b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-11)
def test_I5_coscost_sint_exp_jw_sint(self): a = 0 b = np.pi / 2 omega = 100 def f(t): return np.cos(np.cos(t)) * np.sin(t) def g(t): return np.sin(t) def dg(t): return np.cos(t) def ftot(t): return mp.cos(mp.cos(t)) * mp.sin(t) * mp.exp( 1j * omega * mp.sin(t)) _true_val, _err = mp.quadts(ftot, [a, 0.5, 1, b], maxdegree=9, error=True) true_val = 0.0325497765499959 - 0.121009052128827j for quadfun in [QuadOsc, EvansWebster, AdaptiveLevin]: quad = quadfun(f, g, dg, a, b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-9)
def test_I4_ln_x_exp_jw_30x(self): n = 7 def g(t): return t**n def dg(t): return n * t**(n - 1) def f(t): return dg(t) * np.log(g(t)) a = 0 b = (2 * np.pi)**(1. / n) omega = 30 def ftot(t): return n * t**(n - 1) * mp.log(t**n) * mp.exp(1j * omega * t**n) _true_val, _err = mp.quadts(ftot, [a, b], error=True, maxdegree=8) # true_val = (-0.052183048684992 - 0.193877275099872j) true_val = (-0.0521830486849921 - 0.193877275099871j) for quadfun in [QuadOsc, EvansWebster, AdaptiveLevin]: quad = quadfun(f, g, dg, a, b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-5)
def test_I5_coscost_sint_exp_jw_sint(self): a = 0 b = np.pi / 2 omega = 100 def f(t): return np.cos(np.cos(t)) * np.sin(t) def g(t): return np.sin(t) def dg(t): return np.cos(t) def ftot(t): return mp.cos(mp.cos(t)) * mp.sin(t) * mp.exp(1j * omega * mp.sin(t)) _true_val, _err = mp.quadts(ftot, [a, 0.5, 1, b], maxdegree=9, error=True) true_val = 0.0325497765499959 - 0.121009052128827j for quadfun in [QuadOsc, EvansWebster, AdaptiveLevin]: quad = quadfun(f, g, dg, a, b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-9)
def test_I4_ln_x_exp_jw_30x(self): n = 7 def g(t): return t ** n def dg(t): return n * t ** (n - 1) def f(t): return dg(t) * np.log(g(t)) a = 0 b = (2 * np.pi) ** (1.0 / n) omega = 30 def ftot(t): return n * t ** (n - 1) * mp.log(t ** n) * mp.exp(1j * omega * t ** n) _true_val, _err = mp.quadts(ftot, [a, b], error=True, maxdegree=8) # true_val = (-0.052183048684992 - 0.193877275099872j) true_val = -0.0521830486849921 - 0.193877275099871j for quadfun in [QuadOsc, EvansWebster, AdaptiveLevin]: quad = quadfun(f, g, dg, a, b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-5)
def test_exp_jw_t(self): def g(t): return t def dg(t): return np.ones(np.shape(t)) def true_F(t): return np.exp(1j * omega * g(t)) / (1j * omega) val, _err = mp.quadts(g, [0, 1], error=True) a = 1 b = 2 omega = 1 true_val = true_F(b) - true_F(a) for quadfun in [QuadOsc, AdaptiveLevin, EvansWebster]: quad = quadfun(dg, g, dg, a, b, full_output=True) val, info = quad(omega) assert_allclose(val, true_val) self.assert_(info.error_estimate < 1e-12)
def do_integral(expr, prec, options): func = expr.args[0] x, xlow, xhigh = expr.args[1] if xlow == xhigh: xlow = xhigh = 0 elif x not in func.free_symbols: # only the difference in limits matters in this case # so if there is a symbol in common that will cancel # out when taking the difference, then use that # difference if xhigh.free_symbols & xlow.free_symbols: diff = xhigh - xlow if not diff.free_symbols: xlow, xhigh = 0, diff oldmaxprec = options.get('maxprec', DEFAULT_MAXPREC) options['maxprec'] = min(oldmaxprec, 2 * prec) with workprec(prec + 5): xlow = as_mpmath(xlow, prec + 15, options) xhigh = as_mpmath(xhigh, prec + 15, options) # Integration is like summation, and we can phone home from # the integrand function to update accuracy summation style # Note that this accuracy is inaccurate, since it fails # to account for the variable quadrature weights, # but it is better than nothing from sympy import cos, sin, Wild have_part = [False, False] max_real_term = [MINUS_INF] max_imag_term = [MINUS_INF] def f(t): re, im, re_acc, im_acc = evalf(func, mp.prec, {'subs': {x: t}}) have_part[0] = re or have_part[0] have_part[1] = im or have_part[1] max_real_term[0] = max(max_real_term[0], fastlog(re)) max_imag_term[0] = max(max_imag_term[0], fastlog(im)) if im: return mpc(re or fzero, im) return mpf(re or fzero) if options.get('quad') == 'osc': A = Wild('A', exclude=[x]) B = Wild('B', exclude=[x]) D = Wild('D') m = func.match(cos(A * x + B) * D) if not m: m = func.match(sin(A * x + B) * D) if not m: raise ValueError( "An integrand of the form sin(A*x+B)*f(x) " "or cos(A*x+B)*f(x) is required for oscillatory quadrature" ) period = as_mpmath(2 * S.Pi / m[A], prec + 15, options) result = quadosc(f, [xlow, xhigh], period=period) # XXX: quadosc does not do error detection yet quadrature_error = MINUS_INF else: result, quadrature_error = quadts(f, [xlow, xhigh], error=1) quadrature_error = fastlog(quadrature_error._mpf_) options['maxprec'] = oldmaxprec if have_part[0]: re = result.real._mpf_ if re == fzero: re, re_acc = scaled_zero( min(-prec, -max_real_term[0], -quadrature_error)) re = scaled_zero(re) # handled ok in evalf_integral else: re_acc = -max(max_real_term[0] - fastlog(re) - prec, quadrature_error) else: re, re_acc = None, None if have_part[1]: im = result.imag._mpf_ if im == fzero: im, im_acc = scaled_zero( min(-prec, -max_imag_term[0], -quadrature_error)) im = scaled_zero(im) # handled ok in evalf_integral else: im_acc = -max(max_imag_term[0] - fastlog(im) - prec, quadrature_error) else: im, im_acc = None, None result = re, im, re_acc, im_acc return result
def do_integral(expr, prec, options): func = expr.args[0] x, xlow, xhigh = expr.args[1] if xlow == xhigh: xlow = xhigh = 0 elif x not in func.free_symbols: # only the difference in limits matters in this case # so if there is a symbol in common that will cancel # out when taking the difference, then use that # difference if xhigh.free_symbols & xlow.free_symbols: diff = xhigh - xlow if not diff.free_symbols: xlow, xhigh = 0, diff oldmaxprec = options.get('maxprec', DEFAULT_MAXPREC) options['maxprec'] = min(oldmaxprec, 2*prec) with workprec(prec + 5): xlow = as_mpmath(xlow, prec + 15, options) xhigh = as_mpmath(xhigh, prec + 15, options) # Integration is like summation, and we can phone home from # the integrand function to update accuracy summation style # Note that this accuracy is inaccurate, since it fails # to account for the variable quadrature weights, # but it is better than nothing from sympy import cos, sin, Wild have_part = [False, False] max_real_term = [MINUS_INF] max_imag_term = [MINUS_INF] def f(t): re, im, re_acc, im_acc = evalf(func, mp.prec, {'subs': {x: t}}) have_part[0] = re or have_part[0] have_part[1] = im or have_part[1] max_real_term[0] = max(max_real_term[0], fastlog(re)) max_imag_term[0] = max(max_imag_term[0], fastlog(im)) if im: return mpc(re or fzero, im) return mpf(re or fzero) if options.get('quad') == 'osc': A = Wild('A', exclude=[x]) B = Wild('B', exclude=[x]) D = Wild('D') m = func.match(cos(A*x + B)*D) if not m: m = func.match(sin(A*x + B)*D) if not m: raise ValueError("An integrand of the form sin(A*x+B)*f(x) " "or cos(A*x+B)*f(x) is required for oscillatory quadrature") period = as_mpmath(2*S.Pi/m[A], prec + 15, options) result = quadosc(f, [xlow, xhigh], period=period) # XXX: quadosc does not do error detection yet quadrature_error = MINUS_INF else: result, quadrature_error = quadts(f, [xlow, xhigh], error=1) quadrature_error = fastlog(quadrature_error._mpf_) options['maxprec'] = oldmaxprec if have_part[0]: re = result.real._mpf_ if re == fzero: re, re_acc = scaled_zero( min(-prec, -max_real_term[0], -quadrature_error)) re = scaled_zero(re) # handled ok in evalf_integral else: re_acc = -max(max_real_term[0] - fastlog(re) - prec, quadrature_error) else: re, re_acc = None, None if have_part[1]: im = result.imag._mpf_ if im == fzero: im, im_acc = scaled_zero( min(-prec, -max_imag_term[0], -quadrature_error)) im = scaled_zero(im) # handled ok in evalf_integral else: im_acc = -max(max_imag_term[0] - fastlog(im) - prec, quadrature_error) else: im, im_acc = None, None result = re, im, re_acc, im_acc return result
def test_exp_zdcos2t_dcos2t_exp_jw_cos_t_b_dcos2t(self): x1 = 20 y1 = 50 z1 = 10 beta = np.abs(np.arctan(y1 / x1)) R = np.sqrt(x1**2 + y1**2) def f(t, beta, z1): cos2t = np.cos(t)**2 return np.where(cos2t == 0, 0, np.exp(-z1 / cos2t) / cos2t) def g(t, beta, z1): return np.cos(t - beta) / np.cos(t)**2 def dg(t, beta, z1=0): cos3t = np.cos(t)**3 return 0.5 * (3 * np.sin(beta) - np.sin(beta - 2 * t)) / cos3t def append_dg_zero(zeros, g1, beta): signs = [ 1, ] if np.abs(g1) <= _EPS else [-1, 1] for sgn1 in signs: tn = np.arccos(sgn1 * g1) if -np.pi / 2 <= tn <= np.pi / 2: for sgn2 in [-1, 1]: t = sgn2 * tn if np.abs(dg(t, beta)) < 10 * _EPS: zeros.append(t) return zeros def zeros_dg(beta): k0 = (9 * np.cos(2 * beta) - 7) if k0 < 0: # No stationary points return () k1 = 3 * np.cos(2 * beta) - 5 g0 = np.sqrt(2) * np.sqrt(np.cos(beta)**2 * k0) zeros = [] if g0 + k1 < _EPS: g1 = 1. / 2 * np.sqrt(-g0 - k1) zeros = append_dg_zero(zeros, g1, beta) if _EPS < g0 - k1: g2 = 1. / 2 * np.sqrt(g0 - k1) zeros = append_dg_zero(zeros, g2, beta) if np.abs(g0 + k1) <= _EPS or np.abs(g0 - k1) <= _EPS: zeros = append_dg_zero(zeros, 0, beta) return tuple(zeros) a = -np.pi / 2 b = np.pi / 2 omega = R def ftot(t): cos2t = mp.cos(t)**2 return (mp.exp(-z1 / cos2t) / cos2t * mp.exp(1j * omega * mp.cos(t - beta) / cos2t)) zdg = zeros_dg(beta) ab = (a, ) + zdg + (b, ) true_val, _err = mp.quadts(ftot, ab, maxdegree=9, error=True) # true_val3, err3 = mp.quadgl(ftot, ab, maxdegree=9, error=True) if False: import matplotlib.pyplot as plt t = np.linspace(a, b, 5 * 513) plt.subplot(2, 1, 1) f2 = f(t, beta, z1) * np.exp(1j * R * g(t, beta, z1)) true_val2 = np.trapz(f2, t) plt.plot(t, f2.real, label='f.real') plt.plot(t, f2.imag, 'r', label='f.imag') plt.title( 'integral=%g+1j%g,\n' '(%g+1j%g)' % (true_val2.real, true_val2.imag, true_val.real, true_val.imag)) plt.legend(loc='best', framealpha=0.5) plt.subplot(2, 1, 2) plt.plot(t, dg(t, beta, z1), 'r', label='dg(t,b={},z={})'.format(beta, z1)) plt.plot(t, g(t, beta, z1), label='g(t,b,z)') plt.hlines(0, a, b) plt.axis([a, b, -5, 5]) plt.title('beta=%g' % beta) print(np.trapz(f2, t)) plt.legend(loc='best', framealpha=0.5) plt.show('hold') # true_val = 0.00253186684281+0.004314054498j # s = 15 for quadfun in [QuadOsc]: # , EvansWebster]: # , AdaptiveLevin]: # EvansWebster]: # , AdaptiveLevin, ]: quad = quadfun(f, g, dg, a, b, precision=10, endpoints=False, full_output=True) val, _info = quad(omega, beta, z1) # @UnusedVariable print(quadfun.__name__) assert_allclose(val, complex(true_val), rtol=1e-3) # s = 1 if s<=1 else s//2 pass
def test_exp_zdcos2t_dcos2t_exp_jw_cos_t_b_dcos2t(self): x1 = 20 y1 = 50 z1 = 10 beta = np.abs(np.arctan(y1 / x1)) R = np.sqrt(x1 ** 2 + y1 ** 2) def f(t, beta, z1): cos2t = np.cos(t) ** 2 return np.where(cos2t == 0, 0, np.exp(-z1 / cos2t) / cos2t) def g(t, beta, z1): return np.cos(t - beta) / np.cos(t) ** 2 def dg(t, beta, z1=0): cos3t = np.cos(t) ** 3 return 0.5 * (3 * np.sin(beta) - np.sin(beta - 2 * t)) / cos3t def append_dg_zero(zeros, g1, beta): signs = [1] if np.abs(g1) <= _EPS else [-1, 1] for sgn1 in signs: tn = np.arccos(sgn1 * g1) if -np.pi / 2 <= tn <= np.pi / 2: for sgn2 in [-1, 1]: t = sgn2 * tn if np.abs(dg(t, beta)) < 10 * _EPS: zeros.append(t) return zeros def zeros_dg(beta): k0 = 9 * np.cos(2 * beta) - 7 if k0 < 0: # No stationary points return () k1 = 3 * np.cos(2 * beta) - 5 g0 = np.sqrt(2) * np.sqrt(np.cos(beta) ** 2 * k0) zeros = [] if g0 + k1 < _EPS: g1 = 1.0 / 2 * np.sqrt(-g0 - k1) zeros = append_dg_zero(zeros, g1, beta) if _EPS < g0 - k1: g2 = 1.0 / 2 * np.sqrt(g0 - k1) zeros = append_dg_zero(zeros, g2, beta) if np.abs(g0 + k1) <= _EPS or np.abs(g0 - k1) <= _EPS: zeros = append_dg_zero(zeros, 0, beta) return tuple(zeros) a = -np.pi / 2 b = np.pi / 2 omega = R def ftot(t): cos2t = mp.cos(t) ** 2 return mp.exp(-z1 / cos2t) / cos2t * mp.exp(1j * omega * mp.cos(t - beta) / cos2t) zdg = zeros_dg(beta) ab = (a,) + zdg + (b,) true_val, _err = mp.quadts(ftot, ab, maxdegree=9, error=True) # true_val3, err3 = mp.quadgl(ftot, ab, maxdegree=9, error=True) if False: import matplotlib.pyplot as plt t = np.linspace(a, b, 5 * 513) plt.subplot(2, 1, 1) f2 = f(t, beta, z1) * np.exp(1j * R * g(t, beta, z1)) true_val2 = np.trapz(f2, t) plt.plot(t, f2.real, label="f.real") plt.plot(t, f2.imag, "r", label="f.imag") plt.title( "integral=%g+1j%g,\n" "(%g+1j%g)" % (true_val2.real, true_val2.imag, true_val.real, true_val.imag) ) plt.legend(loc="best", framealpha=0.5) plt.subplot(2, 1, 2) plt.plot(t, dg(t, beta, z1), "r", label="dg(t,b={},z={})".format(beta, z1)) plt.plot(t, g(t, beta, z1), label="g(t,b,z)") plt.hlines(0, a, b) plt.axis([a, b, -5, 5]) plt.title("beta=%g" % beta) print(np.trapz(f2, t)) plt.legend(loc="best", framealpha=0.5) plt.show("hold") # true_val = 0.00253186684281+0.004314054498j # s = 15 for quadfun in [QuadOsc]: # , EvansWebster]: # , AdaptiveLevin]: # EvansWebster]: # , AdaptiveLevin, ]: quad = quadfun(f, g, dg, a, b, precision=10, endpoints=False, full_output=True) val, _info = quad(omega, beta, z1) # @UnusedVariable print(quadfun.__name__) assert_allclose(val, complex(true_val), rtol=1e-3) # s = 1 if s<=1 else s//2 pass