On Saturday, April 9, 2016 at 11:56:01 AM UTC-7, Amy Valhausen wrote:
>
> In the thread ; https://groups.google.com/forum/#!topic/sympy/eUfW6C_nHdI
>
> I was seeking feedback and help with the problem of type ;
>
> ( 1.414213562^6000) % 400)
>
> After reviewing all the excellent collaboration at the above link, Im 
> feeling
> a little lost and overwhelmed.  So many good suggestions were made and
> also a lot of bugs, and bottlenecks discovered - Im not sure which approach
> is best for what I am hoping to solve?
>
> Ive been reviewing the problems with the different approaches, including 
> precision loss
> with use of floats, some of the suggested functions, etc.
>
> Oscar mentioned the solution of using a string value and storing it as a 
> possibility?
>
> My hope is to arrive at a method that returns lossless precision, if I 
> dont have to sacrifice speed then
> thats great but if preserving accuracy comes at a cost of speed thats ok 
> with me.
>
> I'd like also to get the highest precision available, if possible past the 
> 15 digit limit, the larger the better.
>
> What do you guys think is the best code solution for ;
> given any rational  between 1.0x and 2, for example "1.414213562"
> being raised to a power as high as 6000
> with modulus returned of 400
>
> ( 1.414213562^6000) % 400)    ?
>
> So that the greatest and most accurate precision is kept?
>
> I have been testing out some of the code ideas such as ;
>
> from sympy import mpmath
> mpmath.mp.dps = 821
> x = mpmath.mpf('1.414213562') ** 6000
>
> Thanks Oscar, Aaron and everyone!  I have a few questions to ask, but 
> first wanted to say this entire thread has been so meaningful as a learning 
> process for me!
>
> I am an intermediate VB programmer and newbie to python and this single 
> thread you have all been so gracefully collaborating together on has taught 
> me more and helped me to understand the issues surrounding this than any 
> other source online I have researched and I am saving this entire thread 
> for future use and review!
>
> I have been trying to keep pace with all the excellent insights and 
> suggestions as well as potential bottlenecks.
>
>  
Using Python's included Fraction type, you can calculate ((n**6000) % 400) 
exactly and then convert the exact result into a float.

>>> from fractions import Fraction
>>> float((Fraction("1.414213562")**6000) % 400)
314.3479803094588

The Fraction type isn't very fast but the calculation is exact.

However, if your value for n changes a small amount, your result will 
change by a large amount.

>>> float((Fraction("1.414213562")**6000) % 400)
314.3479803094588
>>> float((Fraction("1.4142135623")**6000) % 400)
82.204377195306
>>> float((Fraction("1.41421356237")**6000) % 400)
164.74604114158947
>>> float((Fraction("1.414213562373")**6000) % 400)
394.37793561523273

Your value of n looks suspiciously like an approximation to sqrt(2). If 
that's correct, the result would be:

>>> pow(2,3000,400)
176

Since we are using an approximation, the least significant digits (the ones 
retained by the mod operation) are incorrect. How many digits in the 
approximation of sqrt(2) are needed to produce a stable result?

(Note: I'm the maintainer of gmpy2, a module for very fast arbitrary 
precision arithmetic. If it is present on your system, it will be 
automatically used by mpmath. I'll use gmpy2 directly since I'm more 
familiar with it.)

>>> import gmpy2
>>> gmpy2.get_context().precision=10000
>>> s=str(gmpy2.sqrt(2))
>>> float((gmpy2.mpq(s[:900])**6000) % 400)
397.6970528425263
>>> float((gmpy2.mpq(s[:901])**6000) % 400)
317.77259005351806
>>> float((gmpy2.mpq(s[:902])**6000) % 400)
381.7876974957164
>>> float((gmpy2.mpq(s[:903])**6000) % 400)
381.7876974957164
>>> float((gmpy2.mpq(s[:904])**6000) % 400)
370.4278485701384
>>> float((gmpy2.mpq(s[:905])**6000) % 400)
48.15587878502279
>>> float((gmpy2.mpq(s[:906])**6000) % 400)
345.64468558337177
>>> float((gmpy2.mpq(s[:907])**6000) % 400)
154.42196588552062
>>> float((gmpy2.mpq(s[:908])**6000) % 400)
175.2996939157355
>>> float((gmpy2.mpq(s[:909])**6000) % 400)
175.82163711649088
>>> float((gmpy2.mpq(s[:910])**6000) % 400)
175.9782200767175
>>> 

You need over 900 accurate digits in the approximation of the sqrt(2) to 
get the expected answer.

casevh

-- 
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 sympy+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/65cc70c6-356f-454c-937a-148ee13192b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to