#NEWLINE# def ratint( f , x , **flags ) : #NEWLINE# #INDENT# "Performs indefinite integration of rational functions.\n\n       Given a field :math:`K` and a rational function :math:`f = p/q`,\n       where :math:`p` and :math:`q` are polynomials in :math:`K[x]`,\n       returns a function :math:`g` such that :math:`f = g'`.\n\n       >>> from sympy.integrals.rationaltools import ratint\n       >>> from sympy.abc import x\n\n       >>> ratint(36/(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2), x)\n       (12*x + 6)/(x**2 - 1) + 4*log(x - 2) - 4*log(x + 1)\n\n       References\n       ==========\n\n       .. [Bro05] M. Bronstein, Symbolic Integration I: Transcendental\n          Functions, Second Edition, Springer-Verlag, 2005, pp. 35-70\n\n       See Also\n       ========\n\n       sympy.integrals.integrals.Integral.doit\n       ratint_logpart, ratint_ratpart\n    " #NEWLINE# if ( type ( f ) is not tuple ) : #NEWLINE# #INDENT# ( p , q ) = f . as_numer_denom ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ( p , q ) = f #NEWLINE# #UNINDENT# ( p , q ) = ( Poly ( p , x , composite = False , field = True ) , Poly ( q , x , composite = False , field = True ) ) #NEWLINE# ( coeff , p , q ) = p . cancel ( q ) #NEWLINE# ( poly , p ) = p . div ( q ) #NEWLINE# result = poly . integrate ( x ) . as_expr ( ) #NEWLINE# if p . is_zero : #NEWLINE# #INDENT# return ( coeff * result ) #NEWLINE# #UNINDENT# ( g , h ) = ratint_ratpart ( p , q , x ) #NEWLINE# ( P , Q ) = h . as_numer_denom ( ) #NEWLINE# P = Poly ( P , x ) #NEWLINE# Q = Poly ( Q , x ) #NEWLINE# ( q , r ) = P . div ( Q ) #NEWLINE# result += ( g + q . integrate ( x ) . as_expr ( ) ) #NEWLINE# if ( not r . is_zero ) : #NEWLINE# #INDENT# symbol = flags . get ( 'symbol' , 't' ) #NEWLINE# if ( not isinstance ( symbol , Symbol ) ) : #NEWLINE# #INDENT# t = Dummy ( symbol ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# t = symbol . as_dummy ( ) #NEWLINE# #UNINDENT# L = ratint_logpart ( r , Q , x , t ) #NEWLINE# real = flags . get ( 'real' ) #NEWLINE# if ( real is None ) : #NEWLINE# #INDENT# if ( type ( f ) is not tuple ) : #NEWLINE# #INDENT# atoms = f . atoms ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ( p , q ) = f #NEWLINE# atoms = ( p . atoms ( ) | q . atoms ( ) ) #NEWLINE# #UNINDENT# for elt in ( atoms - { x } ) : #NEWLINE# #INDENT# if ( not elt . is_real ) : #NEWLINE# #INDENT# real = False #NEWLINE# break #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# real = True #NEWLINE# #UNINDENT# #UNINDENT# eps = S ( 0 ) #NEWLINE# if ( not real ) : #NEWLINE# #INDENT# for ( h , q ) in L : #NEWLINE# #INDENT# ( _ , h ) = h . primitive ( ) #NEWLINE# eps += RootSum ( q , Lambda ( t , ( t * log ( h . as_expr ( ) ) ) ) , quadratic = True ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# for ( h , q ) in L : #NEWLINE# #INDENT# ( _ , h ) = h . primitive ( ) #NEWLINE# R = log_to_real ( h , q , x , t ) #NEWLINE# if ( R is not None ) : #NEWLINE# #INDENT# eps += R #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# eps += RootSum ( q , Lambda ( t , ( t * log ( h . as_expr ( ) ) ) ) , quadratic = True ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# result += eps #NEWLINE# #UNINDENT# return ( coeff * result )