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.

Reply via email to