Struggling to use nsimplify and N properly

73 views
Skip to first unread message

Andrew Spielberg

unread,
Nov 6, 2014, 10:52:52 PM11/6/14
to sy...@googlegroups.com
Hi all,

Recent adopter, first time caller, bear with me if I have some newbish misunderstandings about sympy.

I am working on a project where we are trying to use sympy to do a lot of symbolic geometric computation.  The project predates sympy, so I cannot really change too much code to accomodate it.

Our calculations create matrices, and sometimes, the expressions can seem large, like the one seen below.  I know that this is actually supposed to be a linear expression, and I need to get it into a linear form.

Matrix([
[                                                                      1.0*leg1.beamwidth - (2.05432527401305e-33*leg1.beamwidth**3 + 0.166666666666667*leg1.beamwidth**2*total_length + 0.166666666666667*leg1.beamwidth**2*(1.23259516440783e-32*leg1.beamwidth + total_length/2))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)),                                                                                       1.0*leg1.beamwidth - (2.05432527401305e-33*leg1.beamwidth**3 + 0.166666666666667*leg1.beamwidth**2*total_length + 0.166666666666667*leg1.beamwidth**2*(1.23259516440783e-32*leg1.beamwidth + total_length/2))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)),                                                 1.0*leg1.beamwidth - (2.05432527401305e-33*leg1.beamwidth**3 + 0.166666666666667*leg1.beamwidth**2*total_length + 0.166666666666667*leg1.beamwidth**2*(1.23259516440783e-32*leg1.beamwidth + total_length/2))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)),                                 1.0*leg1.beamwidth - (2.05432527401305e-33*leg1.beamwidth**3 + 0.166666666666667*leg1.beamwidth**2*total_length + 0.166666666666667*leg1.beamwidth**2*(1.23259516440783e-32*leg1.beamwidth + total_length/2))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2))],
[-6.12323399573677e-17*leg1.beamwidth - (-2.53215139886928e-65*leg1.beamwidth**3 + 0.0416666666666667*leg1.beamwidth*total_length**2 + 0.166666666666667*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)*(1.23259516440783e-32*leg1.beamwidth + total_length))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)), 6.12323399573677e-17*leg1.beamwidth + total_length/2 - (-2.53215139886928e-65*leg1.beamwidth**3 + 0.0416666666666667*leg1.beamwidth*total_length**2 + 0.166666666666667*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)*(1.23259516440783e-32*leg1.beamwidth + total_length))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)), total_length/2 - (-2.53215139886928e-65*leg1.beamwidth**3 + 0.0416666666666667*leg1.beamwidth*total_length**2 + 0.166666666666667*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)*(1.23259516440783e-32*leg1.beamwidth + total_length))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)), -(-2.53215139886928e-65*leg1.beamwidth**3 + 0.0416666666666667*leg1.beamwidth*total_length**2 + 0.166666666666667*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2)*(1.23259516440783e-32*leg1.beamwidth + total_length))/(6.16297582203915e-33*leg1.beamwidth**2 + 0.25*leg1.beamwidth*total_length + 0.5*leg1.beamwidth*(1.23259516440783e-32*leg1.beamwidth + total_length/2))],
[                                                                                                                                                                                                                                                                                                                                                                                                                        -1.0*leg1.beamwidth,                                                                                                                                                                                                                                                                                                                                                                                                                                         -1.0*leg1.beamwidth,                                                                                                                                                                                                                                                                                                                                                                                                                     0,                                                                                                                                                                                                                                                                                                                                                                                                     0]])

If I perform nsimplify on this with a tolerance = 1e-5, I get something reasonable:

Matrix([
[                                                                 leg1.beamwidth/2,                                                                 leg1.beamwidth/2, leg1.beamwidth/2, leg1.beamwidth/2],
[-612323399573677*leg1.beamwidth/10000000000000000000000000000000 - total_length/4, 612323399573677*leg1.beamwidth/10000000000000000000000000000000 + total_length/4,   total_length/4,  -total_length/4],
[                                                                  -leg1.beamwidth,                                                                  -leg1.beamwidth,                0,                0]])

But I can't simplify it further for some reason.  Even though -612323399573677*leg1.beamwidth/10000000000000000000000000000000  = -6e-17, I can't seem to make that term disappear.

This was a simple case, but in more complex cases, sympy fails to cancel out terms and the solution becomes highly nonlinear.  As an example, this won't simplify with nsimplify for some reason, even though certain terms clearly dominate others:

(leg1.beamwidth*total_length*(24492935982947*leg2.beamwidth/200000000000000000000000000000 + total_length/2)**2/2 - 306161699786839*leg2.beamwidth*total_length**2*(24492935982947*leg2.beamwidth/200000000000000000000000000000 + total_length/2)/10000000000000000000000000000000 + 153080849893419*total_length**3*(24492935982947*leg2.beamwidth/200000000000000000000000000000 + total_length/2)/10000000000000000000000000000000)/(total_length*(24492935982947*leg2.beamwidth/200000000000000000000000000000 + total_length/2)**2)

Lastly, things sometimes get worse.  If I try to play around with simplify, N, and nsimplify to try to "force" it to simplify things, I sometimes get the error attached.

Is there a proper way to get do the simplifications I need?  And, why would I get that value error I displayed attached.

Thanks for any and all help,
Andy S.
errortrace.txt

Aaron Meurer

unread,
Nov 9, 2014, 8:38:00 PM11/9/14
to sy...@googlegroups.com
I think you want the chop option, like expr.eval(chop=True) or N(expr, chop=True).

Aaron Meurer

--
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/c94c3d7f-623e-4a3c-9ff4-f19515598a2b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Spielberg

unread,
Nov 10, 2014, 4:52:50 PM11/10/14
to sy...@googlegroups.com
Thanks a ton - yes, using N and then specifying a tolerance with N worked.

Out of curiosity then, what is the point of the nsimplify tolerance?  What does that do?  I appear to be misunderstanding it.

-Andy S.

Aaron Meurer

unread,
Nov 10, 2014, 5:00:53 PM11/10/14
to sy...@googlegroups.com
nsimplify tries to convert floating point numbers into exact numbers, like sqrt(2) or pi + 1. The tolerance flag specifies how close the exact number needs to be to the floating point number. For example:

In [8]: nsimplify(pi.evalf(), tolerance=0.1)
Out[8]: 22/7

In [9]: nsimplify(pi.evalf(), tolerance=0.01)
Out[9]: 22/7

In [10]: nsimplify(pi.evalf(), tolerance=0.001)
Out[10]:
355
───
113

In [11]: nsimplify(pi.evalf(), tolerance=0.0001)
Out[11]:
355
───
113

Aaron Meurer

Andrew Spielberg

unread,
Nov 10, 2014, 6:42:58 PM11/10/14
to sy...@googlegroups.com
Aha, thanks so much!

-Andy S.

Chris Smith

unread,
Nov 18, 2014, 1:56:21 PM11/18/14
to sy...@googlegroups.com
Note also that your matrix will simplify without evaluation:

>>> m.applyfunc(simplify)
Matrix([
[ 0.5*leg1_beamwidth,  0.5*leg1_beamwidth, 0.5*leg1_beamwidth, 0.5*leg1_beamwidth],
[ -0.25*total_length,   0.25*total_length,  0.25*total_length, -0.25*total_length],
[-1.0*leg1_beamwidth, -1.0*leg1_beamwidth,                  0, 0]])

(I replaced the .beam with _beam, but otherwise you see that it simplifies just fine.)
Reply all
Reply to author
Forward
0 new messages