On Wed, Jul 3, 2013 at 6:42 AM, Amit Saha <[email protected]> wrote: > On Wed, Jul 3, 2013 at 8:11 AM, Ondřej Čertík <[email protected]> wrote: >> On Tue, Jul 2, 2013 at 3:42 PM, Amit Saha <[email protected]> wrote: >>> On Wed, Jul 3, 2013 at 2:29 AM, Ondřej Čertík <[email protected]> >>> wrote: >>>> On Tue, Jul 2, 2013 at 8:33 AM, Amit Saha <[email protected]> wrote: >>>>> Hi Ondřej, >>>>> >>>>> On Tue, Jul 2, 2013 at 1:30 AM, Ondřej Čertík <[email protected]> >>>>> wrote: >>>>>> Hi Amit, >>>>>> >>>>>> On Sat, Jun 29, 2013 at 4:32 AM, Amit Saha <[email protected]> wrote: >>>>>>> Hello, >>>>>>> >>>>>>> Currently the is_perpendicular() method is defined, like so: >>>>>>> >>>>>>> a1, b1, c1 = l1.coefficients >>>>>>> a2, >>>>>>> b2, c2 = l2.coefficients >>>>>>> return >>>>>>> bool(simplify(a1*a2 + b1*b2) == 0) >>>>>>> >>>>>>> Now it is possible (as I have just found) that the above sum may >>>>>>> equate to something tlike 1e-15, but not 0 (same with the product of >>>>>>> the slope coming to -0.9994). >>>>>>> >>>>>>> Does it make sense to have the provision for adding an epsilon value >>>>>>> such that anything below that is deemed to be 0? >>>>>> >>>>>> Can you post your code that gives 1e-15? The idea is that when only >>>>>> symbolic >>>>>> values are used (i.e. no floating point numbers), you can compare >>>>>> directly to 0. >>>>> >>>>> Okay, this is the code: >>>>> >>>>>>>> from sympy import Circle, Point, Segment >>>>>>>> c = Point(0,0) >>>>>>>> r=1 >>>>>>>> circle = Circle(c,r) >>>>>>>> tp = circle.random_point() >>>>>>>> tangent = circle.tangent_lines(tp) >>>>>>>> tangent = tangent[0] >>>>> >>>>>>>> rad = Segment(circle.center, tp) >>>>> >>>>>>>> (tangent.slope * rad.slope).evalf() >>>>> -1.00000000000000 >>>>>>>> tangent.is_perpendicular(rad) >>>>> True >>>> >>>> See my notebook where I explain it: >>>> >>>> http://nbviewer.ipython.org/5910821 >>>> >>>>> >>>>> So, in this case as you can see, both "tests" tell me that they are >>>>> perpendicular, as they should be. >>>>> >>>>> However, for another point (when I originally wrote my query), the >>>>> product (tangent.slope * rad.slope).evalf() resulted >>>>> in -0.999999 (I am sorry what I meant by 1e-15 was a made up figure to >>>>> illustrate the infinitesimal difference between -1 and the product and >>>>> *not* the product). >>>> >>>> The evalf() method returns a floating point, which of course cannot be >>>> directly compared to 0. And you would have to use eps, as you >>>> suggested. However, the point is that you should not call evalf() on >>>> it. >>> >>> Thanks for the notebook. I am clear about what I was doing there. >>> >>>> >>>>> >>>>> Also, the is_perpendicular() method returned False (the value was >>>>> close to 0 but not quite). >>>> >>>> Can you post a code which does that? >>> >>> Sure, here it is: >>> >>> ''' >>> script for multiple tangent/radius >>> ''' >>> from sympy import Point, Segment, Circle, simplify >>> c = Point(0,0) >>> r=1 >>> circle = Circle(c,r) >>> >>> for i in range(20): >>> tp = circle.random_point() >>> tangent = circle.tangent_lines(tp) >>> tangent = tangent[0] >>> rad = Segment(circle.center, tp) >>> >>> a1, b1, c1 = tangent.coefficients >>> a2, b2, c2 = rad.coefficients >>> print(tangent.is_perpendicular(rad), simplify(a1*a2 + b1*b2)) >>> >>> >>> >>> I am basically generating 20 random points on the circle and checking >>> for the validity of the radius and the tangent line being >>> perpendicular to each other. You may not see one False for one run, >>> but you may in another. >>> >>> For example on one of my runs, I got a False value with the following >>> value of a1*a2 + b1*b2: >>> >>> False >>> -3*2**(109/331)*3**(441/662)*5**(311/331)*7**(267/331)*sqrt(7822160432578995537131522933)/14000000000000000 >>> + >>> 128582730964399*sqrt(23466481297736986611394568799)/40000000000000000000000000000 >>> + 23466481297736986611394568799/40000000000000000000000000000 >>> >>> (Sorry about that). >>> >>> That actually evaluates to >>> >>>>>> val.evalf() >>> 1.40310612431989e-17 >>> >>> which is perhaps what I emailed in my original query, but forgot about >>> it later :) >> >> I see. That indeed is a bug if it gives False. Can you try to do >> val.evalf(100), this prints 100 digits. I expect the number to be >> ~1e-100. If you print 1000 digits I expect the number to be ~1e-1000. >> In other words, "val" is zero, but obviously once you convert to >> floating point, you only get approximate zero. >> >> Finally, this clearly needs some simplification. Can you apply >> "simplify" on val? >> >> Also, can you create some definite test case (without random numbers), >> so that we can add it to our test suite and fix it? I can help you if >> you get stuck. > > > Okay, here is something funny. > > I ran the above code using the SymPy from the GitHub clone (using the > 2to3 script for Python 3 install) and didn't get a False for 1000 > random iterations. Then what I did was I noted a point for which I was > getting a failure (False) and fed it into the system where I was using > the library from the latest clone, and the perpendicular test passes. > > So has something been fixed since 0.7.2? It seems to me so.. > > Is there any other test I can do to help?
Can you send the script that fails in 0.7.2 and succeeds in the latest master? We've fixed a lot of things in master, but it'd be nice to make sure and maybe write a simple test for your case to make sure that this is fixed forever and won't break in the future. Ondrej -- 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy. For more options, visit https://groups.google.com/groups/opt_out.
