<s> """<STR_LIT>""" <EOL> from sympy . polys . domains import QQ , EX <EOL> from sympy . polys . rings import PolyElement , ring , sring <EOL> from sympy . polys . polyerrors import DomainError <EOL> from sympy . polys . monomials import ( monomial_min , monomial_mul , monomial_div , <EOL> monomial_ldiv ) <EOL> from mpmath . libmp . libintmath import ifac <EOL> from sympy . core import PoleError , Function , Expr <EOL> from sympy . core . numbers import Rational , igcd <EOL> from sympy . core . compatibility import as_int , range <EOL> from sympy . functions import sin , cos , tan , atan , exp , atanh , tanh , log , ceiling <EOL> from mpmath . libmp . libintmath import giant_steps <EOL> import math <EOL> def _invert_monoms ( p1 ) : <EOL> """<STR_LIT>""" <EOL> terms = list ( p1 . items ( ) ) <EOL> terms . sort ( ) <EOL> deg = p1 . degree ( ) <EOL> R = p1 . ring <EOL> p = R . zero <EOL> cv = p1 . listcoeffs ( ) <EOL> mv = p1 . listmonoms ( ) <EOL> for i in range ( len ( mv ) ) : <EOL> p [ ( deg - mv [ i ] [ <NUM_LIT:0> ] , ) ] = cv [ i ] <EOL> return p <EOL> def _giant_steps ( target ) : <EOL> """<STR_LIT>""" <EOL> res = giant_steps ( <NUM_LIT:2> , target ) <EOL> if res [ <NUM_LIT:0> ] != <NUM_LIT:2> : <EOL> res = [ <NUM_LIT:2> ] + res <EOL> return res <EOL> def rs_trunc ( p1 , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> p = R . zero <EOL> i = R . gens . index ( x ) <EOL> for exp1 in p1 : <EOL> if exp1 [ i ] >= prec : <EOL> continue <EOL> p [ exp1 ] = p1 [ exp1 ] <EOL> return p <EOL> def rs_is_puiseux ( p , x ) : <EOL> """<STR_LIT>""" <EOL> index = p . ring . gens . index ( x ) <EOL> for k in p : <EOL> if k [ index ] != int ( k [ index ] ) : <EOL> return True <EOL> if k [ index ] < <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' % x ) <EOL> return False <EOL> def rs_puiseux ( f , p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> index = p . ring . gens . index ( x ) <EOL> n = <NUM_LIT:1> <EOL> for k in p : <EOL> power = k [ index ] <EOL> if isinstance ( power , Rational ) : <EOL> num , den = power . as_numer_denom ( ) <EOL> n = int ( n * den // igcd ( n , den ) ) <EOL> elif power != int ( power ) : <EOL> num , den = power . numerator , power . denominator <EOL> n = int ( n * den // igcd ( n , den ) ) <EOL> if n != <NUM_LIT:1> : <EOL> p1 = pow_xin ( p , index , n ) <EOL> r = f ( p1 , x , prec * n ) <EOL> n1 = QQ ( <NUM_LIT:1> , n ) <EOL> if isinstance ( r , tuple ) : <EOL> r = tuple ( [ pow_xin ( rx , index , n1 ) for rx in r ] ) <EOL> else : <EOL> r = pow_xin ( r , index , n1 ) <EOL> else : <EOL> r = f ( p , x , prec ) <EOL> return r <EOL> def rs_puiseux2 ( f , p , q , x , prec ) : <EOL> """<STR_LIT>""" <EOL> index = p . ring . gens . index ( x ) <EOL> n = <NUM_LIT:1> <EOL> for k in p : <EOL> power = k [ index ] <EOL> if isinstance ( power , Rational ) : <EOL> num , den = power . as_numer_denom ( ) <EOL> n = n * den // igcd ( n , den ) <EOL> elif power != int ( power ) : <EOL> num , den = power . numerator , power . denominator <EOL> n = n * den // igcd ( n , den ) <EOL> if n != <NUM_LIT:1> : <EOL> p1 = pow_xin ( p , index , n ) <EOL> r = f ( p1 , q , x , prec * n ) <EOL> n1 = QQ ( <NUM_LIT:1> , n ) <EOL> r = pow_xin ( r , index , n1 ) <EOL> else : <EOL> r = f ( p , q , x , prec ) <EOL> return r <EOL> def rs_mul ( p1 , p2 , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> p = R . zero <EOL> if R . __class__ != p2 . ring . __class__ or R != p2 . ring : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> iv = R . gens . index ( x ) <EOL> if not isinstance ( p2 , PolyElement ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if R == p2 . ring : <EOL> get = p . get <EOL> items2 = list ( p2 . items ( ) ) <EOL> items2 . sort ( key = lambda e : e [ <NUM_LIT:0> ] [ iv ] ) <EOL> if R . ngens == <NUM_LIT:1> : <EOL> for exp1 , v1 in p1 . items ( ) : <EOL> for exp2 , v2 in items2 : <EOL> exp = exp1 [ <NUM_LIT:0> ] + exp2 [ <NUM_LIT:0> ] <EOL> if exp < prec : <EOL> exp = ( exp , ) <EOL> p [ exp ] = get ( exp , <NUM_LIT:0> ) + v1 * v2 <EOL> else : <EOL> break <EOL> else : <EOL> monomial_mul = R . monomial_mul <EOL> for exp1 , v1 in p1 . items ( ) : <EOL> for exp2 , v2 in items2 : <EOL> if exp1 [ iv ] + exp2 [ iv ] < prec : <EOL> exp = monomial_mul ( exp1 , exp2 ) <EOL> p [ exp ] = get ( exp , <NUM_LIT:0> ) + v1 * v2 <EOL> else : <EOL> break <EOL> p . strip_zero ( ) <EOL> return p <EOL> def rs_square ( p1 , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> p = R . zero <EOL> iv = R . gens . index ( x ) <EOL> get = p . get <EOL> items = list ( p1 . items ( ) ) <EOL> items . sort ( key = lambda e : e [ <NUM_LIT:0> ] [ iv ] ) <EOL> monomial_mul = R . monomial_mul <EOL> for i in range ( len ( items ) ) : <EOL> exp1 , v1 = items [ i ] <EOL> for j in range ( i ) : <EOL> exp2 , v2 = items [ j ] <EOL> if exp1 [ iv ] + exp2 [ iv ] < prec : <EOL> exp = monomial_mul ( exp1 , exp2 ) <EOL> p [ exp ] = get ( exp , <NUM_LIT:0> ) + v1 * v2 <EOL> else : <EOL> break <EOL> p = p . imul_num ( <NUM_LIT:2> ) <EOL> get = p . get <EOL> for expv , v in p1 . items ( ) : <EOL> if <NUM_LIT:2> * expv [ iv ] < prec : <EOL> e2 = monomial_mul ( expv , expv ) <EOL> p [ e2 ] = get ( e2 , <NUM_LIT:0> ) + v ** <NUM_LIT:2> <EOL> p . strip_zero ( ) <EOL> return p <EOL> def rs_pow ( p1 , n , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> p = R . zero <EOL> if isinstance ( n , Rational ) : <EOL> np = int ( n . p ) <EOL> nq = int ( n . q ) <EOL> if nq != <NUM_LIT:1> : <EOL> res = rs_nth_root ( p1 , nq , x , prec ) <EOL> if np != <NUM_LIT:1> : <EOL> res = rs_pow ( res , np , x , prec ) <EOL> else : <EOL> res = rs_pow ( p1 , np , x , prec ) <EOL> return res <EOL> n = as_int ( n ) <EOL> if n == <NUM_LIT:0> : <EOL> if p1 : <EOL> return R ( <NUM_LIT:1> ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if n < <NUM_LIT:0> : <EOL> p1 = rs_pow ( p1 , - n , x , prec ) <EOL> return rs_series_inversion ( p1 , x , prec ) <EOL> if n == <NUM_LIT:1> : <EOL> return rs_trunc ( p1 , x , prec ) <EOL> if n == <NUM_LIT:2> : <EOL> return rs_square ( p1 , x , prec ) <EOL> if n == <NUM_LIT:3> : <EOL> p2 = rs_square ( p1 , x , prec ) <EOL> return rs_mul ( p1 , p2 , x , prec ) <EOL> p = R ( <NUM_LIT:1> ) <EOL> while <NUM_LIT:1> : <EOL> if n & <NUM_LIT:1> : <EOL> p = rs_mul ( p1 , p , x , prec ) <EOL> n -= <NUM_LIT:1> <EOL> if not n : <EOL> break <EOL> p1 = rs_square ( p1 , x , prec ) <EOL> n = n // <NUM_LIT:2> <EOL> return p <EOL> def rs_subs ( p , rules , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> ngens = R . ngens <EOL> d = R ( <NUM_LIT:0> ) <EOL> for i in range ( ngens ) : <EOL> d [ ( i , <NUM_LIT:1> ) ] = R . gens [ i ] <EOL> for var in rules : <EOL> d [ ( R . index ( var ) , <NUM_LIT:1> ) ] = rules [ var ] <EOL> p1 = R ( <NUM_LIT:0> ) <EOL> p_keys = sorted ( p . keys ( ) ) <EOL> for expv in p_keys : <EOL> p2 = R ( <NUM_LIT:1> ) <EOL> for i in range ( ngens ) : <EOL> power = expv [ i ] <EOL> if power == <NUM_LIT:0> : <EOL> continue <EOL> if ( i , power ) not in d : <EOL> q , r = divmod ( power , <NUM_LIT:2> ) <EOL> if r == <NUM_LIT:0> and ( i , q ) in d : <EOL> d [ ( i , power ) ] = rs_square ( d [ ( i , q ) ] , x , prec ) <EOL> elif ( i , power - <NUM_LIT:1> ) in d : <EOL> d [ ( i , power ) ] = rs_mul ( d [ ( i , power - <NUM_LIT:1> ) ] , d [ ( i , <NUM_LIT:1> ) ] , <EOL> x , prec ) <EOL> else : <EOL> d [ ( i , power ) ] = rs_pow ( d [ ( i , <NUM_LIT:1> ) ] , power , x , prec ) <EOL> p2 = rs_mul ( p2 , d [ ( i , power ) ] , x , prec ) <EOL> p1 += p2 * p [ expv ] <EOL> return p1 <EOL> def _has_constant_term ( p , x ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> iv = R . gens . index ( x ) <EOL> zm = R . zero_monom <EOL> a = [ <NUM_LIT:0> ] * R . ngens <EOL> a [ iv ] = <NUM_LIT:1> <EOL> miv = tuple ( a ) <EOL> for expv in p : <EOL> if monomial_min ( expv , miv ) == zm : <EOL> return True <EOL> return False <EOL> def _get_constant_term ( p , x ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> zm = R . zero_monom <EOL> i = R . gens . index ( x ) <EOL> zm = R . zero_monom <EOL> a = [ <NUM_LIT:0> ] * R . ngens <EOL> a [ i ] = <NUM_LIT:1> <EOL> miv = tuple ( a ) <EOL> c = <NUM_LIT:0> <EOL> for expv in p : <EOL> if monomial_min ( expv , miv ) == zm : <EOL> c += R ( { expv : p [ expv ] } ) <EOL> return c <EOL> def _check_series_var ( p , x , name ) : <EOL> index = p . ring . gens . index ( x ) <EOL> m = min ( p , key = lambda k : k [ index ] ) [ index ] <EOL> if m < <NUM_LIT:0> : <EOL> raise PoleError ( "<STR_LIT>" <EOL> "<STR_LIT>" % name ) <EOL> return index , m <EOL> def _series_inversion1 ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( _series_inversion1 , p , x , prec ) <EOL> R = p . ring <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if prec == int ( prec ) : <EOL> prec = int ( prec ) <EOL> if zm not in p : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if _has_constant_term ( p - c , x ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> one = R ( <NUM_LIT:1> ) <EOL> if R . domain is EX : <EOL> one = <NUM_LIT:1> <EOL> if c != one : <EOL> p1 = R ( <NUM_LIT:1> ) / c <EOL> else : <EOL> p1 = R ( <NUM_LIT:1> ) <EOL> for precx in _giant_steps ( prec ) : <EOL> t = <NUM_LIT:1> - rs_mul ( p1 , p , x , precx ) <EOL> p1 = p1 + rs_mul ( p1 , t , x , precx ) <EOL> return p1 <EOL> def rs_series_inversion ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> if p == R . zero : <EOL> raise ZeroDivisionError <EOL> zm = R . zero_monom <EOL> index = R . gens . index ( x ) <EOL> m = min ( p , key = lambda k : k [ index ] ) [ index ] <EOL> if m : <EOL> p = mul_xin ( p , index , - m ) <EOL> prec = prec + m <EOL> if zm not in p : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> if _has_constant_term ( p - p [ zm ] , x ) : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> r = _series_inversion1 ( p , x , prec ) <EOL> if m != <NUM_LIT:0> : <EOL> r = mul_xin ( r , index , - m ) <EOL> return r <EOL> def _coefficient_t ( p , t ) : <EOL> """<STR_LIT>""" <EOL> i , j = t <EOL> R = p . ring <EOL> expv1 = [ <NUM_LIT:0> ] * R . ngens <EOL> expv1 [ i ] = j <EOL> expv1 = tuple ( expv1 ) <EOL> p1 = R ( <NUM_LIT:0> ) <EOL> for expv in p : <EOL> if expv [ i ] == j : <EOL> p1 [ monomial_div ( expv , expv1 ) ] = p [ expv ] <EOL> return p1 <EOL> def rs_series_reversion ( p , x , n , y ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> raise NotImplementedError <EOL> R = p . ring <EOL> nx = R . gens . index ( x ) <EOL> y = R ( y ) <EOL> ny = R . gens . index ( y ) <EOL> if _has_constant_term ( p , x ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> a = _coefficient_t ( p , ( nx , <NUM_LIT:1> ) ) <EOL> zm = R . zero_monom <EOL> assert zm in a and len ( a ) == <NUM_LIT:1> <EOL> a = a [ zm ] <EOL> r = y / a <EOL> for i in range ( <NUM_LIT:2> , n ) : <EOL> sp = rs_subs ( p , { x : r } , y , i + <NUM_LIT:1> ) <EOL> sp = _coefficient_t ( sp , ( ny , i ) ) * y ** i <EOL> r -= sp / a <EOL> return r <EOL> def rs_series_from_list ( p , c , x , prec , concur = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> n = len ( c ) <EOL> if not concur : <EOL> q = R ( <NUM_LIT:1> ) <EOL> s = c [ <NUM_LIT:0> ] * q <EOL> for i in range ( <NUM_LIT:1> , n ) : <EOL> q = rs_mul ( q , p , x , prec ) <EOL> s += c [ i ] * q <EOL> return s <EOL> J = int ( math . sqrt ( n ) + <NUM_LIT:1> ) <EOL> K , r = divmod ( n , J ) <EOL> if r : <EOL> K += <NUM_LIT:1> <EOL> ax = [ R ( <NUM_LIT:1> ) ] <EOL> b = <NUM_LIT:1> <EOL> q = R ( <NUM_LIT:1> ) <EOL> if len ( p ) < <NUM_LIT:20> : <EOL> for i in range ( <NUM_LIT:1> , J ) : <EOL> q = rs_mul ( q , p , x , prec ) <EOL> ax . append ( q ) <EOL> else : <EOL> for i in range ( <NUM_LIT:1> , J ) : <EOL> if i % <NUM_LIT:2> == <NUM_LIT:0> : <EOL> q = rs_square ( ax [ i // <NUM_LIT:2> ] , x , prec ) <EOL> else : <EOL> q = rs_mul ( q , p , x , prec ) <EOL> ax . append ( q ) <EOL> pj = rs_mul ( ax [ - <NUM_LIT:1> ] , p , x , prec ) <EOL> b = R ( <NUM_LIT:1> ) <EOL> s = R ( <NUM_LIT:0> ) <EOL> for k in range ( K - <NUM_LIT:1> ) : <EOL> r = J * k <EOL> s1 = c [ r ] <EOL> for j in range ( <NUM_LIT:1> , J ) : <EOL> s1 += c [ r + j ] * ax [ j ] <EOL> s1 = rs_mul ( s1 , b , x , prec ) <EOL> s += s1 <EOL> b = rs_mul ( b , pj , x , prec ) <EOL> if not b : <EOL> break <EOL> k = K - <NUM_LIT:1> <EOL> r = J * k <EOL> if r < n : <EOL> s1 = c [ r ] * R ( <NUM_LIT:1> ) <EOL> for j in range ( <NUM_LIT:1> , J ) : <EOL> if r + j >= n : <EOL> break <EOL> s1 += c [ r + j ] * ax [ j ] <EOL> s1 = rs_mul ( s1 , b , x , prec ) <EOL> s += s1 <EOL> return s <EOL> def rs_diff ( p , x ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> n = R . gens . index ( x ) <EOL> p1 = R . zero <EOL> mn = [ <NUM_LIT:0> ] * R . ngens <EOL> mn [ n ] = <NUM_LIT:1> <EOL> mn = tuple ( mn ) <EOL> for expv in p : <EOL> if expv [ n ] : <EOL> e = monomial_ldiv ( expv , mn ) <EOL> p1 [ e ] = p [ expv ] * expv [ n ] <EOL> return p1 <EOL> def rs_integrate ( p , x ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> p1 = R . zero <EOL> n = R . gens . index ( x ) <EOL> mn = [ <NUM_LIT:0> ] * R . ngens <EOL> mn [ n ] = <NUM_LIT:1> <EOL> mn = tuple ( mn ) <EOL> for expv in p : <EOL> e = monomial_mul ( expv , mn ) <EOL> p1 [ e ] = p [ expv ] / ( expv [ n ] + <NUM_LIT:1> ) <EOL> return p1 <EOL> def rs_fun ( p , f , * args ) : <EOL> """<STR_LIT>""" <EOL> _R = p . ring <EOL> R1 , _x = ring ( '<STR_LIT>' , _R . domain ) <EOL> h = int ( args [ - <NUM_LIT:1> ] ) <EOL> args1 = args [ : - <NUM_LIT:2> ] + ( _x , h ) <EOL> zm = _R . zero_monom <EOL> if zm in p : <EOL> x1 = _x + p [ zm ] <EOL> p1 = p - p [ zm ] <EOL> else : <EOL> x1 = _x <EOL> p1 = p <EOL> if isinstance ( f , str ) : <EOL> q = getattr ( x1 , f ) ( * args1 ) <EOL> else : <EOL> q = f ( x1 , * args1 ) <EOL> a = sorted ( q . items ( ) ) <EOL> c = [ <NUM_LIT:0> ] * h <EOL> for x in a : <EOL> c [ x [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ] = x [ <NUM_LIT:1> ] <EOL> p1 = rs_series_from_list ( p1 , c , args [ - <NUM_LIT:2> ] , args [ - <NUM_LIT:1> ] ) <EOL> return p1 <EOL> def mul_xin ( p , i , n ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> q = R ( <NUM_LIT:0> ) <EOL> for k , v in p . items ( ) : <EOL> k1 = list ( k ) <EOL> k1 [ i ] += n <EOL> q [ tuple ( k1 ) ] = v <EOL> return q <EOL> def pow_xin ( p , i , n ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> q = R ( <NUM_LIT:0> ) <EOL> for k , v in p . items ( ) : <EOL> k1 = list ( k ) <EOL> k1 [ i ] *= n <EOL> q [ tuple ( k1 ) ] = v <EOL> return q <EOL> def _nth_root1 ( p , n , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux2 ( _nth_root1 , p , n , x , prec ) <EOL> R = p . ring <EOL> zm = R . zero_monom <EOL> if zm not in p : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> n = as_int ( n ) <EOL> assert p [ zm ] == <NUM_LIT:1> <EOL> p1 = R ( <NUM_LIT:1> ) <EOL> if p == <NUM_LIT:1> : <EOL> return p <EOL> if n == <NUM_LIT:0> : <EOL> return R ( <NUM_LIT:1> ) <EOL> if n == <NUM_LIT:1> : <EOL> return p <EOL> if n < <NUM_LIT:0> : <EOL> n = - n <EOL> sign = <NUM_LIT:1> <EOL> else : <EOL> sign = <NUM_LIT:0> <EOL> for precx in _giant_steps ( prec ) : <EOL> tmp = rs_pow ( p1 , n + <NUM_LIT:1> , x , precx ) <EOL> tmp = rs_mul ( tmp , p , x , precx ) <EOL> p1 += p1 / n - tmp / n <EOL> if sign : <EOL> return p1 <EOL> else : <EOL> return _series_inversion1 ( p1 , x , prec ) <EOL> def rs_nth_root ( p , n , x , prec ) : <EOL> """<STR_LIT>""" <EOL> p0 = p <EOL> n0 = n <EOL> if n == <NUM_LIT:0> : <EOL> if p == <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> else : <EOL> return p . ring ( <NUM_LIT:1> ) <EOL> if n == <NUM_LIT:1> : <EOL> return rs_trunc ( p , x , prec ) <EOL> R = p . ring <EOL> zm = R . zero_monom <EOL> index = R . gens . index ( x ) <EOL> m = min ( p , key = lambda k : k [ index ] ) [ index ] <EOL> p = mul_xin ( p , index , - m ) <EOL> prec -= m <EOL> if _has_constant_term ( p - <NUM_LIT:1> , x ) : <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = c_expr ** QQ ( <NUM_LIT:1> , n ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( c_expr ** ( QQ ( <NUM_LIT:1> , n ) ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> try : <EOL> const = R ( c ** Rational ( <NUM_LIT:1> , n ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> res = rs_nth_root ( p / c , n , x , prec ) * const <EOL> else : <EOL> res = _nth_root1 ( p , n , x , prec ) <EOL> if m : <EOL> m = QQ ( m , n ) <EOL> res = mul_xin ( res , index , m ) <EOL> return res <EOL> def rs_log ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_log , p , x , prec ) <EOL> R = p . ring <EOL> if p == <NUM_LIT:1> : <EOL> return R . zero <EOL> if _has_constant_term ( p , x ) : <EOL> const = <NUM_LIT:0> <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if c == <NUM_LIT:1> : <EOL> pass <EOL> else : <EOL> c_expr = c . as_expr ( ) <EOL> if R . domain is EX : <EOL> const = log ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> const = R ( log ( c_expr ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> try : <EOL> const = R ( log ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> dlog = p . diff ( x ) <EOL> dlog = rs_mul ( dlog , _series_inversion1 ( p , x , prec ) , x , prec - <NUM_LIT:1> ) <EOL> return rs_integrate ( dlog , x ) + const <EOL> else : <EOL> raise NotImplementedError <EOL> def rs_LambertW ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_LambertW , p , x , prec ) <EOL> R = p . ring <EOL> p1 = R ( <NUM_LIT:0> ) <EOL> if _has_constant_term ( p , x ) : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if x in R . gens : <EOL> for precx in _giant_steps ( prec ) : <EOL> e = rs_exp ( p1 , x , precx ) <EOL> p2 = rs_mul ( e , p1 , x , precx ) - p <EOL> p3 = rs_mul ( e , p1 + <NUM_LIT:1> , x , precx ) <EOL> p3 = rs_series_inversion ( p3 , x , precx ) <EOL> tmp = rs_mul ( p2 , p3 , x , precx ) <EOL> p1 -= tmp <EOL> return p1 <EOL> else : <EOL> raise NotImplementedError <EOL> def _exp1 ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> p1 = R ( <NUM_LIT:1> ) <EOL> for precx in _giant_steps ( prec ) : <EOL> pt = p - rs_log ( p1 , x , precx ) <EOL> tmp = rs_mul ( pt , p1 , x , precx ) <EOL> p1 += tmp <EOL> return p1 <EOL> def rs_exp ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_exp , p , x , prec ) <EOL> R = p . ring <EOL> c = _get_constant_term ( p , x ) <EOL> if c : <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = exp ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( exp ( c_expr ) ) <EOL> except ValueError : <EOL> R = R . add_gens ( [ exp ( c_expr ) ] ) <EOL> p = p . set_ring ( R ) <EOL> x = x . set_ring ( R ) <EOL> c = c . set_ring ( R ) <EOL> const = R ( exp ( c_expr ) ) <EOL> else : <EOL> try : <EOL> const = R ( exp ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> p1 = p - c <EOL> return const * rs_exp ( p1 , x , prec ) <EOL> if len ( p ) > <NUM_LIT:20> : <EOL> return _exp1 ( p , x , prec ) <EOL> one = R ( <NUM_LIT:1> ) <EOL> n = <NUM_LIT:1> <EOL> k = <NUM_LIT:1> <EOL> c = [ ] <EOL> for k in range ( prec ) : <EOL> c . append ( one / n ) <EOL> k += <NUM_LIT:1> <EOL> n *= k <EOL> r = rs_series_from_list ( p , c , x , prec ) <EOL> return r <EOL> def _atan ( p , iv , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> mo = R ( - <NUM_LIT:1> ) <EOL> c = [ - mo ] <EOL> p2 = rs_square ( p , iv , prec ) <EOL> for k in range ( <NUM_LIT:1> , prec ) : <EOL> c . append ( mo ** k / ( <NUM_LIT:2> * k + <NUM_LIT:1> ) ) <EOL> s = rs_series_from_list ( p2 , c , iv , prec ) <EOL> s = rs_mul ( s , p , iv , prec ) <EOL> return s <EOL> def rs_atan ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_atan , p , x , prec ) <EOL> R = p . ring <EOL> const = <NUM_LIT:0> <EOL> if _has_constant_term ( p , x ) : <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = atan ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( atan ( c_expr ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> try : <EOL> const = R ( atan ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> dp = p . diff ( x ) <EOL> p1 = rs_square ( p , x , prec ) + R ( <NUM_LIT:1> ) <EOL> p1 = rs_series_inversion ( p1 , x , prec - <NUM_LIT:1> ) <EOL> p1 = rs_mul ( dp , p1 , x , prec - <NUM_LIT:1> ) <EOL> return rs_integrate ( p1 , x ) + const <EOL> def rs_asin ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_asin , p , x , prec ) <EOL> if _has_constant_term ( p , x ) : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> R = p . ring <EOL> if x in R . gens : <EOL> if len ( p ) > <NUM_LIT:20> : <EOL> dp = rs_diff ( p , x ) <EOL> p1 = <NUM_LIT:1> - rs_square ( p , x , prec - <NUM_LIT:1> ) <EOL> p1 = rs_nth_root ( p1 , - <NUM_LIT:2> , x , prec - <NUM_LIT:1> ) <EOL> p1 = rs_mul ( dp , p1 , x , prec - <NUM_LIT:1> ) <EOL> return rs_integrate ( p1 , x ) <EOL> one = R ( <NUM_LIT:1> ) <EOL> c = [ <NUM_LIT:0> , one , <NUM_LIT:0> ] <EOL> for k in range ( <NUM_LIT:3> , prec , <NUM_LIT:2> ) : <EOL> c . append ( ( k - <NUM_LIT:2> ) ** <NUM_LIT:2> * c [ - <NUM_LIT:2> ] / ( k * ( k - <NUM_LIT:1> ) ) ) <EOL> c . append ( <NUM_LIT:0> ) <EOL> return rs_series_from_list ( p , c , x , prec ) <EOL> else : <EOL> raise NotImplementedError <EOL> def _tan1 ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> p1 = R ( <NUM_LIT:0> ) <EOL> for precx in _giant_steps ( prec ) : <EOL> tmp = p - rs_atan ( p1 , x , precx ) <EOL> tmp = rs_mul ( tmp , <NUM_LIT:1> + rs_square ( p1 , x , precx ) , x , precx ) <EOL> p1 += tmp <EOL> return p1 <EOL> def rs_tan ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> r = rs_puiseux ( rs_tan , p , x , prec ) <EOL> return r <EOL> R = p . ring <EOL> const = <NUM_LIT:0> <EOL> c = _get_constant_term ( p , x ) <EOL> if c : <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = tan ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( tan ( c_expr ) ) <EOL> except ValueError : <EOL> R = R . add_gens ( [ tan ( c_expr , ) ] ) <EOL> p = p . set_ring ( R ) <EOL> x = x . set_ring ( R ) <EOL> c = c . set_ring ( R ) <EOL> const = R ( tan ( c_expr ) ) <EOL> else : <EOL> try : <EOL> const = R ( tan ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> p1 = p - c <EOL> t2 = rs_tan ( p1 , x , prec ) <EOL> t = rs_series_inversion ( <NUM_LIT:1> - const * t2 , x , prec ) <EOL> return rs_mul ( const + t2 , t , x , prec ) <EOL> if R . ngens == <NUM_LIT:1> : <EOL> return _tan1 ( p , x , prec ) <EOL> else : <EOL> return rs_fun ( p , rs_tan , x , prec ) <EOL> def rs_cot ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> r = rs_puiseux ( rs_cot , p , x , prec ) <EOL> return r <EOL> i , m = _check_series_var ( p , x , '<STR_LIT>' ) <EOL> prec1 = prec + <NUM_LIT:2> * m <EOL> c , s = rs_cos_sin ( p , x , prec1 ) <EOL> s = mul_xin ( s , i , - m ) <EOL> s = rs_series_inversion ( s , x , prec1 ) <EOL> res = rs_mul ( c , s , x , prec1 ) <EOL> res = mul_xin ( res , i , - m ) <EOL> res = rs_trunc ( res , x , prec ) <EOL> return res <EOL> def rs_sin ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_sin , p , x , prec ) <EOL> R = x . ring <EOL> if not p : <EOL> return R ( <NUM_LIT:0> ) <EOL> c = _get_constant_term ( p , x ) <EOL> if c : <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> t1 , t2 = sin ( c_expr ) , cos ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> t1 , t2 = R ( sin ( c_expr ) ) , R ( cos ( c_expr ) ) <EOL> except ValueError : <EOL> R = R . add_gens ( [ sin ( c_expr ) , cos ( c_expr ) ] ) <EOL> p = p . set_ring ( R ) <EOL> x = x . set_ring ( R ) <EOL> c = c . set_ring ( R ) <EOL> t1 , t2 = R ( sin ( c_expr ) ) , R ( cos ( c_expr ) ) <EOL> else : <EOL> try : <EOL> t1 , t2 = R ( sin ( c ) ) , R ( cos ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> p1 = p - c <EOL> return rs_sin ( p1 , x , prec ) * t2 + rs_cos ( p1 , x , prec ) * t1 <EOL> if len ( p ) > <NUM_LIT:20> and R . ngens == <NUM_LIT:1> : <EOL> t = rs_tan ( p / <NUM_LIT:2> , x , prec ) <EOL> t2 = rs_square ( t , x , prec ) <EOL> p1 = rs_series_inversion ( <NUM_LIT:1> + t2 , x , prec ) <EOL> return rs_mul ( p1 , <NUM_LIT:2> * t , x , prec ) <EOL> one = R ( <NUM_LIT:1> ) <EOL> n = <NUM_LIT:1> <EOL> c = [ <NUM_LIT:0> ] <EOL> for k in range ( <NUM_LIT:2> , prec + <NUM_LIT:2> , <NUM_LIT:2> ) : <EOL> c . append ( one / n ) <EOL> c . append ( <NUM_LIT:0> ) <EOL> n *= - k * ( k + <NUM_LIT:1> ) <EOL> return rs_series_from_list ( p , c , x , prec ) <EOL> def rs_cos ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_cos , p , x , prec ) <EOL> R = p . ring <EOL> c = _get_constant_term ( p , x ) <EOL> if c : <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> t1 , t2 = sin ( c_expr ) , cos ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> t1 , t2 = R ( sin ( c_expr ) ) , R ( cos ( c_expr ) ) <EOL> except ValueError : <EOL> R = R . add_gens ( [ sin ( c_expr ) , cos ( c_expr ) ] ) <EOL> p = p . set_ring ( R ) <EOL> x = x . set_ring ( R ) <EOL> c = c . set_ring ( R ) <EOL> else : <EOL> try : <EOL> t1 , t2 = R ( sin ( c ) ) , R ( cos ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> p1 = p - c <EOL> p_cos = rs_cos ( p1 , x , prec ) <EOL> p_sin = rs_sin ( p1 , x , prec ) <EOL> R = R . compose ( p_cos . ring ) . compose ( p_sin . ring ) <EOL> p_cos . set_ring ( R ) <EOL> p_sin . set_ring ( R ) <EOL> t1 , t2 = R ( sin ( c_expr ) ) , R ( cos ( c_expr ) ) <EOL> return p_cos * t2 - p_sin * t1 <EOL> if len ( p ) > <NUM_LIT:20> and R . ngens == <NUM_LIT:1> : <EOL> t = rs_tan ( p / <NUM_LIT:2> , x , prec ) <EOL> t2 = rs_square ( t , x , prec ) <EOL> p1 = rs_series_inversion ( <NUM_LIT:1> + t2 , x , prec ) <EOL> return rs_mul ( p1 , <NUM_LIT:1> - t2 , x , prec ) <EOL> one = R ( <NUM_LIT:1> ) <EOL> n = <NUM_LIT:1> <EOL> c = [ ] <EOL> for k in range ( <NUM_LIT:2> , prec + <NUM_LIT:2> , <NUM_LIT:2> ) : <EOL> c . append ( one / n ) <EOL> c . append ( <NUM_LIT:0> ) <EOL> n *= - k * ( k - <NUM_LIT:1> ) <EOL> return rs_series_from_list ( p , c , x , prec ) <EOL> def rs_cos_sin ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_cos_sin , p , x , prec ) <EOL> t = rs_tan ( p / <NUM_LIT:2> , x , prec ) <EOL> t2 = rs_square ( t , x , prec ) <EOL> p1 = rs_series_inversion ( <NUM_LIT:1> + t2 , x , prec ) <EOL> return ( rs_mul ( p1 , <NUM_LIT:1> - t2 , x , prec ) , rs_mul ( p1 , <NUM_LIT:2> * t , x , prec ) ) <EOL> def _atanh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> one = R ( <NUM_LIT:1> ) <EOL> c = [ one ] <EOL> p2 = rs_square ( p , x , prec ) <EOL> for k in range ( <NUM_LIT:1> , prec ) : <EOL> c . append ( one / ( <NUM_LIT:2> * k + <NUM_LIT:1> ) ) <EOL> s = rs_series_from_list ( p2 , c , x , prec ) <EOL> s = rs_mul ( s , p , x , prec ) <EOL> return s <EOL> def rs_atanh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_atanh , p , x , prec ) <EOL> R = p . ring <EOL> const = <NUM_LIT:0> <EOL> if _has_constant_term ( p , x ) : <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = atanh ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( atanh ( c_expr ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> try : <EOL> const = R ( atanh ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> dp = rs_diff ( p , x ) <EOL> p1 = - rs_square ( p , x , prec ) + <NUM_LIT:1> <EOL> p1 = rs_series_inversion ( p1 , x , prec - <NUM_LIT:1> ) <EOL> p1 = rs_mul ( dp , p1 , x , prec - <NUM_LIT:1> ) <EOL> return rs_integrate ( p1 , x ) + const <EOL> def rs_sinh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_sinh , p , x , prec ) <EOL> t = rs_exp ( p , x , prec ) <EOL> t1 = rs_series_inversion ( t , x , prec ) <EOL> return ( t - t1 ) / <NUM_LIT:2> <EOL> def rs_cosh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_cosh , p , x , prec ) <EOL> t = rs_exp ( p , x , prec ) <EOL> t1 = rs_series_inversion ( t , x , prec ) <EOL> return ( t + t1 ) / <NUM_LIT:2> <EOL> def _tanh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> R = p . ring <EOL> p1 = R ( <NUM_LIT:0> ) <EOL> for precx in _giant_steps ( prec ) : <EOL> tmp = p - rs_atanh ( p1 , x , precx ) <EOL> tmp = rs_mul ( tmp , <NUM_LIT:1> - rs_square ( p1 , x , prec ) , x , precx ) <EOL> p1 += tmp <EOL> return p1 <EOL> def rs_tanh ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> if rs_is_puiseux ( p , x ) : <EOL> return rs_puiseux ( rs_tanh , p , x , prec ) <EOL> R = p . ring <EOL> const = <NUM_LIT:0> <EOL> if _has_constant_term ( p , x ) : <EOL> zm = R . zero_monom <EOL> c = p [ zm ] <EOL> if R . domain is EX : <EOL> c_expr = c . as_expr ( ) <EOL> const = tanh ( c_expr ) <EOL> elif isinstance ( c , PolyElement ) : <EOL> try : <EOL> c_expr = c . as_expr ( ) <EOL> const = R ( tanh ( c_expr ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> try : <EOL> const = R ( tanh ( c ) ) <EOL> except ValueError : <EOL> raise DomainError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> p1 = p - c <EOL> t1 = rs_tanh ( p1 , x , prec ) <EOL> t = rs_series_inversion ( <NUM_LIT:1> + const * t1 , x , prec ) <EOL> return rs_mul ( const + t1 , t , x , prec ) <EOL> if R . ngens == <NUM_LIT:1> : <EOL> return _tanh ( p , x , prec ) <EOL> else : <EOL> return rs_fun ( p , _tanh , x , prec ) <EOL> def rs_newton ( p , x , prec ) : <EOL> """<STR_LIT>""" <EOL> deg = p . degree ( ) <EOL> p1 = _invert_monoms ( p ) <EOL> p2 = rs_series_inversion ( p1 , x , prec ) <EOL> p3 = rs_mul ( p1 . diff ( x ) , p2 , x , prec ) <EOL> res = deg - p3 * x <EOL> return res <EOL> def rs_hadamard_exp ( p1 , inverse = False ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> if R . domain != QQ : <EOL> raise NotImplementedError <EOL> p = R . zero <EOL> if not inverse : <EOL> for exp1 , v1 in p1 . items ( ) : <EOL> p [ exp1 ] = v1 / int ( ifac ( exp1 [ <NUM_LIT:0> ] ) ) <EOL> else : <EOL> for exp1 , v1 in p1 . items ( ) : <EOL> p [ exp1 ] = v1 * int ( ifac ( exp1 [ <NUM_LIT:0> ] ) ) <EOL> return p <EOL> def rs_compose_add ( p1 , p2 ) : <EOL> """<STR_LIT>""" <EOL> R = p1 . ring <EOL> x = R . gens [ <NUM_LIT:0> ] <EOL> prec = p1 . degree ( ) * p2 . degree ( ) + <NUM_LIT:1> <EOL> np1 = rs_newton ( p1 , x , prec ) <EOL> np1e = rs_hadamard_exp ( np1 ) <EOL> np2 = rs_newton ( p2 , x , prec ) <EOL> np2e = rs_hadamard_exp ( np2 ) <EOL> np3e = rs_mul ( np1e , np2e , x , prec ) <EOL> np3 = rs_hadamard_exp ( np3e , True ) <EOL> np3a = ( np3 [ ( <NUM_LIT:0> , ) ] - np3 ) / x <EOL> q = rs_integrate ( np3a , x ) <EOL> q = rs_exp ( q , x , prec ) <EOL> q = _invert_monoms ( q ) <EOL> q = q . primitive ( ) [ <NUM_LIT:1> ] <EOL> dp = p1 . degree ( ) * p2 . degree ( ) - q . degree ( ) <EOL> if dp : <EOL> q = q * x ** dp <EOL> return q <EOL> _convert_func = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def rs_min_pow ( expr , series_rs , a ) : <EOL> """<STR_LIT>""" <EOL> series = <NUM_LIT:0> <EOL> n = <NUM_LIT:2> <EOL> while series == <NUM_LIT:0> : <EOL> series = _rs_series ( expr , series_rs , a , n ) <EOL> n *= <NUM_LIT:2> <EOL> R = series . ring <EOL> a = R ( a ) <EOL> i = R . gens . index ( a ) <EOL> return min ( series , key = lambda t : t [ i ] ) [ i ] <EOL> def _rs_series ( expr , series_rs , a , prec ) : <EOL> args = expr . args <EOL> R = series_rs . ring <EOL> if not any ( arg . has ( Function ) for arg in args ) and not expr . is_Function : <EOL> return series_rs <EOL> if not expr . has ( a ) : <EOL> return series_rs <EOL> elif expr . is_Function : <EOL> arg = args [ <NUM_LIT:0> ] <EOL> if len ( args ) > <NUM_LIT:1> : <EOL> raise NotImplementedError <EOL> R1 , series = sring ( arg , domain = QQ , expand = False , series = True ) <EOL> series_inner = _rs_series ( arg , series , a , prec ) <EOL> R = R . compose ( R1 ) . compose ( series_inner . ring ) <EOL> series_inner = series_inner . set_ring ( R ) <EOL> series = eval ( _convert_func [ str ( expr . func ) ] ) ( series_inner , <EOL> R ( a ) , prec ) <EOL> return series <EOL> elif expr . is_Mul : <EOL> n = len ( args ) <EOL> for arg in args : <EOL> if not arg . is_Number : <EOL> R1 , _ = sring ( arg , expand = False , series = True ) <EOL> R = R . compose ( R1 ) <EOL> min_pows = list ( map ( rs_min_pow , args , [ R ( arg ) for arg in args ] , <EOL> [ a ] * len ( args ) ) ) <EOL> sum_pows = sum ( min_pows ) <EOL> series = R ( <NUM_LIT:1> ) <EOL> for i in range ( n ) : <EOL> _series = _rs_series ( args [ i ] , R ( args [ i ] ) , a , prec - sum_pows + <EOL> min_pows [ i ] ) <EOL> R = R . compose ( _series . ring ) <EOL> _series = _series . set_ring ( R ) <EOL> series = series . set_ring ( R ) <EOL> series *= _series <EOL> series = rs_trunc ( series , R ( a ) , prec ) <EOL> return series <EOL> elif expr . is_Add : <EOL> n = len ( args ) <EOL> series = R ( <NUM_LIT:0> ) <EOL> for i in range ( n ) : <EOL> _series = _rs_series ( args [ i ] , R ( args [ i ] ) , a , prec ) <EOL> R = R . compose ( _series . ring ) <EOL> _series = _series . set_ring ( R ) <EOL> series = series . set_ring ( R ) <EOL> series += _series <EOL> return series <EOL> elif expr . is_Pow : <EOL> R1 , _ = sring ( expr . base , domain = QQ , expand = False , series = True ) <EOL> R = R . compose ( R1 ) <EOL> series_inner = _rs_series ( expr . base , R ( expr . base ) , a , prec ) <EOL> return rs_pow ( series_inner , expr . exp , series_inner . ring ( a ) , prec ) <EOL> elif isinstance ( expr , Expr ) and expr . is_constant ( ) : <EOL> return sring ( expr , domain = QQ , expand = False , series = True ) [ <NUM_LIT:1> ] <EOL> else : <EOL> raise NotImplementedError <EOL> def rs_series ( expr , a , prec ) : <EOL> """<STR_LIT>""" <EOL> R , series = sring ( expr , domain = QQ , expand = False , series = True ) <EOL> if a not in R . symbols : <EOL> R = R . add_gens ( [ a , ] ) <EOL> series = series . set_ring ( R ) <EOL> series = _rs_series ( expr , series , a , prec ) <EOL> R = series . ring <EOL> gen = R ( a ) <EOL> prec_got = series . degree ( gen ) + <NUM_LIT:1> <EOL> if prec_got >= prec : <EOL> return rs_trunc ( series , gen , prec ) <EOL> else : <EOL> for more in range ( <NUM_LIT:1> , <NUM_LIT:9> ) : <EOL> p1 = _rs_series ( expr , series , a , prec = prec + more ) <EOL> gen = gen . set_ring ( p1 . ring ) <EOL> new_prec = p1 . degree ( gen ) + <NUM_LIT:1> <EOL> if new_prec != prec_got : <EOL> prec_do = ceiling ( prec + ( prec - prec_got ) * more / ( new_prec - <EOL> prec_got ) ) <EOL> p1 = _rs_series ( expr , series , a , prec = prec_do ) <EOL> while p1 . degree ( gen ) + <NUM_LIT:1> < prec : <EOL> p1 = _rs_series ( expr , series , a , prec = prec_do ) <EOL> gen = gen . set_ring ( p1 . ring ) <EOL> prec_do *= <NUM_LIT:2> <EOL> break <EOL> else : <EOL> break <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' <EOL> % ( str ( prec ) , expr ) ) <EOL> return rs_trunc ( p1 , gen , prec ) </s>
