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

-- 
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.

Reply via email to