Separable next

So the next thing on my list is seperable differential equations. As I predicted in my proposal, I am going to have to do some work to get SymPy to recognize all equations that are separable. Currently, it can match expressions that are exactly written as a(x)b(y)\frac{dy}{dx}+c(x)d(y)=0, such as x^2(y+2)\frac{dy}{dx}-y^3=0 but the matching engine cannot get things like (x^2y+2x^2)\frac{dy}{dx}+-y^3=0, because it doesn’t know how to factor out the x^2. There is a function, collect, that can factor out expressions if you give them to it explicily with

collect(x**2*y+x**2,x**2)

but it doesn’t know yet how to separate variables in general. So I will be working on it this week. Once it can properly separate separable expressions, implementing it in dsolve will be cake.

Also, it needs to learn how to do e^{x+y}\rightarrow e^{x}e^{y} and 1+x+y+xy \rightarrow (1+x)(1+y).

Advertisements

4 Responses to Separable next

  1. vks says:

    Did you try cse() + factor()?

    • asmeurer says:

      I know that factor can reduce the polynomial. I was just saying that I need to use it.

      cse() doesn’t seem to do anything. Any expression I put in cse(expr) just returns [[],[expr,]].

      I figured out what cse does from the examples, but I don’t see how that will help me separate expressions. It looks like it turns things like (x+y)**2+sqrt(x+y) into ([(x0, x + y)], [x0**(1/2) + x0**2]). It doesn’t even seem to work for exp(x+y), although ([(x0, x + y)], [exp(x0)]) is not what I want.

      • vks says:

        >>> e = sin(x)
        >>> factor(e**2 + e)
        Traceback (most recent call last):
        File “”, line 1, in
        File “sympy/polys/factortools.py”, line 80, in factor
        coeff, factors = poly_factors(f, *symbols, **flags)
        File “sympy/polys/factortools.py”, line 20, in poly_factors
        f = Poly(f, *symbols)
        File “sympy/polys/polynomial.py”, line 402, in __new__
        terms = Poly._decompose(poly, *symbols)
        File “sympy/polys/polynomial.py”, line 545, in _decompose
        raise PolynomialError(“Can’t decompose %s” % factor)
        sympy.polys.polynomial.PolynomialError: Can’t decompose sin(x)**2
        >>> cse(e**2 + e)
        ([(x0, sin(x))], [x0 + x0**2])

        Then you can substitute back:

        >>> w, g = cse(e**2 + e)
        >>> g = factor(g[0])
        >>> g
        x0*(1 + x0)
        >>> g.subs(w[0][0], w[0][1]) # you’d have to iterate
        (1 + sin(x))*sin(x)

        > It doesn’t even seem to work for exp(x+y)

        It should only replace x+y if it occurs multiple times:

        >>> cse(exp(x+y))
        ([], [exp(x + y)]) # correct
        >>> cse(exp(x+y)+x+y)
        ([], [x + y + exp(x + y)]) # wrong
        >>> cse(exp(x+y)+x+y+sin(x+y))
        ([(x0, x + y)], [x0 + sin(x0) + exp(x0)]) # correct

        I filed a bug report for the second case.

  2. asmeurer says:

    OK. I see what you mean now. cse() turns it into a polynomial which can then be handled by factor(). It seems to choke if it has too many transcendentals:
    >>> e = expand(x*sin(x)*(y**2+sin(y)))
    >>> e
    x*y**2*sin(x) + x*sin(x)*sin(y)
    >>> cse(e)
    ([(x0, sin(x))], [x*x0*sin(y) + x*x0*y**2])
    >>> factor(cse(e)[1][0])
    Traceback (most recent call last):
    File “”, line 1, in
    File “./sympy/polys/factortools.py”, line 80, in factor
    coeff, factors = poly_factors(f, *symbols, **flags)
    File “./sympy/polys/factortools.py”, line 20, in poly_factors
    f = Poly(f, *symbols)
    File “./sympy/polys/polynomial.py”, line 402, in __new__
    terms = Poly._decompose(poly, *symbols)
    File “./sympy/polys/polynomial.py”, line 545, in _decompose
    raise PolynomialError(“Can’t decompose %s” % factor)
    PolynomialError: Can’t decompose sin(y)

    Compared to the simple separatevars function I wrote up:
    >>> separatevars(e)
    x*(sin(y) + y**2)*sin(x)

    As for expanding exponentials, I will write a function that does that (it should be simple). Right now, I am working on fixing issue 252 so that they aren’t put right back together after I take them apart.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: