(a, b, two=False)
Return the gcd, s1, s2, a1, a2, bool where

    If two is False (default) then::
        a + b = gcd*(s1*f(a1) + s2*f(a2)) where f = cos if bool else sin
    else:
        if bool, a + b was +/- cos(a1)*cos(a2) +/- sin(a1)*sin(a2) and equals
            n1*gcd*cos(a - b) if n1 == n2 else
            n1*gcd*cos(a + b)
        else a + b was +/- cos(a1)*sin(a2) +/- sin(a1)*cos(a2) and equals
            n1*gcd*sin(a + b) if n1 = n2 else
            n1*gcd*sin(b - a)

    Examples
    ========

    >>> from sympy.simplify.fu import trig_split
    >>> from sympy.abc import x, y, z
    >>> from sympy import cos, sin, sqrt

    >>> trig_split(cos(x), cos(y))
    (1, 1, 1, x, y, True)
    >>> trig_split(2*cos(x), -2*cos(y))
    (2, 1, -1, x, y, True)
    >>> trig_split(cos(x)*sin(y), cos(y)*sin(y))
    (sin(y), 1, 1, x, y, True)

    >>> trig_split(cos(x), -sqrt(3)*sin(x), two=True)
    (2, 1, -1, x, pi/6, False)
    >>> trig_split(cos(x), sin(x), two=True)
    (sqrt(2), 1, 1, x, pi/4, False)
    >>> trig_split(cos(x), -sin(x), two=True)
    (sqrt(2), 1, -1, x, pi/4, False)
    >>> trig_split(sqrt(2)*cos(x), -sqrt(6)*sin(x), two=True)
    (2*sqrt(2), 1, -1, x, pi/6, False)
    >>> trig_split(-sqrt(6)*cos(x), -sqrt(2)*sin(x), two=True)
    (-2*sqrt(2), 1, 1, x, pi/3, False)
    >>> trig_split(cos(x)/sqrt(6), sin(x)/sqrt(2), two=True)
    (sqrt(6)/3, 1, 1, x, pi/6, False)
    >>> trig_split(-sqrt(6)*cos(x)*sin(y), -sqrt(2)*sin(x)*sin(y), two=True)
    (-2*sqrt(2)*sin(y), 1, 1, x, pi/3, False)

    >>> trig_split(cos(x), sin(x))
    >>> trig_split(cos(x), sin(z))
    >>> trig_split(2*cos(x), -sin(x))
    >>> trig_split(cos(x), -sqrt(3)*sin(x))
    >>> trig_split(cos(x)*cos(y), sin(x)*sin(z))
    >>> trig_split(cos(x)*cos(y), sin(x)*sin(y))
    >>> trig_split(-sqrt(6)*cos(x), sqrt(2)*sin(x)*sin(y), two=True)
