On Thu, Jul 4, 2013 at 1:42 AM, Ondřej Čertík <[email protected]> wrote: > 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?
Here it is: ''' script for multiple tangent/radius ''' from sympy import Point, Segment, Circle, simplify, sqrt c = Point(0,0) r=1 circle = Circle(c,r) tp = Point(583472175031549/1000000000000000, 63*sqrt(166177934231280788032465271)/1000000000000000) 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)) > > 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. Thanks, I hope the above helps. Best, Amit. > > 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. > > -- http://echorand.me -- 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.
