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

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

Aaron Meurer

>
>>>> Poly((x + y + t)*z, t, domain='EX', expand=False)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File 
> "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sympy/polys/polytools.py",
> line 98, in __new__
>     return cls._from_expr(rep, opt)
>   File 
> "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sympy/polys/polytools.py",
> line 208, in _from_expr
>     rep, opt = _dict_from_expr(rep, opt)
>   File 
> "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sympy/polys/polyutils.py",
> line 292, in _dict_from_expr
>     rep, gens = _dict_from_expr_if_gens(expr, opt)
>   File 
> "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sympy/polys/polyutils.py",
> line 250, in _dict_from_expr_if_gens
>     (poly,), gens = _parallel_dict_from_expr_if_gens((expr,), opt)
>   File 
> "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sympy/polys/polyutils.py",
> line 160, in _parallel_dict_from_expr_if_gens
>     raise PolynomialError("%s contains an element of the generators
> set" % factor)
> sympy.polys.polyerrors.PolynomialError: t + x + y contains an element
> of the generators set
>
> Thanks,
> 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.
>

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