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.

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