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.


Reply via email to