Repository: sympy/sympy
File: sympy/concrete/summations.py (Python)

Code before:
        extraneous_neg = [f.xreplace({i: i0}) for i0 in range(int(a), 0)]
        extraneous_pos = [f.xreplace({i: i0}) for i0 in range(0, int(a))]
        result = half_sum + sum(extraneous_neg) - sum(extraneous_pos)

        return result

    # Compute Sum(f, (i, min(poles) + 1, oo))
    half_sum = full_sum / 2

    # Subtract extraneous evaluations
    extraneous = [f.xreplace({i: i0}) for i0 in range(max(int_roots) + 1, int(a))]
    result = half_sum - sum(extraneous)

    return result


def _get_residue(numer: Poly, denom: Poly, a: Expr, alternating: bool) -> Expr:
    """``Res((cot/csc)(pi*z)*numer(z)/denom(z))`` at ``a``."""
    #
    # Helper for eval_sum_residue. Since we know that a is a root of denom, we
    # can factor out ``(x - a)^p`` from denom exactly using polynomials over
    # the extension field containing ``a``. This is more efficient and more
    # robust than the current implementation of ``residue`` which uses a series
    # expansion.
    #
    x = denom.gen
    z = Dummy("z")

    if (2 * a).is_Integer:
        # In this case we have to deal with zeros and poles of cot(pi*z) or
        # csc(pi*z) which complicate the residue calculation. The series
        # residue function handles rational roots well enough though.
        from sympy.series.residues import residue
        if not alternating:
            return residue(cot(S.Pi*z)*(numer(z)/denom(z)), z, a)
        else:
            return residue(csc(S.Pi*z)*(numer(z)/denom(z)), z, a)

    numer = numer.xreplace({x: z})
    denom = denom.xreplace({x: z})
    za = Poly(z - a, z, extension=True)
    za, denom = za.unify(denom)

    # Divide out (z - a)^p from denom
    # Should this first cancel factors of (z - a) between numer and denom?
    p = 0
    q, r = denom.div(za)
    while r == 0 and denom != 0:
        denom = q
        p += 1
        q, r = denom.div(za)

Review comment (suggestion):
It probably makes sense to move some of this to the residue function although there is a long comment there explaining why a different approach should be used anyway.

Code after:

        # Add and subtract extraneous evaluations
        extraneous_neg = [f.xreplace({i: i0}) for i0 in range(int(a), 0)]
        extraneous_pos = [f.xreplace({i: i0}) for i0 in range(0, int(a))]
        result = half_sum + sum(extraneous_neg) - sum(extraneous_pos)

        return result

    # Compute Sum(f, (i, min(poles) + 1, oo))
    half_sum = full_sum / 2

    # Subtract extraneous evaluations
    extraneous = [f.xreplace({i: i0}) for i0 in range(max(int_roots) + 1, int(a))]
    result = half_sum - sum(extraneous)

    return result


def _get_residue(numer: Poly, denom: Poly, a: Expr, alternating: bool) -> Expr:
    """``Res((cot/csc)(pi*z)*numer(z)/denom(z))`` at ``a``."""
    #
    # Helper for eval_sum_residue. Since we know that a is a root of denom, we
    # can factor out ``(x - a)^p`` from denom exactly using polynomials over
    # the extension field containing ``a``. This is more efficient and more
    # robust than the current implementation of ``residue`` which uses a series
    # expansion.
    #
    x = denom.gen
    z = Dummy("z")

    if (2 * a).is_Integer:
        # In this case we have to deal with zeros and poles of cot(pi*z) or
        # csc(pi*z) which complicate the residue calculation. The series
        # residue function handles rational roots well enough though.
        from sympy.series.residues import residue
        if not alternating:
            return residue(cot(S.Pi*z)*(numer(z)/denom(z)), z, a)
        else:
            return residue(csc(S.Pi*z)*(numer(z)/denom(z)), z, a)

    numer = numer.xreplace({x: z})
    denom = denom.xreplace({x: z})
    za = Poly(z - a, z, extension=True)
    za, denom = za.unify(denom)

    # Divide out (z - a)^p from denom
    # Should this first cancel factors of (z - a) between numer and denom?
    p = 0
    q, r = denom.div(za)
    while r == 0 and denom != 0:
        denom = q