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?

Thanks,
Amit.


--
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.


Reply via email to