Exemple #1
0
def mpIntegralfunc( dor, force_integ):
    '''The mpmath package is used to arrive to integrate to lower dor than 
    possible with scipy.quad'''
   
    if dor > 100:
        starttime = time.time()
        inte = mp.quad(force_integ(dor),[0,mp.inf])
        print('the duration for dor = {0} is: {1}'.format(dor, time.time()-starttime))
        return float(inte)
    elif dor < 0.05:
        mp.mp.prec = 250
    elif dor < 0.1:
        mp.mp.prec = 100
    #else:
        #mp.mp.prec = 5
    
    j0zero = lambda n: mp.findroot(mp.j0, mp.pi*(n-0.25))
    
    starttime = time.time()
    inte = mp.quadosc(force_integ(dor),[0,mp.inf], zeros = j0zero)
    print('the duration for dor = {0} is: {1}'.format(dor, time.time()-starttime))
    return float(inte)
Exemple #2
0
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
Exemple #3
0
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 near_integral(func, radius, z, hight, Height, m=0):
    '''Return integral in infinite range.'''
    return np.array(mp.quadosc(lambda x: func(x, radius, z, hight, Height), 
                    [0, mp.inf], zeros=lambda n: zeros_j[m][int(n-1)] / (2*pi)))