Return the gcd, s1, s2, a1, a2, bool where
Return the gcd s1 s2 a1 a2 bool where
def trig_split(a, b, two=False):
    """Return the gcd, s1, s2, a1, a2, bool where

    If two is False (default) then::
        a + b = gcd*(s1*f(a1) + s2*f(a2)) where f = cos if bool else sin
    else:
        if bool, a + b was +/- cos(a1)*cos(a2) +/- sin(a1)*sin(a2) and equals
            n1*gcd*cos(a - b) if n1 == n2 else
            n1*gcd*cos(a + b)
        else a + b was +/- cos(a1)*sin(a2) +/- sin(a1)*cos(a2) and equals
            n1*gcd*sin(a + b) if n1 = n2 else
            n1*gcd*sin(b - a)

    Examples
    ========

    >>> from sympy.simplify.fu import trig_split
    >>> from sympy.abc import x, y, z
    >>> from sympy import cos, sin, sqrt

    >>> trig_split(cos(x), cos(y))
    (1, 1, 1, x, y, True)
    >>> trig_split(2*cos(x), -2*cos(y))
    (2, 1, -1, x, y, True)
    >>> trig_split(cos(x)*sin(y), cos(y)*sin(y))
    (sin(y), 1, 1, x, y, True)

    >>> trig_split(cos(x), -sqrt(3)*sin(x), two=True)
    (2, 1, -1, x, pi/6, False)
    >>> trig_split(cos(x), sin(x), two=True)
    (sqrt(2), 1, 1, x, pi/4, False)
    >>> trig_split(cos(x), -sin(x), two=True)
    (sqrt(2), 1, -1, x, pi/4, False)
    >>> trig_split(sqrt(2)*cos(x), -sqrt(6)*sin(x), two=True)
    (2*sqrt(2), 1, -1, x, pi/6, False)
    >>> trig_split(-sqrt(6)*cos(x), -sqrt(2)*sin(x), two=True)
    (-2*sqrt(2), 1, 1, x, pi/3, False)
    >>> trig_split(cos(x)/sqrt(6), sin(x)/sqrt(2), two=True)
    (sqrt(6)/3, 1, 1, x, pi/6, False)
    >>> trig_split(-sqrt(6)*cos(x)*sin(y), -sqrt(2)*sin(x)*sin(y), two=True)
    (-2*sqrt(2)*sin(y), 1, 1, x, pi/3, False)

    >>> trig_split(cos(x), sin(x))
    >>> trig_split(cos(x), sin(z))
    >>> trig_split(2*cos(x), -sin(x))
    >>> trig_split(cos(x), -sqrt(3)*sin(x))
    >>> trig_split(cos(x)*cos(y), sin(x)*sin(z))
    >>> trig_split(cos(x)*cos(y), sin(x)*sin(y))
    >>> trig_split(-sqrt(6)*cos(x), sqrt(2)*sin(x)*sin(y), two=True)
    """
    global _ROOT2, _ROOT3, _invROOT3
    if _ROOT2 is None:
        _roots()

    a, b = [Factors(i) for i in (a, b)]
    ua, ub = a.normal(b)
    gcd = a.gcd(b).as_expr()
    n1 = n2 = 1
    if S.NegativeOne in ua.factors:
        ua = ua.quo(S.NegativeOne)
        n1 = -n1
    elif S.NegativeOne in ub.factors:
        ub = ub.quo(S.NegativeOne)
        n2 = -n2
    a, b = [i.as_expr() for i in (ua, ub)]

    def pow_cos_sin(a, two):
        """Return ``a`` as a tuple (r, c, s) such that
        ``a = (r or 1)*(c or 1)*(s or 1)``.

        Three arguments are returned (radical, c-factor, s-factor) as
        long as the conditions set by ``two`` are met; otherwise None is
        returned. If ``two`` is True there will be one or two non-None
        values in the tuple: c and s or c and r or s and r or s or c with c
        being a cosine function (if possible) else a sine, and s being a sine
        function (if possible) else oosine. If ``two`` is False then there
        will only be a c or s term in the tuple.

        ``two`` also require that either two cos and/or sin be present (with
        the condition that if the functions are the same the arguments are
        different or vice versa) or that a single cosine or a single sine
        be present with an optional radical.

        If the above conditions dictated by ``two`` are not met then None
        is returned.
        """
        c = s = None
        co = S.One
        if a.is_Mul:
            co, a = a.as_coeff_Mul()
            if len(a.args) > 2 or not two:
                return None
            if a.is_Mul:
                args = list(a.args)
            else:
                args = [a]
            a = args.pop(0)
            if a.func is cos:
                c = a
            elif a.func is sin:
                s = a
            elif a.is_Pow and a.exp is S.Half:  # autoeval doesn't allow -1/2
                co *= a
            else:
                return None
            if args:
                b = args[0]
                if b.func is cos:
                    if c:
                        s = b
                    else:
                        c = b
                elif b.func is sin:
                    if s:
                        c = b
                    else:
                        s = b
                elif b.is_Pow and b.exp is S.Half:
                    co *= b
                else:
                    return None
            return co if co is not S.One else None, c, s
        elif a.func is cos:
            c = a
        elif a.func is sin:
            s = a
        if c is None and s is None:
            return
        co = co if co is not S.One else None
        return co, c, s

    # get the parts
    m = pow_cos_sin(a, two)
    if m is None:
        return
    coa, ca, sa = m
    m = pow_cos_sin(b, two)
    if m is None:
        return
    cob, cb, sb = m

    # check them
    if (not ca) and cb or ca and ca.func is sin:
        coa, ca, sa, cob, cb, sb = cob, cb, sb, coa, ca, sa
        n1, n2 = n2, n1
    if not two:  # need cos(x) and cos(y) or sin(x) and sin(y)
        c = ca or sa
        s = cb or sb
        if c.func is not s.func:
            return None
        return gcd, n1, n2, c.args[0], s.args[0], c.func is cos
    else:
        if not coa and not cob:
            if (ca and cb and sa and sb):
                if not ((ca.func is sa.func) is (cb.func is sb.func)):
                    return
                args = set([j.args for j in (ca, sa)])
                if not all(i.args in args for i in (cb, sb)):
                    return
                return gcd, n1, n2, ca.args[0], sa.args[0], ca.func is sa.func
        if ca and sa or cb and sb or \
            two and (ca is None and sa is None or cb is None and sb is None):
            return
        c = ca or sa
        s = cb or sb
        if c.args != s.args:
            return
        if not coa:
            coa = S.One
        if not cob:
            cob = S.One
        if coa is cob:
            gcd *= _ROOT2
            return gcd, n1, n2, c.args[0], pi/4, False
        elif coa/cob == _ROOT3:
            gcd *= 2*cob
            return gcd, n1, n2, c.args[0], pi/3, False
        elif coa/cob == _invROOT3:
            gcd *= 2*coa
            return gcd, n1, n2, c.args[0], pi/6, False
