Repository: sympy/sympy
File: sympy/concrete/tests/test_sums_products.py (Python)

Code before:

    # Some examples made from 1 / x**2
    assert eval_sum_residue(1 / x**2, (x, S(2), oo)) == -1 + pi**2/6
    assert eval_sum_residue(1 / x**2, (x, S(3), oo)) == -S(5)/4 + pi**2/6
    assert eval_sum_residue((-1)**x / x**2, (x, S(1), oo)) == -pi**2/12
    assert eval_sum_residue((-1)**x / x**2, (x, S(2), oo)) == 1 - pi**2/12

    # https://github.com/sympy/sympy/issues/27824
    #An example of even function which works for -oo to k
    assert eval_sum_residue((1/(k**2+1)), (k, -oo, S(0))) == Rational(1, 2) + pi/(2*tanh(pi))

    #An example of function which is neither even nor odd which works for -oo to k
    assert eval_sum_residue(1 / (k**2 + 2*k +2), (k, -oo, S(0))) == 1 + pi/(2*tanh(pi))
    assert eval_sum_residue(1 / (k**2 + 2*k +2), (k, -oo, -S(1))) == S.Half+pi/tanh(pi)/2

    # Odd functions over (-oo to k) are handled by other parts of the summation
    # logic, so eval_sum_residue will return None in such cases.
    # The odd function when called directly in eval_sum_residue returns None
    # because the current implementation attempts to convert non-even functions
    # into even ones by shifting. However, this doesn't work in this case,
    # as the coefficient of the second-highest power in the denominator (k**2)
    # is zero. This results in a shift of zero, which means the function should
    # return None.
    assert eval_sum_residue((1/k**3), (k,-oo, S(-1))) == None
    # SO issue cited on #27827
    assert summation(1 / ((k+1) ** 4 + 1), (k, -oo, oo)).simplify() == sqrt(2)*pi*(1 - I)*(I/tan(sqrt(2)*pi*(1 + I)/2) + 1/tan(sqrt(2)*pi*(1 - I)/2))/4


@slow
def test_summation_by_residues_failing():
    x = Symbol('x')

    # Failing because of the bug in residue computation
    assert eval_sum_residue(x**2 / (x**4 + 1), (x, S(1), oo))
    assert eval_sum_residue(1 / ((x - 1)*(x - 2) + 1), (x, -oo, oo)) != 0


def test_process_limits():
    from sympy.concrete.expr_with_limits import _process_limits

    # these should be (x, Range(3)) not Range(3)
    raises(ValueError, lambda: _process_limits(
        Range(3), discrete=True))
    raises(ValueError, lambda: _process_limits(
        Range(3), discrete=False))
    # these should be (x, union) not union
    # (but then we would get a TypeError because we don't
    # handle non-contiguous sets: see below use of `union`)
    union = Or(x < 1, x > 3).as_set()
    raises(ValueError, lambda: _process_limits(
        union, discrete=True))

Review comment (refactor):
```suggestion
    # SO issue cited on #27827
    # this will return 0 if it is not allowed to shift to become even
    assert summation(1 / ((k + 1) ** 4 + 1), (k, -oo, oo)).simplify() == (sqrt(2)*pi*(1 - I)*(
        I/tan(sqrt(2)*pi*(1 + I)/2) + 1/tan(sqrt(2)*pi*(1 - I)/2))/4)
```

Code after:

    # Some examples made from 1 / x**2
    assert eval_sum_residue(1 / x**2, (x, S(2), oo)) == -1 + pi**2/6
    assert eval_sum_residue(1 / x**2, (x, S(3), oo)) == -S(5)/4 + pi**2/6
    assert eval_sum_residue((-1)**x / x**2, (x, S(1), oo)) == -pi**2/12
    assert eval_sum_residue((-1)**x / x**2, (x, S(2), oo)) == 1 - pi**2/12

    # https://github.com/sympy/sympy/issues/27824
    # even function which works for -oo to k
    ans = Rational(1, 2) + pi/(2*tanh(pi))
    assert eval_sum_residue((1/(k**2+1)), (k, -oo, S(0))) == ans
    assert eval_sum_residue((1/(k**2+1)), (k, oo, -S(1))) == -ans  # Karr convention

    # function which is neither even nor odd which works for -oo to k
    assert eval_sum_residue(1 / (k**2 + 2*k +2), (k, -oo, S(0))) == 1 + pi/(2*tanh(pi))
    assert eval_sum_residue(1 / (k**2 + 2*k +2), (k, -oo, -S(1))) == S.Half+pi/tanh(pi)/2

    # odd function that cannot be made even returns None
    assert eval_sum_residue(1/(k**3 + 1), (k, S(0), oo)) is None

    # SO issue cited on #27827
    assert summation(1 / ((k+1) ** 4 + 1), (k, -oo, oo)).simplify() == (
        sqrt(2)*pi*(1 - I)*(I/tan(sqrt(2)*pi*(1 + I)/2) +
        1/tan(sqrt(2)*pi*(1 - I)/2))/4)


@slow
def test_summation_by_residues_failing():
    x = Symbol('x')

    # Failing because of the bug in residue computation
    assert eval_sum_residue(x**2 / (x**4 + 1), (x, S(1), oo))
    assert eval_sum_residue(1 / ((x - 1)*(x - 2) + 1), (x, -oo, oo)) != 0


def test_process_limits():
    from sympy.concrete.expr_with_limits import _process_limits

    # these should be (x, Range(3)) not Range(3)
    raises(ValueError, lambda: _process_limits(
        Range(3), discrete=True))
    raises(ValueError, lambda: _process_limits(
        Range(3), discrete=False))
    # these should be (x, union) not union
    # (but then we would get a TypeError because we don't
    # handle non-contiguous sets: see below use of `union`)
    union = Or(x < 1, x > 3).as_set()
    raises(ValueError, lambda: _process_limits(
        union, discrete=True))
    raises(ValueError, lambda: _process_limits(
        union, discrete=False))