'A mostly naive separation of a Mul or Add into arguments that are not
are dependent on deps. To obtain as complete a separation of variables
as possible, use a separation method first, e.g.:
* separatevars() to change Mul, Add and Pow (including exp) into Mul
* .expand(mul=True) to change Add or Mul into Add
* .expand(log=True) to change log expr into an Add
The only non-naive thing that is done here is to respect noncommutative
ordering of variables and to always return (0, 0) for `self` of zero
regardless of hints.
For nonzero `self`, the returned tuple (i, d) has the
following interpretation:
* i will has no variable that appears in deps
* d will be 1 or else have terms that contain variables that are in deps
* if self is an Add then self = i + d
* if self is a Mul then self = i*d
* otherwise (self, S.One) or (S.One, self) is returned.
To force the expression to be treated as an Add, use the hint as_Add=True
Examples
-- self is an Add
>>> from sympy import sin, cos, exp
>>> from sympy.abc import x, y, z
>>> (x + x*y).as_independent(x)
(0, x*y + x)
>>> (x + x*y).as_independent(y)
(x, x*y)
>>> (2*x*sin(x) + y + x + z).as_independent(x)
(y + z, 2*x*sin(x) + x)
>>> (2*x*sin(x) + y + x + z).as_independent(x, y)
(z, 2*x*sin(x) + x + y)
-- self is a Mul
>>> (x*sin(x)*cos(y)).as_independent(x)
(cos(y), x*sin(x))
non-commutative terms cannot always be separated out when self is a Mul
>>> from sympy import symbols
>>> n1, n2, n3 = symbols(\'n1 n2 n3\', commutative=False)
>>> (n1 + n1*n2).as_independent(n2)
(n1, n1*n2)
>>> (n2*n1 + n1*n2).as_independent(n2)
(0, n1*n2 + n2*n1)
>>> (n1*n2*n3).as_independent(n1)
(1, n1*n2*n3)
>>> (n1*n2*n3).as_independent(n2)
(n1, n2*n3)
>>> ((x-n1)*(x-y)).as_independent(x)
(1, (x - y)*(x - n1))
-- self is anything else:
>>> (sin(x)).as_independent(x)
(1, sin(x))
>>> (sin(x)).as_independent(y)
(sin(x), 1)
>>> exp(x+y).as_independent(x)
(1, exp(x + y))
-- force self to be treated as an Add:
>>> (3*x).as_independent(x, as_Add=True)
(0, 3*x)
-- force self to be treated as a Mul:
>>> (3+x).as_independent(x, as_Add=False)
(1, x + 3)
>>> (-3+x).as_independent(x, as_Add=False)
(1, x - 3)
Note how the below differs from the above in making the
constant on the dep term positive.
>>> (y*(-3+x)).as_independent(x)
(y, x - 3)
-- use .as_independent() for true independence testing instead
of .has(). The former considers only symbols in the free
symbols while the latter considers all symbols
>>> from sympy import Integral
>>> I = Integral(x, (x, 1, 2))
>>> I.has(x)
True
>>> x in I.free_symbols
False
>>> I.as_independent(x) == (I, 1)
True
>>> (I + x).as_independent(x) == (I, x)
True
Note: when trying to get independent terms, a separation method
might need to be used first. In this case, it is important to keep
track of what you send to this routine so you know how to interpret
the returned values
>>> from sympy import separatevars, log
>>> separatevars(exp(x+y)).as_independent(x)
(exp(y), exp(x))
>>> (x + x*y).as_independent(y)
(x, x*y)
>>> separatevars(x + x*y).as_independent(y)
(x, y + 1)
>>> (x*(1 + y)).as_independent(y)
(x, y + 1)
>>> (x*(1 + y)).expand(mul=True).as_independent(y)
(x, x*y)
>>> a, b=symbols(\'a b\', positive=True)
>>> (log(a*b).expand(log=True)).as_independent(b)
(log(a), log(b))
See Also
.separatevars(), .expand(log=True), Add.as_two_terms(),
Mul.as_two_terms(), .as_coeff_add(), .as_coeff_mul()'

def as_independent(self, *deps, **hint):

    from .symbol import Symbol
    from .add import _unevaluated_Add
    from .mul import _unevaluated_Mul
    from sympy.utilities.iterables import sift
    if self.is_zero:
        return (S.Zero, S.Zero)
    func = self.func
    if hint.get('as_Add', (func is Add)):
        want = Add
    else:
        want = Mul
    sym = set()
    other = []
    for d in deps:
        if isinstance(d, Symbol):
            sym.add(d)
        else:
            other.append(d)
    def has(e):
        'return    the    standard    has()    if    there    are    no    literal    symbols,    else\n                                                check    to    see    that    symbol-deps    are    in    the    free    symbols.'
        has_other = e.has(*other)
        if (not sym):
            return has_other
        return (has_other or e.has(*(e.free_symbols & sym)))
    if ((want is not func) or ((func is not Add) and (func is not Mul))):
        if has(self):
            return (want.identity, self)
        else:
            return (self, want.identity)
    elif (func is Add):
        args = list(self.args)
    else:
        (args, nc) = self.args_cnc()
    d = sift(args, (lambda x: has(x)))
    depend = d[True]
    indep = d[False]
    if (func is Add):
        return (Add(*indep), _unevaluated_Add(*depend))
    else:
        for (i, n) in enumerate(nc):
            if has(n):
                depend.extend(nc[i:])
                break
            indep.append(n)
        return (Mul(*indep), (Mul(evaluate=False, *depend) if nc else _unevaluated_Mul(*depend)))