def trig_split ( a , b , two = False ) : global _ROOT2 , _ROOT3 , _invROOT3 if _ROOT2 is None : _roots ( ) a , b = [ Factors ( i ) for i in ( a , b ) ] ua , ub = a . normal ( b ) gcd = a . gcd ( b ) . as_expr ( ) n1 = n2 = 1 if S . NegativeOne in ua . factors : ua = ua . quo ( S . NegativeOne ) n1 = - n1 elif S . NegativeOne in ub . factors : ub = ub . quo ( S . NegativeOne ) n2 = - n2 a , b = [ i . as_expr ( ) for i in ( ua , ub ) ] def pow_cos_sin ( a , two ) : """Return ``a`` as a tuple (r, c, s) such that
        ``a = (r or 1)*(c or 1)*(s or 1)``.

        Three arguments are returned (radical, c-factor, s-factor) as
        long as the conditions set by ``two`` are met; otherwise None is
        returned. If ``two`` is True there will be one or two non-None
        values in the tuple: c and s or c and r or s and r or s or c with c
        being a cosine function (if possible) else a sine, and s being a sine
        function (if possible) else oosine. If ``two`` is False then there
        will only be a c or s term in the tuple.

        ``two`` also require that either two cos and/or sin be present (with
        the condition that if the functions are the same the arguments are
        different or vice versa) or that a single cosine or a single sine
        be present with an optional radical.

        If the above conditions dictated by ``two`` are not met then None
        is returned.
        """ c = s = None co = S . One if a . is_Mul : co , a = a . as_coeff_Mul ( ) if len ( a . args ) > 2 or not two : return None if a . is_Mul : args = list ( a . args ) else : args = [ a ] a = args . pop ( 0 ) if a . func is cos : c = a elif a . func is sin : s = a elif a . is_Pow and a . exp is S . Half : # autoeval doesn't allow -1/2 co *= a else : return None if args : b = args [ 0 ] if b . func is cos : if c : s = b else : c = b elif b . func is sin : if s : c = b else : s = b elif b . is_Pow and b . exp is S . Half : co *= b else : return None return co if co is not S . One else None , c , s elif a . func is cos : c = a elif a . func is sin : s = a if c is None and s is None : return co = co if co is not S . One else None return co , c , s # get the parts m = pow_cos_sin ( a , two ) if m is None : return coa , ca , sa = m m = pow_cos_sin ( b , two ) if m is None : return cob , cb , sb = m # check them if ( not ca ) and cb or ca and ca . func is sin : coa , ca , sa , cob , cb , sb = cob , cb , sb , coa , ca , sa n1 , n2 = n2 , n1 if not two : # need cos(x) and cos(y) or sin(x) and sin(y) c = ca or sa s = cb or sb if c . func is not s . func : return None return gcd , n1 , n2 , c . args [ 0 ] , s . args [ 0 ] , c . func is cos else : if not coa and not cob : if ( ca and cb and sa and sb ) : if not ( ( ca . func is sa . func ) is ( cb . func is sb . func ) ) : return args = set ( [ j . args for j in ( ca , sa ) ] ) if not all ( i . args in args for i in ( cb , sb ) ) : return return gcd , n1 , n2 , ca . args [ 0 ] , sa . args [ 0 ] , ca . func is sa . func if ca and sa or cb and sb or two and ( ca is None and sa is None or cb is None and sb is None ) : return c = ca or sa s = cb or sb if c . args != s . args : return if not coa : coa = S . One if not cob : cob = S . One if coa is cob : gcd *= _ROOT2 return gcd , n1 , n2 , c . args [ 0 ] , pi / 4 , False elif coa / cob == _ROOT3 : gcd *= 2 * cob return gcd , n1 , n2 , c . args [ 0 ] , pi / 3 , False elif coa / cob == _invROOT3 : gcd *= 2 * coa return gcd , n1 , n2 , c . args [ 0 ] , pi / 6 , False