def test_partial_loops_c(): # check that loop boundaries are determined by Idx, and array strides # determined by shape of IndexedBase object. from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m, o, p = symbols('n m o p', integer=True) A = IndexedBase('A', shape=(m, p)) x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', (o, m - 5)) # Note: bounds are inclusive j = Idx('j', n) # dimension n corresponds to bounds (0, n - 1) (f1, code), (f2, interface) = codegen( ('matrix_vector', Eq(y[i], A[i, j] * x[j])), "C", "file", header=False, empty=False) assert f1 == 'file.c' expected = ( '#include "file.h"\n' '#include <math.h>\n' 'void matrix_vector(double *A, int m, int n, int o, int p, double *x, double *y) {\n' ' for (int i=o; i<%(upperi)s; i++){\n' ' y[i] = 0;\n' ' }\n' ' for (int i=o; i<%(upperi)s; i++){\n' ' for (int j=0; j<n; j++){\n' ' y[i] = y[i] + %(rhs)s;\n' ' }\n' ' }\n' '}\n') % { 'upperi': m - 4, 'rhs': '%(rhs)s' } assert (code == expected % { 'rhs': 'A[i*p + j]*x[j]' } or code == expected % { 'rhs': 'A[j + i*p]*x[j]' } or code == expected % { 'rhs': 'x[j]*A[i*p + j]' } or code == expected % { 'rhs': 'x[j]*A[j + i*p]' }) assert f2 == 'file.h' assert interface == ( '#ifndef PROJECT__FILE__H\n' '#define PROJECT__FILE__H\n' 'void matrix_vector(double *A, int m, int n, int o, int p, double *x, double *y);\n' '#endif\n')
def test_deltasummation_mul_add_x_kd_add_y_kd(): assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= 3)), (0, True)) + 3*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 1)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 1)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 2, 2)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 2)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 3, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 3)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, k)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= k)), (0, True)) + k*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= 3)), (0, True)) + (4 - k)*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, l)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= l)), (0, True)) + (l - k + 1)*(KD(i, k) + x)*y)
def test_loops(): from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m = symbols('n,m', integer=True) A, x, y = map(IndexedBase, 'Axy') i = Idx('i', m) j = Idx('j', n) (f1, code), (f2, interface) = codegen( ('matrix_vector', Eq(y[i], A[i, j] * x[j])), "F95", "file", header=False, empty=False) assert f1 == 'file.f90' expected = ('subroutine matrix_vector(A, m, n, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'INTEGER*4, intent(in) :: n\n' 'REAL*8, intent(in), dimension(1:m, 1:n) :: A\n' 'REAL*8, intent(in), dimension(1:n) :: x\n' 'REAL*8, intent(out), dimension(1:m) :: y\n' 'INTEGER*4 :: i\n' 'INTEGER*4 :: j\n' 'do i = 1, m\n' ' y(i) = 0\n' 'end do\n' 'do i = 1, m\n' ' do j = 1, n\n' ' y(i) = y(i) + %(rhs)s\n' ' end do\n' 'end do\n' 'end subroutine\n') % { 'rhs': 'A(i, j)*x(j)' } assert expected == code assert f2 == 'file.h' assert interface == ('interface\n' 'subroutine matrix_vector(A, m, n, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'INTEGER*4, intent(in) :: n\n' 'REAL*8, intent(in), dimension(1:m, 1:n) :: A\n' 'REAL*8, intent(in), dimension(1:n) :: x\n' 'REAL*8, intent(out), dimension(1:m) :: y\n' 'end subroutine\n' 'end interface\n')
def test_loops_InOut(): from sympy.tensor import IndexedBase, Idx from sympy import symbols i, j, n, m = symbols('i,j,n,m', integer=True) A, x, y = symbols('A,x,y') A = IndexedBase(A)[Idx(i, m), Idx(j, n)] x = IndexedBase(x)[Idx(j, n)] y = IndexedBase(y)[Idx(i, m)] (f1, code), (f2, interface) = codegen(('matrix_vector', Eq(y, y + A * x)), "F95", "file", header=False, empty=False) assert f1 == 'file.f90' expected = ('subroutine matrix_vector(A, m, n, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'INTEGER*4, intent(in) :: n\n' 'REAL*8, intent(in), dimension(1:m, 1:n) :: A\n' 'REAL*8, intent(in), dimension(1:n) :: x\n' 'REAL*8, intent(inout), dimension(1:m) :: y\n' 'INTEGER*4 :: i\n' 'INTEGER*4 :: j\n' 'do i = 1, m\n' ' do j = 1, n\n' ' y(i) = %(rhs)s + y(i)\n' ' end do\n' 'end do\n' 'end subroutine\n') assert (code == expected % { 'rhs': 'A(i, j)*x(j)' } or code == expected % { 'rhs': 'x(j)*A(i, j)' }) assert f2 == 'file.h' assert interface == ('interface\n' 'subroutine matrix_vector(A, m, n, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'INTEGER*4, intent(in) :: n\n' 'REAL*8, intent(in), dimension(1:m, 1:n) :: A\n' 'REAL*8, intent(in), dimension(1:n) :: x\n' 'REAL*8, intent(inout), dimension(1:m) :: y\n' 'end subroutine\n' 'end interface\n')
def test_loops_c(): from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m = symbols('n m', integer=True) A = IndexedBase('A') x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', m) j = Idx('j', n) (f1, code), (f2, interface) = codegen( ('matrix_vector', Eq(y[i], A[i, j] * x[j])), "C", "file", header=False, empty=False) assert f1 == 'file.c' expected = ( '#include "file.h"\n' '#include <math.h>\n' 'void matrix_vector(double *A, int m, int n, double *x, double *y) {\n' ' for (int i=0; i<m; i++){\n' ' y[i] = 0;\n' ' }\n' ' for (int i=0; i<m; i++){\n' ' for (int j=0; j<n; j++){\n' ' y[i] = %(rhs)s + y[i];\n' ' }\n' ' }\n' '}\n') assert (code == expected % { 'rhs': 'A[%s]*x[j]' % (i * n + j) } or code == expected % { 'rhs': 'A[%s]*x[j]' % (j + i * n) } or code == expected % { 'rhs': 'x[j]*A[%s]' % (i * n + j) } or code == expected % { 'rhs': 'x[j]*A[%s]' % (j + i * n) }) assert f2 == 'file.h' assert interface == ( '#ifndef PROJECT__FILE__H\n' '#define PROJECT__FILE__H\n' 'void matrix_vector(double *A, int m, int n, double *x, double *y);\n' '#endif\n')
def test_partial_loops_f(): # check that loop boundaries are determined by Idx, and array strides # determined by shape of IndexedBase object. from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m, o, p = symbols('n m o p', integer=True) A = IndexedBase('A', shape=(m, p)) x = IndexedBase('x') y = IndexedBase('y') i = Idx('i', (o, m - 5)) # Note: bounds are inclusive j = Idx('j', n) # dimension n corresponds to bounds (0, n - 1) (f1, code), (f2, interface) = codegen( ('matrix_vector', Eq(y[i], A[i, j] * x[j])), "F95", "file", header=False, empty=False) expected = ('subroutine matrix_vector(A, m, n, o, p, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'INTEGER*4, intent(in) :: n\n' 'INTEGER*4, intent(in) :: o\n' 'INTEGER*4, intent(in) :: p\n' 'REAL*8, intent(in), dimension(1:m, 1:p) :: A\n' 'REAL*8, intent(in), dimension(1:n) :: x\n' 'REAL*8, intent(out), dimension(1:%(iup-ilow)s) :: y\n' 'INTEGER*4 :: i\n' 'INTEGER*4 :: j\n' 'do i = %(ilow)s, %(iup)s\n' ' y(i) = 0\n' 'end do\n' 'do i = %(ilow)s, %(iup)s\n' ' do j = 1, n\n' ' y(i) = %(rhs)s + y(i)\n' ' end do\n' 'end do\n' 'end subroutine\n') % { 'rhs': '%(rhs)s', 'iup': str(m - 4), 'ilow': str(1 + o), 'iup-ilow': str(m - 4 - o) } assert code == expected % {'rhs': 'A(i, j)*x(j)'} or\ code == expected % {'rhs': 'x(j)*A(i, j)'}
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == 'x**y' assert prntr.doprint(Mod(x, 2)) == 'x % 2' assert prntr.doprint(And(x, y)) == 'x and y' assert prntr.doprint(Or(x, y)) == 'x or y' assert not prntr.module_imports assert prntr.doprint(pi) == 'math.pi' assert prntr.module_imports == {'math': {'pi'}} assert prntr.doprint(acos(x)) == 'math.acos(x)' assert prntr.doprint(Assignment(x, 2)) == 'x = 2' assert prntr.doprint(Piecewise((1, Eq(x, 0)), (2, x>6))) == '((1) if (x == 0) else (2) if (x > 6) else None)' assert prntr.doprint(Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\ ' (3) if (x > 0) else None)'
def test_inline_function(): from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m = symbols('n m', integer=True) A, x, y = map(IndexedBase, 'Axy') i = Idx('i', m) p = FCodeGen() func = implemented_function('func', Lambda(n, n * (n + 1))) routine = Routine('test_inline', Eq(y[i], func(x[i]))) code = get_string(p.dump_f95, [routine]) expected = ('subroutine test_inline(m, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m\n' 'REAL*8, intent(in), dimension(1:m) :: x\n' 'REAL*8, intent(out), dimension(1:m) :: y\n' 'INTEGER*4 :: i\n' 'do i = 1, m\n' ' y(i) = x(i)*(1 + x(i))\n' 'end do\n' 'end subroutine\n') assert code == expected
def test_dummy_loops_f95(): from sympy.tensor import IndexedBase, Idx i, m = symbols('i m', integer=True, cls=Dummy) x = IndexedBase('x') y = IndexedBase('y') i = Idx(i, m) expected = ( 'subroutine test_dummies(m_%(mcount)i, x, y)\n' 'implicit none\n' 'INTEGER*4, intent(in) :: m_%(mcount)i\n' 'REAL*8, intent(in), dimension(1:m_%(mcount)i) :: x\n' 'REAL*8, intent(out), dimension(1:m_%(mcount)i) :: y\n' 'INTEGER*4 :: i_%(icount)i\n' 'do i_%(icount)i = 1, m_%(mcount)i\n' ' y(i_%(icount)i) = x(i_%(icount)i)\n' 'end do\n' 'end subroutine\n' ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index} r = make_routine('test_dummies', Eq(y[i], x[i])) c = FCodeGen() code = get_string(c.dump_f95, [r]) assert code == expected
def test_dummy_loops_c(): from sympy.tensor import IndexedBase, Idx # the following line could also be # [Dummy(s, integer=True) for s in 'im'] # or [Dummy(integer=True) for s in 'im'] i, m = symbols('i m', integer=True, cls=Dummy) x = IndexedBase('x') y = IndexedBase('y') i = Idx(i, m) expected = ( '#include "file.h"\n' '#include <math.h>\n' 'void test_dummies(int m_%(mno)i, double *x, double *y) {\n' ' for (int i_%(ino)i=0; i_%(ino)i<m_%(mno)i; i_%(ino)i++){\n' ' y[i_%(ino)i] = x[i_%(ino)i];\n' ' }\n' '}\n' ) % {'ino': i.label.dummy_index, 'mno': m.dummy_index} r = Routine('test_dummies', Eq(y[i], x[i])) c = CCodeGen() code = get_string(c.dump_c, [r]) assert code == expected
def test_dummy_loops_c(): from sympy.tensor import IndexedBase, Idx i, m = symbols('i m', integer=True, cls=Dummy) x = IndexedBase('x') y = IndexedBase('y') i = Idx(i, m) expected = ( '#include "file.h"\n' '#include <math.h>\n' 'void test_dummies(int m_%(mno)i, double *x, double *y) {\n' ' for (int i_%(ino)i=0; i_%(ino)i<m_%(mno)i; i_%(ino)i++){\n' ' y[i_%(ino)i] = x[i_%(ino)i];\n' ' }\n' '}\n' ) % {'ino': i.label.dummy_index, 'mno': m.dummy_index} r = make_routine('test_dummies', Eq(y[i], x[i])) c89 = C89CodeGen() c99 = C99CodeGen() code = get_string(c99.dump_c, [r]) assert code == expected with raises(NotImplementedError): get_string(c89.dump_c, [r])
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == 'x**y' assert prntr.doprint(Mod(x, 2)) == 'x % 2' assert prntr.doprint(-Mod(x, y)) == '-(x % y)' assert prntr.doprint(Mod(-x, y)) == '(-x) % y' assert prntr.doprint(And(x, y)) == 'x and y' assert prntr.doprint(Or(x, y)) == 'x or y' assert not prntr.module_imports assert prntr.doprint(pi) == 'math.pi' assert prntr.module_imports == {'math': {'pi'}} assert prntr.doprint(x**Rational(1, 2)) == 'math.sqrt(x)' assert prntr.doprint(sqrt(x)) == 'math.sqrt(x)' assert prntr.module_imports == {'math': {'pi', 'sqrt'}} assert prntr.doprint(acos(x)) == 'math.acos(x)' assert prntr.doprint(Assignment(x, 2)) == 'x = 2' assert prntr.doprint(Piecewise( (1, Eq(x, 0)), (2, x > 6))) == '((1) if (x == 0) else (2) if (x > 6) else None)' assert prntr.doprint(Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\ ' (3) if (x > 0) else None)' assert prntr.doprint(sign(x)) == '(0.0 if x == 0 else math.copysign(1, x))' assert prntr.doprint(p[0, 1]) == 'p[0, 1]' assert prntr.doprint(KroneckerDelta(x, y)) == '(1 if x == y else 0)' assert prntr.doprint((2, 3)) == "(2, 3)" assert prntr.doprint([2, 3]) == "[2, 3]" assert prntr.doprint(Min(x, y)) == "min(x, y)" assert prntr.doprint(Max(x, y)) == "max(x, y)"
def test_jl_tensor_loops_multiple_contractions(): # see comments in previous test about vectorizing from sympy.tensor import IndexedBase, Idx from sympy import symbols n, m, o, p = symbols("n m o p", integer=True) A = IndexedBase("A") B = IndexedBase("B") y = IndexedBase("y") i = Idx("i", m) j = Idx("j", n) k = Idx("k", o) l = Idx("l", p) (result, ) = codegen( ("tensorthing", Eq(y[i], B[j, k, l] * A[i, j, k, l])), "Julia", header=False, empty=False, ) source = result[1] expected = ("function tensorthing(y, A, B, m, n, o, p)\n" " for i = 1:m\n" " y[i] = 0\n" " end\n" " for i = 1:m\n" " for j = 1:n\n" " for k = 1:o\n" " for l = 1:p\n" " y[i] = A[i,j,k,l].*B[j,k,l] + y[i]\n" " end\n" " end\n" " end\n" " end\n" " return y\n" "end\n") assert source == expected
def test_deltasummation_mul_add_x_y_add_kd_kd(): assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, 1, 3)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= 3)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, 1, 1)) == piecewise_fold( Piecewise((x + y, Eq(i, 1)), (0, True)) + Piecewise((x + y, Eq(j, 1)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, 2, 2)) == piecewise_fold( Piecewise((x + y, Eq(i, 2)), (0, True)) + Piecewise((x + y, Eq(j, 2)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, 3, 3)) == piecewise_fold( Piecewise((x + y, Eq(i, 3)), (0, True)) + Piecewise((x + y, Eq(j, 3)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, 1, l)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= l)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, l, 3)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(l <= j, j <= 3)), (0, True))) assert ds((x + y) * (KD(i, k) + KD(j, k)), (k, l, m)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= m)), (0, True)) + Piecewise((x + y, And(l <= j, j <= m)), (0, True)))
def test_deltasummation_add_mul_x_kd_kd(): assert ds(x * KD(i, k) + KD(j, k), (k, 1, 3)) == piecewise_fold( Piecewise((x, And(1 <= i, i <= 3)), (0, True)) + Piecewise((1, And(1 <= j, j <= 3)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, 1, 1)) == piecewise_fold( Piecewise((x, Eq(i, 1)), (0, True)) + Piecewise((1, Eq(j, 1)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, 2, 2)) == piecewise_fold( Piecewise((x, Eq(i, 2)), (0, True)) + Piecewise((1, Eq(j, 2)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, 3, 3)) == piecewise_fold( Piecewise((x, Eq(i, 3)), (0, True)) + Piecewise((1, Eq(j, 3)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, 1, l)) == piecewise_fold( Piecewise((x, And(1 <= i, i <= l)), (0, True)) + Piecewise((1, And(1 <= j, j <= l)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, l, 3)) == piecewise_fold( Piecewise((x, And(l <= i, i <= 3)), (0, True)) + Piecewise((1, And(l <= j, j <= 3)), (0, True))) assert ds(x * KD(i, k) + KD(j, k), (k, l, m)) == piecewise_fold( Piecewise((x, And(l <= i, i <= m)), (0, True)) + Piecewise((1, And(l <= j, j <= m)), (0, True)))
def test_deltasummation(): ds = deltasummation assert ds(x, (j, 1, 0)) == 0 assert ds(x, (j, 1, 3)) == 3*x assert ds(x + y, (j, 1, 3)) == 3*(x + y) assert ds(x*y, (j, 1, 3)) == 3*x*y assert ds(KD(i, j), (k, 1, 3)) == 3*KD(i, j) assert ds(x*KD(i, j), (k, 1, 3)) == 3*x*KD(i, j) assert ds(x*y*KD(i, j), (k, 1, 3)) == 3*x*y*KD(i, j) n = symbols('n', integer=True, nonzero=True) assert ds(KD(n, 0), (n, 1, 3)) == 0 # return unevaluated, until it gets implemented assert ds(KD(i**2, j**2), (j, -oo, oo)) == \ Sum(KD(i**2, j**2), (j, -oo, oo)) assert Piecewise((KD(i, k), And(S(1) <= i, i <= 3)), (0, True)) == \ ds(KD(i, j)*KD(j, k), (j, 1, 3)) == \ ds(KD(j, k)*KD(i, j), (j, 1, 3)) assert ds(KD(i, k), (k, -oo, oo)) == 1 assert ds(KD(i, k), (k, 0, oo)) == Piecewise((1, i >= 0), (0, True)) assert ds(KD(i, k), (k, 1, 3)) == \ Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) assert ds(k*KD(i, j)*KD(j, k), (k, -oo, oo)) == j*KD(i, j) assert ds(j*KD(i, j), (j, -oo, oo)) == i assert ds(i*KD(i, j), (i, -oo, oo)) == j assert ds(x, (i, 1, 3)) == 3*x assert ds((i + j)*KD(i, j), (j, -oo, oo)) == 2*i assert ds(KD(i, j), (j, 1, 3)) == \ Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) assert ds(KD(i, j), (j, 1, 1)) == Piecewise((1, Eq(i, 1)), (0, True)) assert ds(KD(i, j), (j, 2, 2)) == Piecewise((1, Eq(i, 2)), (0, True)) assert ds(KD(i, j), (j, 3, 3)) == Piecewise((1, Eq(i, 3)), (0, True)) assert ds(KD(i, j), (j, 1, k)) == \ Piecewise((1, And(S(1) <= i, i <= k)), (0, True)) assert ds(KD(i, j), (j, k, 3)) == \ Piecewise((1, And(k <= i, i <= 3)), (0, True)) assert ds(KD(i, j), (j, k, l)) == \ Piecewise((1, And(k <= i, i <= l)), (0, True)) assert ds(x*KD(i, j), (j, 1, 3)) == \ Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) assert ds(x*KD(i, j), (j, 1, 1)) == Piecewise((x, Eq(i, 1)), (0, True)) assert ds(x*KD(i, j), (j, 2, 2)) == Piecewise((x, Eq(i, 2)), (0, True)) assert ds(x*KD(i, j), (j, 3, 3)) == Piecewise((x, Eq(i, 3)), (0, True)) assert ds(x*KD(i, j), (j, 1, k)) == \ Piecewise((x, And(S(1) <= i, i <= k)), (0, True)) assert ds(x*KD(i, j), (j, k, 3)) == \ Piecewise((x, And(k <= i, i <= 3)), (0, True)) assert ds(x*KD(i, j), (j, k, l)) == \ Piecewise((x, And(k <= i, i <= l)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, 3)) == \ Piecewise((x + y, And(S(1) <= i, i <= 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, 1)) == \ Piecewise((x + y, Eq(i, 1)), (0, True)) assert ds((x + y)*KD(i, j), (j, 2, 2)) == \ Piecewise((x + y, Eq(i, 2)), (0, True)) assert ds((x + y)*KD(i, j), (j, 3, 3)) == \ Piecewise((x + y, Eq(i, 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, 1, k)) == \ Piecewise((x + y, And(S(1) <= i, i <= k)), (0, True)) assert ds((x + y)*KD(i, j), (j, k, 3)) == \ Piecewise((x + y, And(k <= i, i <= 3)), (0, True)) assert ds((x + y)*KD(i, j), (j, k, l)) == \ Piecewise((x + y, And(k <= i, i <= l)), (0, True)) assert ds(KD(i, k) + KD(j, k), (k, 1, 3)) == piecewise_fold( Piecewise((1, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 1, 1)) == piecewise_fold( Piecewise((1, Eq(i, 1)), (0, True)) + Piecewise((1, Eq(j, 1)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 2, 2)) == piecewise_fold( Piecewise((1, Eq(i, 2)), (0, True)) + Piecewise((1, Eq(j, 2)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 3, 3)) == piecewise_fold( Piecewise((1, Eq(i, 3)), (0, True)) + Piecewise((1, Eq(j, 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, 1, l)) == piecewise_fold( Piecewise((1, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= l)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, l, 3)) == piecewise_fold( Piecewise((1, And(l <= i, i <= 3)), (0, True)) + Piecewise((1, And(l <= j, j <= 3)), (0, True))) assert ds(KD(i, k) + KD(j, k), (k, l, m)) == piecewise_fold( Piecewise((1, And(l <= i, i <= m)), (0, True)) + Piecewise((1, And(l <= j, j <= m)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, 3)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, 1)) == piecewise_fold( Piecewise((x, Eq(i, 1)), (0, True)) + Piecewise((1, Eq(j, 1)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 2, 2)) == piecewise_fold( Piecewise((x, Eq(i, 2)), (0, True)) + Piecewise((1, Eq(j, 2)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 3, 3)) == piecewise_fold( Piecewise((x, Eq(i, 3)), (0, True)) + Piecewise((1, Eq(j, 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, 1, l)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((1, And(S(1) <= j, j <= l)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, l, 3)) == piecewise_fold( Piecewise((x, And(l <= i, i <= 3)), (0, True)) + Piecewise((1, And(l <= j, j <= 3)), (0, True))) assert ds(x*KD(i, k) + KD(j, k), (k, l, m)) == piecewise_fold( Piecewise((x, And(l <= i, i <= m)), (0, True)) + Piecewise((1, And(l <= j, j <= m)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, 3)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((x, And(S(1) <= j, j <= 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, 1)) == piecewise_fold( Piecewise((x, Eq(i, 1)), (0, True)) + Piecewise((x, Eq(j, 1)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 2, 2)) == piecewise_fold( Piecewise((x, Eq(i, 2)), (0, True)) + Piecewise((x, Eq(j, 2)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 3, 3)) == piecewise_fold( Piecewise((x, Eq(i, 3)), (0, True)) + Piecewise((x, Eq(j, 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, 1, l)) == piecewise_fold( Piecewise((x, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((x, And(S(1) <= j, j <= l)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, l, 3)) == piecewise_fold( Piecewise((x, And(l <= i, i <= 3)), (0, True)) + Piecewise((x, And(l <= j, j <= 3)), (0, True))) assert ds(x*(KD(i, k) + KD(j, k)), (k, l, m)) == piecewise_fold( Piecewise((x, And(l <= i, i <= m)), (0, True)) + Piecewise((x, And(l <= j, j <= m)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, 3)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, 1)) == piecewise_fold( Piecewise((x + y, Eq(i, 1)), (0, True)) + Piecewise((x + y, Eq(j, 1)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 2, 2)) == piecewise_fold( Piecewise((x + y, Eq(i, 2)), (0, True)) + Piecewise((x + y, Eq(j, 2)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 3, 3)) == piecewise_fold( Piecewise((x + y, Eq(i, 3)), (0, True)) + Piecewise((x + y, Eq(j, 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, 1, l)) == piecewise_fold( Piecewise((x + y, And(S(1) <= i, i <= l)), (0, True)) + Piecewise((x + y, And(S(1) <= j, j <= l)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, l, 3)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= 3)), (0, True)) + Piecewise((x + y, And(l <= j, j <= 3)), (0, True))) assert ds((x + y)*(KD(i, k) + KD(j, k)), (k, l, m)) == piecewise_fold( Piecewise((x + y, And(l <= i, i <= m)), (0, True)) + Piecewise((x + y, And(l <= j, j <= m)), (0, True))) assert ds(x*y + x*KD(i, j), (j, 1, 3)) == \ Piecewise((3*x*y + x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*y + x*KD(i, j), (j, 1, 1)) == \ Piecewise((x*y + x, Eq(i, 1)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 2, 2)) == \ Piecewise((x*y + x, Eq(i, 2)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 3, 3)) == \ Piecewise((x*y + x, Eq(i, 3)), (x*y, True)) assert ds(x*y + x*KD(i, j), (j, 1, k)) == \ Piecewise((k*x*y + x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*y + x*KD(i, j), (j, k, 3)) == \ Piecewise(((4 - k)*x*y + x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*y + x*KD(i, j), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, 3)) == \ Piecewise((3*x*y + x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, 1)) == \ Piecewise((x*y + x, Eq(i, 1)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 2, 2)) == \ Piecewise((x*y + x, Eq(i, 2)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 3, 3)) == \ Piecewise((x*y + x, Eq(i, 3)), (x*y, True)) assert ds(x*(y + KD(i, j)), (j, 1, k)) == \ Piecewise((k*x*y + x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*(y + KD(i, j)), (j, k, 3)) == \ Piecewise(((4 - k)*x*y + x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*(y + KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, 3)) == \ Piecewise((3*x*y + 2*x, And(S(1) <= i, i <= 3)), (3*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, 1)) == \ Piecewise((x*y + 2*x, Eq(i, 1)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 2, 2)) == \ Piecewise((x*y + 2*x, Eq(i, 2)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 3, 3)) == \ Piecewise((x*y + 2*x, Eq(i, 3)), (x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, 1, k)) == \ Piecewise((k*x*y + 2*x, And(S(1) <= i, i <= k)), (k*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, k, 3)) == Piecewise( ((4 - k)*x*y + 2*x, And(k <= i, i <= 3)), ((4 - k)*x*y, True)) assert ds(x*(y + 2*KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*x*y + 2*x, And(k <= i, i <= l)), ((l - k + 1)*x*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, 3)) == Piecewise( (3*(x + y)*y + x + y, And(S(1) <= i, i <= 3)), (3*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, 1)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 1)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 2, 2)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 2)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 3, 3)) == \ Piecewise(((x + y)*y + x + y, Eq(i, 3)), ((x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, 1, k)) == Piecewise( (k*(x + y)*y + x + y, And(S(1) <= i, i <= k)), (k*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, k, 3)) == Piecewise( ((4 - k)*(x + y)*y + x + y, And(k <= i, i <= 3)), ((4 - k)*(x + y)*y, True)) assert ds((x + y)*(y + KD(i, j)), (j, k, l)) == Piecewise( ((l - k + 1)*(x + y)*y + x + y, And(k <= i, i <= l)), ((l - k + 1)*(x + y)*y, True)) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= 3)), (0, True)) + 3*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, 1)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 1)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 2, 2)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 2)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 3, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, Eq(i, 3)), (0, True)) + (KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, 1, k)) == piecewise_fold( Piecewise((KD(i, k) + x, And(S(1) <= i, i <= k)), (0, True)) + k*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, 3)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= 3)), (0, True)) + (4 - k)*(KD(i, k) + x)*y) assert ds((x + KD(i, k))*(y + KD(i, j)), (j, k, l)) == piecewise_fold( Piecewise((KD(i, k) + x, And(k <= i, i <= l)), (0, True)) + (l - k + 1)*(KD(i, k) + x)*y)
def trigintegrate(f, x, conds='piecewise'): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos, tan, sec, csc, cot >>> from sympy.integrals.trigonometry import trigintegrate >>> from sympy.abc import x >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - sin(x)*cos(x)/2 >>> trigintegrate(tan(x)*sec(x), x) 1/cos(x) >>> trigintegrate(sin(x)*tan(x), x) -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x) http://en.wikibooks.org/wiki/Calculus/Integration_techniques See Also ======== sympy.integrals.integrals.Integral.doit sympy.integrals.integrals.Integral """ from sympy.integrals.integrals import integrate pat, a, n, m = _pat_sincos(x) f = f.rewrite('sincos') M = f.match(pat) if M is None: return n, m = M[n], M[m] if n is S.Zero and m is S.Zero: return x zz = x if n is S.Zero else S.Zero a = M[a] if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1 - u**2)**((n - 1) / 2) * u**m uu = cos(a * x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1 - u**2)**((m - 1) / 2) uu = sin(a * x) fi = integrate(ff, u) # XXX cyclic deps fx = fi.subs(u, uu) if conds == 'piecewise': return Piecewise((zz, Eq(a, 0)), (fx / a, True)) return fx / a # n & m are both even # # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1 - S ) = sum(i, (-) * B(k, i) * S ) if m > 0: for i in range(0, m // 2 + 1): res += ((-1)**i * binomial(m // 2, i) * _sin_pow_integrate(n + 2 * i, x)) elif m == 0: res = _sin_pow_integrate(n, x) else: # m < 0 , |n| > |m| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # -1 m+1 n-1 n - 1 | m+2 n-2 # ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # m + 1 m + 1 | # / res = (Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * trigintegrate(cos(x)**(m + 2) * sin(x)**(n - 2), x)) elif m_: # 2k 2 k i 2i # S = (1 - C ) = sum(i, (-) * B(k, i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m, n >0 ; m, n belong to Z - {0} # n 2 # sin (x) term is expanded here in terms of cos (x), # and then integrated. # for i in range(0, n // 2 + 1): res += ((-1)**i * binomial(n // 2, i) * _cos_pow_integrate(m + 2 * i, x)) elif n == 0: # / # | # | 1 # | _ _ _ # | m # | cos (x) # / # res = _cos_pow_integrate(m, x) else: # n < 0 , |m| > |n| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # 1 m-1 n+1 m - 1 | m-2 n+2 # _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # n + 1 n + 1 | # / res = (Rational(1, n + 1) * cos(x)**(m - 1) * sin(x)**(n + 1) + Rational(m - 1, n + 1) * trigintegrate(cos(x)**(m - 2) * sin(x)**(n + 2), x)) else: if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res = integrate((Rational(1, 2) * sin(2 * x))**m, x) elif (m == -n): if n < 0: # Same as the scheme described above. # the function argument to integrate in the end will # be 1 , this cannot be integrated by trigintegrate. # Hence use sympy.integrals.integrate. res = (Rational(1, n + 1) * cos(x)**(m - 1) * sin(x)**(n + 1) + Rational(m - 1, n + 1) * integrate(cos(x)**(m - 2) * sin(x)**(n + 2), x)) else: res = ( Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * integrate(cos(x)**(m + 2) * sin(x)**(n - 2), x)) if conds == 'piecewise': return Piecewise((zz, Eq(a, 0)), (res.subs(x, a * x) / a, True)) return res.subs(x, a * x) / a
def _regular_point_ellipse(self, a, b, c, d, e, f): D = 4 * a * c - b**2 ok = D if not ok: raise ValueError("Rational Point on the conic does not exist") if a == 0 and c == 0: K = -1 L = 4 * (d * e - b * f) elif c != 0: K = D L = 4 * c**2 * d**2 - 4 * b * c * d * e + 4 * a * c * e**2 + 4 * b**2 * c * f - 16 * a * c**2 * f else: K = D L = 4 * a**2 * e**2 - 4 * b * a * d * e + 4 * b**2 * a * f ok = L != 0 and not (K > 0 and L < 0) if not ok: raise ValueError("Rational Point on the conic does not exist") K = Rational(K).limit_denominator(10**12) L = Rational(L).limit_denominator(10**12) k1, k2 = K.p, K.q l1, l2 = L.p, L.q g = gcd(k2, l2) a1 = (l2 * k2) / g b1 = (k1 * l2) / g c1 = -(l1 * k2) / g a2 = sign(a1) * core(abs(a1), 2) r1 = sqrt(a1 / a2) b2 = sign(b1) * core(abs(b1), 2) r2 = sqrt(b1 / b2) c2 = sign(c1) * core(abs(c1), 2) r3 = sqrt(c1 / c2) g = gcd(gcd(a2, b2), c2) a2 = a2 / g b2 = b2 / g c2 = c2 / g g1 = gcd(a2, b2) a2 = a2 / g1 b2 = b2 / g1 c2 = c2 * g1 g2 = gcd(a2, c2) a2 = a2 / g2 b2 = b2 * g2 c2 = c2 / g2 g3 = gcd(b2, c2) a2 = a2 * g3 b2 = b2 / g3 c2 = c2 / g3 x, y, z = symbols("x y z") eq = a2 * x**2 + b2 * y**2 + c2 * z**2 solutions = diophantine(eq) if len(solutions) == 0: raise ValueError("Rational Point on the conic does not exist") flag = False for sol in solutions: syms = Tuple(*sol).free_symbols rep = {s: 3 for s in syms} sol_z = sol[2] if sol_z == 0: flag = True continue if not (isinstance(sol_z, Integer) or isinstance(sol_z, int)): syms_z = sol_z.free_symbols if len(syms_z) == 1: p = next(iter(syms_z)) p_values = Complement( S.Integers, solveset(Eq(sol_z, 0), p, S.Integers)) rep[p] = next(iter(p_values)) if len(syms_z) == 2: p, q = list(ordered(syms_z)) for i in S.Integers: subs_sol_z = sol_z.subs(p, i) q_values = Complement( S.Integers, solveset(Eq(subs_sol_z, 0), q, S.Integers)) if not q_values.is_empty: rep[p] = i rep[q] = next(iter(q_values)) break if len(syms) != 0: x, y, z = tuple(s.subs(rep) for s in sol) else: x, y, z = sol flag = False break if flag: raise ValueError("Rational Point on the conic does not exist") x = (x * g3) / r1 y = (y * g2) / r2 z = (z * g1) / r3 x = x / z y = y / z if a == 0 and c == 0: x_reg = (x + y - 2 * e) / (2 * b) y_reg = (x - y - 2 * d) / (2 * b) elif c != 0: x_reg = (x - 2 * d * c + b * e) / K y_reg = (y - b * x_reg - e) / (2 * c) else: y_reg = (x - 2 * e * a + b * d) / K x_reg = (y - b * y_reg - d) / (2 * a) return x_reg, y_reg
def _is_1x1(self): """Returns true if the matrix is known to be 1x1""" shape = self.shape return Eq(shape[0], 1) & Eq(shape[1], 1)
def eval_sum_symbolic(f, limits): (i, a, b) = limits if not f.has(i): return f * (b - a + 1) # Linearity if f.is_Mul: L, R = f.as_two_terms() if not L.has(i): sR = eval_sum_symbolic(R, (i, a, b)) if sR: return L * sR if not R.has(i): sL = eval_sum_symbolic(L, (i, a, b)) if sL: return R * sL try: f = apart(f, i) # see if it becomes an Add except PolynomialError: pass if f.is_Add: L, R = f.as_two_terms() lrsum = telescopic(L, R, (i, a, b)) if lrsum: return lrsum lsum = eval_sum_symbolic(L, (i, a, b)) rsum = eval_sum_symbolic(R, (i, a, b)) if None not in (lsum, rsum): return lsum + rsum # Polynomial terms with Faulhaber's formula n = Wild('n') result = f.match(i**n) if result is not None: n = result[n] if n.is_Integer: if n >= 0: return ((C.bernoulli(n + 1, b + 1) - C.bernoulli(n + 1, a)) / (n + 1)).expand() elif a.is_Integer and a >= 1: if n == -1: return C.harmonic(b) - C.harmonic(a - 1) else: return C.harmonic(b, abs(n)) - C.harmonic(a - 1, abs(n)) if not (a.has(S.Infinity, S.NegativeInfinity) or b.has(S.Infinity, S.NegativeInfinity)): # Geometric terms c1 = C.Wild('c1', exclude=[i]) c2 = C.Wild('c2', exclude=[i]) c3 = C.Wild('c3', exclude=[i]) e = f.match(c1**(c2 * i + c3)) if e is not None: p = (c1**c3).subs(e) q = (c1**c2).subs(e) r = p * (q**a - q**(b + 1)) / (1 - q) l = p * (b - a + 1) return Piecewise((l, Eq(q, S.One)), (r, True)) r = gosper_sum(f, (i, a, b)) if not r in (None, S.NaN): return r return eval_sum_hyper(f, (i, a, b))