(ex, x, dom)
return res
Computes the minimal polynomial of an algebraic element
    using operations on minimal polynomials

    Examples
    ========

    >>> from sympy import minimal_polynomial, sqrt, Rational
    >>> from sympy.abc import x, y
    >>> minimal_polynomial(sqrt(2) + 3*Rational(1, 3), x, compose=True)
    x**2 - 2*x - 1
    >>> minimal_polynomial(sqrt(y) + 1/y, x, compose=True)
    x**2*y**2 - 2*x*y - y**3 + 1
Computes the minimal polynomial of an algebraic element
    using operations on minimal polynomials
Computes the minimal polynomial of an algebraic element using operations on minimal polynomials
def _minpoly_compose(ex, x, dom):
    """
    Computes the minimal polynomial of an algebraic element
    using operations on minimal polynomials

    Examples
    ========

    >>> from sympy import minimal_polynomial, sqrt, Rational
    >>> from sympy.abc import x, y
    >>> minimal_polynomial(sqrt(2) + 3*Rational(1, 3), x, compose=True)
    x**2 - 2*x - 1
    >>> minimal_polynomial(sqrt(y) + 1/y, x, compose=True)
    x**2*y**2 - 2*x*y - y**3 + 1

    """
    if ex.is_Rational:
        return ex.q*x - ex.p
    if ex is I:
        return x**2 + 1
    if hasattr(dom, 'symbols') and ex in dom.symbols:
        return x - ex

    if dom.is_QQ and _is_sum_surds(ex):
        # eliminate the square roots
        ex -= x
        while 1:
            ex1 = _separate_sq(ex)
            if ex1 is ex:
                return ex
            else:
                ex = ex1

    if ex.is_Add:
        res = _minpoly_add(x, dom, *ex.args)
    elif ex.is_Mul:
        f = Factors(ex).factors
        r = sift(f.items(), lambda itx: itx[0].is_rational and itx[1].is_rational)
        if r[True] and dom == QQ:
            ex1 = Mul(*[bx**ex for bx, ex in r[False] + r[None]])
            r1 = r[True]
            dens = [y.q for _, y in r1]
            lcmdens = reduce(lcm, dens, 1)
            nums = [base**(y.p*lcmdens // y.q) for base, y in r1]
            ex2 = Mul(*nums)
            mp1 = minimal_polynomial(ex1, x)
            # use the fact that in SymPy canonicalization products of integers
            # raised to rational powers are organized in relatively prime
            # bases, and that in ``base**(n/d)`` a perfect power is
            # simplified with the root
            mp2 = ex2.q*x**lcmdens - ex2.p
            ex2 = ex2**Rational(1, lcmdens)
            res = _minpoly_op_algebraic_element(Mul, ex1, ex2, x, dom, mp1=mp1, mp2=mp2)
        else:
            res = _minpoly_mul(x, dom, *ex.args)
    elif ex.is_Pow:
        res = _minpoly_pow(ex.base, ex.exp, x, dom)
    elif ex.__class__ is C.sin:
        res = _minpoly_sin(ex, x)
    elif ex.__class__ is C.cos:
        res = _minpoly_cos(ex, x)
    elif ex.__class__ is C.exp:
        res = _minpoly_exp(ex, x)
    elif ex.__class__ is RootOf:
        res = _minpoly_rootof(ex, x)
    else:
        raise NotAlgebraic("%s doesn't seem to be an algebraic element" % ex)
    return res
def _minpoly_compose ( ex , x , dom ) : if ex . is_Rational : return ex . q * x - ex . p if ex is I : return x ** 2 + 1 if hasattr ( dom , 'symbols' ) and ex in dom . symbols : return x - ex if dom . is_QQ and _is_sum_surds ( ex ) : # eliminate the square roots ex -= x while 1 : ex1 = _separate_sq ( ex ) if ex1 is ex : return ex else : ex = ex1 if ex . is_Add : res = _minpoly_add ( x , dom , * ex . args ) elif ex . is_Mul : f = Factors ( ex ) . factors r = sift ( f . items ( ) , lambda itx : itx [ 0 ] . is_rational and itx [ 1 ] . is_rational ) if r [ True ] and dom == QQ : ex1 = Mul ( * [ bx ** ex for bx , ex in r [ False ] + r [ None ] ] ) r1 = r [ True ] dens = [ y . q for _ , y in r1 ] lcmdens = reduce ( lcm , dens , 1 ) nums = [ base ** ( y . p * lcmdens // y . q ) for base , y in r1 ] ex2 = Mul ( * nums ) mp1 = minimal_polynomial ( ex1 , x ) # use the fact that in SymPy canonicalization products of integers # raised to rational powers are organized in relatively prime # bases, and that in ``base**(n/d)`` a perfect power is # simplified with the root mp2 = ex2 . q * x ** lcmdens - ex2 . p ex2 = ex2 ** Rational ( 1 , lcmdens ) res = _minpoly_op_algebraic_element ( Mul , ex1 , ex2 , x , dom , mp1 = mp1 , mp2 = mp2 ) else : res = _minpoly_mul ( x , dom , * ex . args ) elif ex . is_Pow : res = _minpoly_pow ( ex . base , ex . exp , x , dom ) elif ex . __class__ is C . sin : res = _minpoly_sin ( ex , x ) elif ex . __class__ is C . cos : res = _minpoly_cos ( ex , x ) elif ex . __class__ is C . exp : res = _minpoly_exp ( ex , x ) elif ex . __class__ is RootOf : res = _minpoly_rootof ( ex , x ) else : raise NotAlgebraic ( "%s doesn't seem to be an algebraic element" % ex ) return res