<s> from __future__ import print_function , division <EOL> from sympy . concrete . expr_with_limits import AddWithLimits <EOL> from sympy . concrete . expr_with_intlimits import ExprWithIntLimits <EOL> from sympy . core . function import Derivative <EOL> from sympy . core . relational import Eq <EOL> from sympy . core . singleton import S <EOL> from sympy . core . symbol import Dummy , Wild <EOL> from sympy . core . add import Add <EOL> from sympy . calculus . singularities import is_decreasing <EOL> from sympy . concrete . gosper import gosper_sum <EOL> from sympy . functions . special . zeta_functions import zeta <EOL> from sympy . functions . elementary . piecewise import Piecewise <EOL> from sympy . logic . boolalg import And <EOL> from sympy . polys import apart , PolynomialError <EOL> from sympy . solvers import solve <EOL> from sympy . series . limits import limit <EOL> from sympy . series . order import O <EOL> from sympy . core . compatibility import range <EOL> from sympy . tensor . indexed import Idx <EOL> class Sum ( AddWithLimits , ExprWithIntLimits ) : <EOL> r"""<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT>' ] <EOL> def __new__ ( cls , function , * symbols , ** assumptions ) : <EOL> obj = AddWithLimits . __new__ ( cls , function , * symbols , ** assumptions ) <EOL> if not hasattr ( obj , '<STR_LIT>' ) : <EOL> return obj <EOL> if any ( len ( l ) != <NUM_LIT:3> or None in l for l in obj . limits ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return obj <EOL> def _eval_is_zero ( self ) : <EOL> if self . function . is_zero : <EOL> return True <EOL> def doit ( self , ** hints ) : <EOL> if hints . get ( '<STR_LIT>' , True ) : <EOL> f = self . function . doit ( ** hints ) <EOL> else : <EOL> f = self . function <EOL> if self . function . is_Matrix : <EOL> return self . expand ( ) . doit ( ) <EOL> for n , limit in enumerate ( self . limits ) : <EOL> i , a , b = limit <EOL> dif = b - a <EOL> if dif . is_integer and ( dif < <NUM_LIT:0> ) == True : <EOL> a , b = b + <NUM_LIT:1> , a - <NUM_LIT:1> <EOL> f = - f <EOL> if isinstance ( i , Idx ) : <EOL> i = i . label <EOL> newf = eval_sum ( f , ( i , a , b ) ) <EOL> if newf is None : <EOL> if f == self . function : <EOL> zeta_function = self . eval_zeta_function ( f , ( i , a , b ) ) <EOL> if zeta_function is not None : <EOL> return zeta_function <EOL> return self <EOL> else : <EOL> return self . func ( f , * self . limits [ n : ] ) <EOL> f = newf <EOL> if hints . get ( '<STR_LIT>' , True ) : <EOL> if not isinstance ( f , Piecewise ) : <EOL> return f . doit ( ** hints ) <EOL> return f <EOL> def eval_zeta_function ( self , f , limits ) : <EOL> """<STR_LIT>""" <EOL> i , a , b = limits <EOL> w , y , z = Wild ( '<STR_LIT:w>' , exclude = [ i ] ) , Wild ( '<STR_LIT:y>' , exclude = [ i ] ) , Wild ( '<STR_LIT:z>' , exclude = [ i ] ) <EOL> result = f . match ( ( w * i + y ) ** ( - z ) ) <EOL> if result is not None and b == S . Infinity : <EOL> coeff = <NUM_LIT:1> / result [ w ] ** result [ z ] <EOL> s = result [ z ] <EOL> q = result [ y ] / result [ w ] + a <EOL> return Piecewise ( ( coeff * zeta ( s , q ) , And ( q > <NUM_LIT:0> , s > <NUM_LIT:1> ) ) , ( self , True ) ) <EOL> def _eval_derivative ( self , x ) : <EOL> """<STR_LIT>""" <EOL> if x not in self . free_symbols : <EOL> return S . Zero <EOL> f , limits = self . function , list ( self . limits ) <EOL> limit = limits . pop ( - <NUM_LIT:1> ) <EOL> if limits : <EOL> f = self . func ( f , * limits ) <EOL> if len ( limit ) == <NUM_LIT:3> : <EOL> _ , a , b = limit <EOL> if x in a . free_symbols or x in b . free_symbols : <EOL> return None <EOL> df = Derivative ( f , x , evaluate = True ) <EOL> rv = self . func ( df , limit ) <EOL> if limit [ <NUM_LIT:0> ] not in df . free_symbols : <EOL> rv = rv . doit ( ) <EOL> return rv <EOL> else : <EOL> return NotImplementedError ( '<STR_LIT>' ) <EOL> def _eval_difference_delta ( self , n , step ) : <EOL> k , _ , upper = self . args [ - <NUM_LIT:1> ] <EOL> new_upper = upper . subs ( n , n + step ) <EOL> if len ( self . args ) == <NUM_LIT:2> : <EOL> f = self . args [ <NUM_LIT:0> ] <EOL> else : <EOL> f = self . func ( * self . args [ : - <NUM_LIT:1> ] ) <EOL> return Sum ( f , ( k , upper + <NUM_LIT:1> , new_upper ) ) . doit ( ) <EOL> def _eval_simplify ( self , ratio , measure ) : <EOL> from sympy . simplify . simplify import sum_simplify <EOL> return sum_simplify ( self ) <EOL> def _eval_summation ( self , f , x ) : <EOL> return None <EOL> def is_convergent ( self ) : <EOL> r"""<STR_LIT>""" <EOL> from sympy import Interval , Integral , Limit , log , symbols , Ge , Gt , simplify <EOL> p , q = symbols ( '<STR_LIT>' , cls = Wild ) <EOL> sym = self . limits [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> lower_limit = self . limits [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> upper_limit = self . limits [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> sequence_term = self . function <EOL> if len ( sequence_term . free_symbols ) > <NUM_LIT:1> : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if lower_limit . is_finite and upper_limit . is_finite : <EOL> return S . true <EOL> if lower_limit is S . NegativeInfinity : <EOL> if upper_limit is S . Infinity : <EOL> return Sum ( sequence_term , ( sym , <NUM_LIT:0> , S . Infinity ) ) . is_convergent ( ) and Sum ( sequence_term , ( sym , S . NegativeInfinity , <NUM_LIT:0> ) ) . is_convergent ( ) <EOL> sequence_term = simplify ( sequence_term . xreplace ( { sym : - sym } ) ) <EOL> lower_limit = - upper_limit <EOL> upper_limit = S . Infinity <EOL> interval = Interval ( lower_limit , upper_limit ) <EOL> if sequence_term . is_Piecewise : <EOL> for func_cond in sequence_term . args : <EOL> if func_cond [ <NUM_LIT:1> ] . func is Ge or func_cond [ <NUM_LIT:1> ] . func is Gt or func_cond [ <NUM_LIT:1> ] == True : <EOL> return Sum ( func_cond [ <NUM_LIT:0> ] , ( sym , lower_limit , upper_limit ) ) . is_convergent ( ) <EOL> return S . true <EOL> try : <EOL> lim_val = limit ( sequence_term , sym , upper_limit ) <EOL> if lim_val . is_number and lim_val is not S . Zero : <EOL> return S . false <EOL> except NotImplementedError : <EOL> pass <EOL> try : <EOL> lim_val_abs = limit ( abs ( sequence_term ) , sym , upper_limit ) <EOL> if lim_val_abs . is_number and lim_val_abs is not S . Zero : <EOL> return S . false <EOL> except NotImplementedError : <EOL> pass <EOL> order = O ( sequence_term , ( sym , S . Infinity ) ) <EOL> p1_series_test = order . expr . match ( sym ** p ) <EOL> if p1_series_test is not None : <EOL> if p1_series_test [ p ] < - <NUM_LIT:1> : <EOL> return S . true <EOL> if p1_series_test [ p ] > - <NUM_LIT:1> : <EOL> return S . false <EOL> p2_series_test = order . expr . match ( ( <NUM_LIT:1> / sym ) ** p ) <EOL> if p2_series_test is not None : <EOL> if p2_series_test [ p ] > <NUM_LIT:1> : <EOL> return S . true <EOL> if p2_series_test [ p ] < <NUM_LIT:1> : <EOL> return S . false <EOL> lim = Limit ( abs ( sequence_term ) ** ( <NUM_LIT:1> / sym ) , sym , S . Infinity ) <EOL> lim_evaluated = lim . doit ( ) <EOL> if lim_evaluated . is_number : <EOL> if lim_evaluated < <NUM_LIT:1> : <EOL> return S . true <EOL> if lim_evaluated > <NUM_LIT:1> : <EOL> return S . false <EOL> dict_val = sequence_term . match ( ( - <NUM_LIT:1> ) ** ( sym + p ) * q ) <EOL> if not dict_val [ p ] . has ( sym ) and is_decreasing ( dict_val [ q ] , interval ) : <EOL> return S . true <EOL> log_test = order . expr . match ( <NUM_LIT:1> / ( log ( sym ) ** p ) ) <EOL> if log_test is not None : <EOL> return S . false <EOL> log_n_test = order . expr . match ( <NUM_LIT:1> / ( sym * ( log ( sym ) ) ** p ) ) <EOL> if log_n_test is not None : <EOL> if log_n_test [ p ] > <NUM_LIT:1> : <EOL> return S . true <EOL> return S . false <EOL> log_log_n_test = order . expr . match ( <NUM_LIT:1> / ( sym * ( log ( sym ) * log ( log ( sym ) ) ** p ) ) ) <EOL> if log_log_n_test is not None : <EOL> if log_log_n_test [ p ] > <NUM_LIT:1> : <EOL> return S . true <EOL> return S . false <EOL> n_log_test = order . expr . match ( <NUM_LIT:1> / ( sym ** p * log ( sym ) ) ) <EOL> if n_log_test is not None : <EOL> if n_log_test [ p ] > <NUM_LIT:1> : <EOL> return S . true <EOL> return S . false <EOL> if is_decreasing ( sequence_term , interval ) : <EOL> integral_val = Integral ( sequence_term , ( sym , lower_limit , upper_limit ) ) <EOL> try : <EOL> integral_val_evaluated = integral_val . doit ( ) <EOL> if integral_val_evaluated . is_number : <EOL> return S ( integral_val_evaluated . is_finite ) <EOL> except NotImplementedError : <EOL> pass <EOL> if order . expr . is_Mul : <EOL> a_n , b_n = order . expr . args [ <NUM_LIT:0> ] , order . expr . args [ <NUM_LIT:1> ] <EOL> m = Dummy ( '<STR_LIT:m>' , integer = True ) <EOL> def _dirichlet_test ( g_n ) : <EOL> try : <EOL> ing_val = limit ( Sum ( g_n , ( sym , interval . inf , m ) ) . doit ( ) , m , S . Infinity ) <EOL> if ing_val . is_finite : <EOL> return S . true <EOL> except NotImplementedError : <EOL> pass <EOL> if is_decreasing ( a_n , interval ) : <EOL> dirich1 = _dirichlet_test ( b_n ) <EOL> if dirich1 is not None : <EOL> return dirich1 <EOL> if is_decreasing ( b_n , interval ) : <EOL> dirich2 = _dirichlet_test ( a_n ) <EOL> if dirich2 is not None : <EOL> return dirich2 <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( sequence_term ) ) <EOL> def is_absolutely_convergent ( self ) : <EOL> """<STR_LIT>""" <EOL> return Sum ( abs ( self . function ) , self . limits ) . is_convergent ( ) <EOL> def euler_maclaurin ( self , m = <NUM_LIT:0> , n = <NUM_LIT:0> , eps = <NUM_LIT:0> , eval_integral = True ) : <EOL> """<STR_LIT>""" <EOL> from sympy . functions import bernoulli , factorial <EOL> from sympy . integrals import Integral <EOL> m = int ( m ) <EOL> n = int ( n ) <EOL> f = self . function <EOL> if len ( self . limits ) != <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> i , a , b = self . limits [ <NUM_LIT:0> ] <EOL> if ( a > b ) == True : <EOL> if a - b == <NUM_LIT:1> : <EOL> return S . Zero , S . Zero <EOL> a , b = b + <NUM_LIT:1> , a - <NUM_LIT:1> <EOL> f = - f <EOL> s = S . Zero <EOL> if m : <EOL> if b . is_Integer and a . is_Integer : <EOL> m = min ( m , b - a + <NUM_LIT:1> ) <EOL> if not eps or f . is_polynomial ( i ) : <EOL> for k in range ( m ) : <EOL> s += f . subs ( i , a + k ) <EOL> else : <EOL> term = f . subs ( i , a ) <EOL> if term : <EOL> test = abs ( term . evalf ( <NUM_LIT:3> ) ) < eps <EOL> if test == True : <EOL> return s , abs ( term ) <EOL> elif not ( test == False ) : <EOL> return term , S . Zero <EOL> s += term <EOL> for k in range ( <NUM_LIT:1> , m ) : <EOL> term = f . subs ( i , a + k ) <EOL> if abs ( term . evalf ( <NUM_LIT:3> ) ) < eps and term != <NUM_LIT:0> : <EOL> return s , abs ( term ) <EOL> s += term <EOL> if b - a + <NUM_LIT:1> == m : <EOL> return s , S . Zero <EOL> a += m <EOL> x = Dummy ( '<STR_LIT:x>' ) <EOL> I = Integral ( f . subs ( i , x ) , ( x , a , b ) ) <EOL> if eval_integral : <EOL> I = I . doit ( ) <EOL> s += I <EOL> def fpoint ( expr ) : <EOL> if b is S . Infinity : <EOL> return expr . subs ( i , a ) , <NUM_LIT:0> <EOL> return expr . subs ( i , a ) , expr . subs ( i , b ) <EOL> fa , fb = fpoint ( f ) <EOL> iterm = ( fa + fb ) / <NUM_LIT:2> <EOL> g = f . diff ( i ) <EOL> for k in range ( <NUM_LIT:1> , n + <NUM_LIT:2> ) : <EOL> ga , gb = fpoint ( g ) <EOL> term = bernoulli ( <NUM_LIT:2> * k ) / factorial ( <NUM_LIT:2> * k ) * ( gb - ga ) <EOL> if ( eps and term and abs ( term . evalf ( <NUM_LIT:3> ) ) < eps ) or ( k > n ) : <EOL> break <EOL> s += term <EOL> g = g . diff ( i , <NUM_LIT:2> , simplify = False ) <EOL> return s + iterm , abs ( term ) <EOL> def reverse_order ( self , * indices ) : <EOL> """<STR_LIT>""" <EOL> l_indices = list ( indices ) <EOL> for i , indx in enumerate ( l_indices ) : <EOL> if not isinstance ( indx , int ) : <EOL> l_indices [ i ] = self . index ( indx ) <EOL> e = <NUM_LIT:1> <EOL> limits = [ ] <EOL> for i , limit in enumerate ( self . limits ) : <EOL> l = limit <EOL> if i in l_indices : <EOL> e = - e <EOL> l = ( limit [ <NUM_LIT:0> ] , limit [ <NUM_LIT:2> ] + <NUM_LIT:1> , limit [ <NUM_LIT:1> ] - <NUM_LIT:1> ) <EOL> limits . append ( l ) <EOL> return Sum ( e * self . function , * limits ) <EOL> def summation ( f , * symbols , ** kwargs ) : <EOL> r"""<STR_LIT>""" <EOL> return Sum ( f , * symbols , ** kwargs ) . doit ( deep = False ) <EOL> def telescopic_direct ( L , R , n , limits ) : <EOL> """<STR_LIT>""" <EOL> ( i , a , b ) = limits <EOL> s = <NUM_LIT:0> <EOL> for m in range ( n ) : <EOL> s += L . subs ( i , a + m ) + R . subs ( i , b - m ) <EOL> return s <EOL> def telescopic ( L , R , limits ) : <EOL> '''<STR_LIT>''' <EOL> ( i , a , b ) = limits <EOL> if L . is_Add or R . is_Add : <EOL> return None <EOL> k = Wild ( "<STR_LIT:k>" ) <EOL> sol = ( - R ) . match ( L . subs ( i , i + k ) ) <EOL> s = None <EOL> if sol and k in sol : <EOL> s = sol [ k ] <EOL> if not ( s . is_Integer and L . subs ( i , i + s ) == - R ) : <EOL> s = None <EOL> if s is None : <EOL> m = Dummy ( '<STR_LIT:m>' ) <EOL> try : <EOL> sol = solve ( L . subs ( i , i + m ) + R , m ) or [ ] <EOL> except NotImplementedError : <EOL> return None <EOL> sol = [ si for si in sol if si . is_Integer and <EOL> ( L . subs ( i , i + si ) + R ) . expand ( ) . is_zero ] <EOL> if len ( sol ) != <NUM_LIT:1> : <EOL> return None <EOL> s = sol [ <NUM_LIT:0> ] <EOL> if s < <NUM_LIT:0> : <EOL> return telescopic_direct ( R , L , abs ( s ) , ( i , a , b ) ) <EOL> elif s > <NUM_LIT:0> : <EOL> return telescopic_direct ( L , R , s , ( i , a , b ) ) <EOL> def eval_sum ( f , limits ) : <EOL> from sympy . concrete . delta import deltasummation , _has_simple_delta <EOL> from sympy . functions import KroneckerDelta <EOL> ( i , a , b ) = limits <EOL> if f is S . Zero : <EOL> return S . Zero <EOL> if i not in f . free_symbols : <EOL> return f * ( b - a + <NUM_LIT:1> ) <EOL> if a == b : <EOL> return f . subs ( i , a ) <EOL> if isinstance ( f , Piecewise ) : <EOL> if not any ( i in arg . args [ <NUM_LIT:1> ] . free_symbols for arg in f . args ) : <EOL> newargs = [ ] <EOL> for arg in f . args : <EOL> newexpr = eval_sum ( arg . expr , limits ) <EOL> if newexpr is None : <EOL> return None <EOL> newargs . append ( ( newexpr , arg . cond ) ) <EOL> return f . func ( * newargs ) <EOL> if f . has ( KroneckerDelta ) and _has_simple_delta ( f , limits [ <NUM_LIT:0> ] ) : <EOL> return deltasummation ( f , limits ) <EOL> dif = b - a <EOL> definite = dif . is_Integer <EOL> if definite and ( dif < <NUM_LIT:100> ) : <EOL> return eval_sum_direct ( f , ( i , a , b ) ) <EOL> if isinstance ( f , Piecewise ) : <EOL> return None <EOL> value = eval_sum_symbolic ( f . expand ( ) , ( i , a , b ) ) <EOL> if value is not None : <EOL> return value <EOL> if definite : <EOL> return eval_sum_direct ( f , ( i , a , b ) ) <EOL> def eval_sum_direct ( expr , limits ) : <EOL> from sympy . core import Add <EOL> ( i , a , b ) = limits <EOL> dif = b - a <EOL> return Add ( * [ expr . subs ( i , a + j ) for j in range ( dif + <NUM_LIT:1> ) ] ) <EOL> def eval_sum_symbolic ( f , limits ) : <EOL> from sympy . functions import harmonic , bernoulli <EOL> f_orig = f <EOL> ( i , a , b ) = limits <EOL> if not f . has ( i ) : <EOL> return f * ( b - a + <NUM_LIT:1> ) <EOL> if f . is_Mul : <EOL> L , R = f . as_two_terms ( ) <EOL> if not L . has ( i ) : <EOL> sR = eval_sum_symbolic ( R , ( i , a , b ) ) <EOL> if sR : <EOL> return L * sR <EOL> if not R . has ( i ) : <EOL> sL = eval_sum_symbolic ( L , ( i , a , b ) ) <EOL> if sL : <EOL> return R * sL <EOL> try : <EOL> f = apart ( f , i ) <EOL> except PolynomialError : <EOL> pass <EOL> if f . is_Add : <EOL> L , R = f . as_two_terms ( ) <EOL> lrsum = telescopic ( L , R , ( i , a , b ) ) <EOL> if lrsum : <EOL> return lrsum <EOL> lsum = eval_sum_symbolic ( L , ( i , a , b ) ) <EOL> rsum = eval_sum_symbolic ( R , ( i , a , b ) ) <EOL> if None not in ( lsum , rsum ) : <EOL> r = lsum + rsum <EOL> if not r is S . NaN : <EOL> return r <EOL> n = Wild ( '<STR_LIT:n>' ) <EOL> result = f . match ( i ** n ) <EOL> if result is not None : <EOL> n = result [ n ] <EOL> if n . is_Integer : <EOL> if n >= <NUM_LIT:0> : <EOL> if ( b is S . Infinity and not a is S . NegativeInfinity ) or ( a is S . NegativeInfinity and not b is S . Infinity ) : <EOL> return S . Infinity <EOL> return ( ( bernoulli ( n + <NUM_LIT:1> , b + <NUM_LIT:1> ) - bernoulli ( n + <NUM_LIT:1> , a ) ) / ( n + <NUM_LIT:1> ) ) . expand ( ) <EOL> elif a . is_Integer and a >= <NUM_LIT:1> : <EOL> if n == - <NUM_LIT:1> : <EOL> return harmonic ( b ) - harmonic ( a - <NUM_LIT:1> ) <EOL> else : <EOL> return harmonic ( b , abs ( n ) ) - harmonic ( a - <NUM_LIT:1> , abs ( n ) ) <EOL> if not ( a . has ( S . Infinity , S . NegativeInfinity ) or <EOL> b . has ( S . Infinity , S . NegativeInfinity ) ) : <EOL> c1 = Wild ( '<STR_LIT>' , exclude = [ i ] ) <EOL> c2 = Wild ( '<STR_LIT>' , exclude = [ i ] ) <EOL> c3 = Wild ( '<STR_LIT>' , exclude = [ i ] ) <EOL> e = f . match ( c1 ** ( c2 * i + c3 ) ) <EOL> if e is not None : <EOL> p = ( c1 ** c3 ) . subs ( e ) <EOL> q = ( c1 ** c2 ) . subs ( e ) <EOL> r = p * ( q ** a - q ** ( b + <NUM_LIT:1> ) ) / ( <NUM_LIT:1> - q ) <EOL> l = p * ( b - a + <NUM_LIT:1> ) <EOL> return Piecewise ( ( l , Eq ( q , S . One ) ) , ( r , True ) ) <EOL> r = gosper_sum ( f , ( i , a , b ) ) <EOL> if not r in ( None , S . NaN ) : <EOL> return r <EOL> return eval_sum_hyper ( f_orig , ( i , a , b ) ) <EOL> def _eval_sum_hyper ( f , i , a ) : <EOL> """<STR_LIT>""" <EOL> from sympy . functions import hyper <EOL> from sympy . simplify import hyperexpand , hypersimp , fraction , simplify <EOL> from sympy . polys . polytools import Poly , factor <EOL> if a != <NUM_LIT:0> : <EOL> return _eval_sum_hyper ( f . subs ( i , i + a ) , i , <NUM_LIT:0> ) <EOL> if f . subs ( i , <NUM_LIT:0> ) == <NUM_LIT:0> : <EOL> if simplify ( f . subs ( i , Dummy ( '<STR_LIT:i>' , integer = True , positive = True ) ) ) == <NUM_LIT:0> : <EOL> return S ( <NUM_LIT:0> ) , True <EOL> return _eval_sum_hyper ( f . subs ( i , i + <NUM_LIT:1> ) , i , <NUM_LIT:0> ) <EOL> hs = hypersimp ( f , i ) <EOL> if hs is None : <EOL> return None <EOL> numer , denom = fraction ( factor ( hs ) ) <EOL> top , topl = numer . as_coeff_mul ( i ) <EOL> bot , botl = denom . as_coeff_mul ( i ) <EOL> ab = [ top , bot ] <EOL> factors = [ topl , botl ] <EOL> params = [ [ ] , [ ] ] <EOL> for k in range ( <NUM_LIT:2> ) : <EOL> for fac in factors [ k ] : <EOL> mul = <NUM_LIT:1> <EOL> if fac . is_Pow : <EOL> mul = fac . exp <EOL> fac = fac . base <EOL> if not mul . is_Integer : <EOL> return None <EOL> p = Poly ( fac , i ) <EOL> if p . degree ( ) != <NUM_LIT:1> : <EOL> return None <EOL> m , n = p . all_coeffs ( ) <EOL> ab [ k ] *= m ** mul <EOL> params [ k ] += [ n / m ] * mul <EOL> ap = params [ <NUM_LIT:0> ] + [ <NUM_LIT:1> ] <EOL> bq = params [ <NUM_LIT:1> ] <EOL> x = ab [ <NUM_LIT:0> ] / ab [ <NUM_LIT:1> ] <EOL> h = hyper ( ap , bq , x ) <EOL> return f . subs ( i , <NUM_LIT:0> ) * hyperexpand ( h ) , h . convergence_statement <EOL> def eval_sum_hyper ( f , i_a_b ) : <EOL> from sympy . logic . boolalg import And <EOL> i , a , b = i_a_b <EOL> if ( b - a ) . is_Integer : <EOL> return None <EOL> old_sum = Sum ( f , ( i , a , b ) ) <EOL> if b != S . Infinity : <EOL> if a == S . NegativeInfinity : <EOL> res = _eval_sum_hyper ( f . subs ( i , - i ) , i , - b ) <EOL> if res is not None : <EOL> return Piecewise ( res , ( old_sum , True ) ) <EOL> else : <EOL> res1 = _eval_sum_hyper ( f , i , a ) <EOL> res2 = _eval_sum_hyper ( f , i , b + <NUM_LIT:1> ) <EOL> if res1 is None or res2 is None : <EOL> return None <EOL> ( res1 , cond1 ) , ( res2 , cond2 ) = res1 , res2 <EOL> cond = And ( cond1 , cond2 ) <EOL> if cond == False : <EOL> return None <EOL> return Piecewise ( ( res1 - res2 , cond ) , ( old_sum , True ) ) <EOL> if a == S . NegativeInfinity : <EOL> res1 = _eval_sum_hyper ( f . subs ( i , - i ) , i , <NUM_LIT:1> ) <EOL> res2 = _eval_sum_hyper ( f , i , <NUM_LIT:0> ) <EOL> if res1 is None or res2 is None : <EOL> return None <EOL> res1 , cond1 = res1 <EOL> res2 , cond2 = res2 <EOL> cond = And ( cond1 , cond2 ) <EOL> if cond == False : <EOL> return None <EOL> return Piecewise ( ( res1 + res2 , cond ) , ( old_sum , True ) ) <EOL> res = _eval_sum_hyper ( f , i , a ) <EOL> if res is not None : <EOL> r , c = res <EOL> if c == False : <EOL> if r . is_number : <EOL> f = f . subs ( i , Dummy ( '<STR_LIT:i>' , integer = True , positive = True ) + a ) <EOL> if f . is_positive or f . is_zero : <EOL> return S . Infinity <EOL> elif f . is_negative : <EOL> return S . NegativeInfinity <EOL> return None <EOL> return Piecewise ( res , ( old_sum , True ) ) </s>
