Problems with simplifying

56 views
Skip to first unread message

Darek Cidlinský

unread,
Nov 9, 2014, 11:24:15 AM11/9/14
to sy...@googlegroups.com
I would like to have sympy simplify a monstrous polynom ratio:

In [2]: E=1/(2*x1**2 - 4*x1*x2 + 2*x2**2 + 2*y1**2 - 4*y1*y2 + 2*y2**2) * (-y1*r1**2 + y2*r1**2 + y1*r2**2 - y2*r2**2 + y1*x1**2 + y2*x1**2 - 2*x1*x2*y1 - 2*x1*x2*y2 + y1*x2**2 + y2*x2**2 + y1**3 - y2*y1**2 - y1*y2**2 + y2**3)

In [3]: simplify(E)

   2       2       2       2       2      2                            2       2      3     2         2    3
- r₁ ⋅y₁ + r₁ ⋅y₂ + r₂ ⋅y₁ - r₂ ⋅y₂ + x₁ ⋅y₁ + x₁ ⋅y₂ - 2⋅x₁⋅x₂⋅y₁ - 2⋅x₁⋅x₂⋅y₂ + x₂ ⋅y₁ + x₂ ⋅y₂ + y₁  - y₁ ⋅y₂ - y₁⋅y₂  + y₂ 
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                           ⎛ 2             2     2             2⎞                                         
                                         2⋅⎝x₁  - 2⋅x₁⋅x₂ + x₂  + y₁  - 2⋅y₁⋅y₂ + y₂ ⎠                                         


The only thing that was simplified was the denominator, and even there it didn't output 2[(x1-x2)^2 + (y1-y2)^2] as could be expected, but it only moved the 2 out of the way. Which is OK, but it's one of 100 steps that need be taken.

I sat down with pencil and paper and after some effort simplified this bestiality to

In [4]: F = ((y1-y2)*(r2**2 - r1**2 + y1**2 - y2**2) + (y1+y2)*(x1-x2)**2)/(2*((x1-x2)**2 + (y1-y2)**2))

In [5]: F
Out[5]: 
        2                     ⎛    2    2    2     2⎞
(x₁ - x₂) ⋅(y₁ + y₂) + (y₁ - y₂)⋅⎝- r₁  + r₂  + y₁  - y₂ ⎠
──────────────────────────────────────────────────────────
                         2             2                
               2⋅(x₁ - x₂)  + 2⋅(y₁ - y₂)                 

In [8]: simplify(E-F)
Out[8]: 0

F is truly equal to E ... so why couldn't it be simplified at least to that?

I even searched the docs and tried to use various dedicated simplification functions, but to no avail (factor() left it alone -- eventhough I thought that when it simplifies x^2 + 2xy + y^2 to (x+y)^2, it could do something here, and so did the other functions). The only "salvation" here seems to be collect(), but the problem is that I need to tell the symbol which should be collected, so the best I could do with that would be some kind of "guided tour" -- I'd need to look at it, then think out what should be done next, then write the command and have it done.

Is there a way to automate this?

Mateusz Paprocki

unread,
Nov 10, 2014, 7:37:12 AM11/10/14
to sympy
Hi,
sympy doesn't have a built-in automatic method to do this kind of
simplifications. factor() doesn't help here because it works on the
whole expression and must give a product if expression has factors.
collect() doesn't help either, because it's not smart about what
subexpressions to factor out (that's by design). You can, however,
take all the low-level tools and compose them to get an algorithm for
your purpose. See for example
https://gist.github.com/mattpap/c59ed5529744c06f23b1, where I use
factor(), multiset_partitions() and count_ops() to get the desired
behavior. This approach is horribly inefficient, so this isn't
anything we would provide by default in sympy (or at least run by
default in simplify()).

Mateusz

> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/25f22412-038b-420b-af5f-05733d251f99%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Chris Smith

unread,
Nov 18, 2014, 2:48:39 PM11/18/14
to sy...@googlegroups.com
If you suspect that you are working with something that is pretty symmetric, something like this can work:

>>> def group_factor(r, *p):
...  a = []
...  for g in p:
...   i,r = r.as_independent(*g)
...   a.append(factor(i))
...  return Add(*a)
...
>>> n,d = [i.expand() for i in E.expand().as_numer_denom()]
>>> pairs = (x1,x2),(y1,y2),(r1,r2)
>>> pprint(group_factor(n,*pairs)/group_factor(d,*pairs))
         2                       /    2     2     2     2\
(x1 - x2) *(y1 + y2) + (y1 - y2)*\- r1  + r2  + y1  - y2 /
----------------------------------------------------------
                          2              2
               2*(x1 - x2)  + 2*(y1 - y2)


Darek Cidlinský

unread,
Dec 1, 2014, 11:37:23 AM12/1/14
to sy...@googlegroups.com
So humans still beat computers on this field? Nice :)

The factor grouping function is nice, but sadly I don't have such a deep understanding of sympy's mechanisms. I'm afraid it will be easier for me to simplify it by hand, unless it's a monstrous expression I got as a result of some prior computations.

Thank you anyway.
Reply all
Reply to author
Forward
0 new messages