On Sun, Sep 30, 2012 at 10:32 PM, Geoffrey Irving <[email protected]> wrote: > On Thu, Sep 27, 2012 at 11:34 PM, Aaron Meurer <[email protected]> wrote: >> On Thu, Sep 27, 2012 at 11:30 PM, Geoffrey Irving <[email protected]> wrote: >>> On Thu, Sep 27, 2012 at 7:14 PM, Aaron Meurer <[email protected]> wrote: >>>> Yes, use expand=False: >>>> >>>> Poly((x + y)*z, t, domain='EX', expand=False) >>>> >>>> Note that the generators must already be expanded out for this to work. >>>> >>>> This is also recommended anyway if you already know ahead of time that >>>> the generators are expanded out, because it will be much faster. But >>>> also keep in mind that Poly won't notice if you have x*z + y*z in >>>> another place that it is the same as (x + y)*z. >>> >>> I guess I need a more complicated example then. What I actually want >>> to do is something like >>> >>> x,y,z = symbols('x y z') >>> a,b,c = symbols('a b c') >>> xs = x+a >>> ys = y+b >>> zs = z+c >>> p = (xs + ys) * zs >>> >>> then expand p as a polynomial in a,b,c without losing the structure of >>> each coefficient. For example, the constant term should be (x + y)*z. >>> As you say, a simple case of this fails: >> >> That's an interesting problem. I'm not sure if there's an easy way to >> do it in SymPy. In general, I guess you want to perform naive >> expansion, but only on those terms that contain variables of your >> polynomial. expand() works more efficiently than that. For example, >> if you had something like (x + y + a + b)**3, you would want to have >> your constant term be (x + y)**3. But expand works by computing all >> the multinomial coefficients and combines them together (it does *not* >> multiply out (x + y + a + b)*(x + y + a + b)*(x + y + a + b)). >> >> I suppose if your expression is a polynomial, and your "structure" can >> always be retrieved by factoring (i.e., you don't need to keep stuff >> like x*(y + 1) - 2), then you could just expand everything and then >> factor. You can do this using collect(expr.expand(), [a, b, c], >> factor): >> >> In [20]: collect(expand(p), [a, b, c], factor) >> Out[20]: a⋅(c + z) + b⋅(c + z) + c⋅(x + y) + z⋅(x + y) >> >> The only down fall of this is that it is inefficient (something you'll >> definitely notice if your expressions are of large degree). > > Currently my largest one is of degree 3 in 12 variables. I may need > to go higher later, so I'm leery of solutions which will be > exponential time in complexity. :) > >> Another way might be to try to collect all non-generator terms >> together into single symbols. You might be able to tweak cse() to do >> this. For example, if you started with just (c + z)*(a + b + x0), and >> then replaced x0 with x + y after expanding, you'd get what you want. >> >> cse() tweaking is not something that I've ever tried to do before, but >> I think you might be able to get what you want by using a sufficient >> optimization. If not, we should modify cse() so that it is possible >> :) >> >> If you can get something like this to work in a general setting, it >> might be worth sending a patch so we can just include it as an option >> to Poly. And if you make the cse() trick work, it would also be worth >> adding that as a direct option to cse (basically an option that says, >> "don't optimize these variables"). > > For now I just wrote my own minimalist polynomial class that doesn't > do any expansion or simplification: > > > https://github.com/otherlab/core/blob/7c9dbfd8f581f80364fdb415a79bc066737dad45/exact/simplicity.py#L125 > > Definitely a cop out, but it works for now. It would definitely be > great to have this as an option in standard sympy, but I don't know > enough about the architecture to know if it could be easily integrated > into everything else (though of course the linked code shows that it's > an easy add-on). It works by keeping the polynomial generators > completely separate from normal sympy objects, so that I control all > arithmetic involving the special polynomials. > > Geoffrey
I created an issue in the issue tracker for it, so we don't forget about the idea. See http://code.google.com/p/sympy/issues/detail?id=3412. Aaron Meurer > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/sympy?hl=en. > -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
