Highly precise division, multiplication, and exponentiation of large complex numbers - python

I am working on a project that requires highly precise division of large numbers which will sometimes be complex numbers. I need to do this in python, preferably python 3.7, but everything I have tried so far has not worked at all.
With real numbers, I can simply use the decimal module, but I found the decimal module does not work for complex numbers. In addition, when I have tried to extend the decimal module to the complex numbers, it has failed as I get inaccurate results with both large real and large complex inputs. When trying to download external modules with the functionality, it has not worked.
from decimal import *
def div(a,b):
y = b.real - (b.imag*1j)
a = a*y
b = Decimal((b*y).real)
return [Decimal(a.real)/b,Decimal(a.imag)/b]
Here is my code for using the decimal module on complex numbers, and to demonstrate what I mean (and to demonstrate this method of division works) Ill show below some inputs and outputs. The first one will be the method of working with relatively small inputs, and the 2nd will be the method very much not working with a large input.
>>> div(13243,23)[0]*23
Decimal('13243.00000000000000000000000')
>>> div(15**17,23)[0]*23
Decimal('98526125335693355453.21739130')
The result from trying with 15**17 is not only a few thousand higher than 15**17, but it's also not a whole number. This is very incorrect. As said I need this method to be transferable to the complex numbers, and as it stands to store complex numbers in a list is a pain and not ideal. It was necessary to do so in order to use decimal on the parts though, however, it clearly hasn't worked.
I thought at first that perhaps it was a case of I just needed to set the precision higher, but even when set to 1000 it still fails.
At this point, I tried to find some modules that would allow me to do this. I found 2. mpmath and gmpy. I tried to install gmpy via pip, and I tried doing so on multiple versions of python and with multiple versions of gmpy, and each time I got an error message, normally one about a sever "actively refusing connection", as well as others saying it wasn't supported, etc.
This kind of leaves me stuck. I can't get the modules that do it for me, and when I try to do it myself it quite blatantly isn't working. Is there another module that provides this functionality out there or is there something I am particularly doing wrong with my attempts that can be fixed somehow?

Related

Why does my Python freeze when I do an overflow calculation?

I'm a MATLAB user trying to understand Python so sorry if this is obvious.
If I say
print(9**9)
I get:
387420489
Great.
If I say print(9**9**9)
Python just sits there indefinitely and freezes (I use Spyder version 4). Ctrl-C doesn't stop it.
Why does it not just immediately return Inf? Is this expected behavior?
When doing numerical calculations with integers, python is not limited to machine-specific numbers such as "int32", and therefore a number such as "2147483647" does not mean much to it. Instead, it uses a "big integer" library, which can, in principle, express any large number, provided there is enough memory for it. When facing a computation such as 9**9**9 python tries to perform it exactly, producing the exact result, however big it may be. For this particular calculation it just takes a lot of time (and memory, presumably internally python is trying to allocate more and more memory as needed).
the num 9**9**9 is very big to caculated
you can wait untill it will return a result
it can take much long time
Why does my Python freeze when I do an overflow calculation?
because no overflow occurred and python hasn't given up. Python will extend the precision until either the calculation succeeds or the machine runs out of memory.

Python Panda.read_csv rounds to get import errors?

I have a 10000 x 250 dataset in a csv file. When I use the command
data = pd.read_csv('pool.csv', delimiter=',',header=None)
while I am in the correct path I actually import the values.
First I get the Dataframe. Since I want to work with the numpy package I need to convert this to its values using
data = data.values
And this is when i gets weird. I have at position [9999,0] in the file a -0.3839 as value. However after importing and calculating with it I noticed, that Python (or numpy) does something strange while importing.
Calling the value of data[9999,0] SHOULD give the expected -0.3839, but gives something like -0.383899892....
I already imported the file in other languages like Matlab and there was no issue of rounding those values. I aswell tried to use the .to_csv command from the pandas package instead of .values. However there is the exact same problem.
The last 10 elements of the first column are
-0.2716
0.3711
0.0487
-1.518
0.5068
0.4456
-1.753
-0.4615
-0.5872
-0.3839
Is there any import routine, which does not have those rounding errors?
Passing float_precision='round_trip' should solve this issue:
data = pd.read_csv('pool.csv',delimiter=',',header=None,float_precision='round_trip')
That's a floating point error. This is because of how computers work. (You can look it up if you really want to know how it works.) Don't be bothered by it, it is very small.
If you really want to use exact precision (because you are testing for exact values) you can look at the decimal module of Python, but your program will be a lot slower (probably like 100 times slower).
You can read more here: https://docs.python.org/3/tutorial/floatingpoint.html
You should know that all languages have this problem, only some are better in hiding it. (Also note that in Python3 this "hiding" of the floating point error has been improved.)
Since this problem cannot be solved by an ideal solution, you are given the task to solve it yourself and choose the most appropriate solution for your situtation
I don't know about 'round_trip' and its limitations, but it probably can help you. Other solutions would be to use float_format from the to_csv method. (https://docs.python.org/3/library/string.html#format-specification-mini-language)

Exact calculations in python [duplicate]

>>> float(str(0.65000000000000002))
0.65000000000000002
>>> float(str(0.47000000000000003))
0.46999999999999997 ???
What is going on here?
How do I convert 0.47000000000000003 to string and the resultant value back to float?
I am using Python 2.5.4 on Windows.
str(0.47000000000000003) give '0.47' and float('0.47') can be 0.46999999999999997.
This is due to the way floating point number are represented (see this wikipedia article)
Note: float(repr(0.47000000000000003)) or eval(repr(0.47000000000000003)) will give you the expected result, but you should use Decimal if you need precision.
float (and double) do not have infinite precision. Naturally, rounding errors occur when you operate on them.
This is a Python FAQ
The same question comes up quite regularly in comp.lang.python also.
I think reason it is a FAQ is that because python is perfect in all other respects ;-), we expect it to perform arithmetic perfectly - just like we were taught at school. However, as anyone who has done a numerical methods course will tell you, floating point numbers are a very long way from perfect.
Decimal is a good alternative and if you want more speed and more options gmpy is great too.
by this example
I think this is an error in Python when you devide
>>> print(int(((48/5.0)-9)*5))
2
the easy way, I solve this problem by this
>>> print(int(round(((48/5.0)-9)*5,2)))
3

How to set a general option in Python to display only N digits everywhere?

I want to work with 3 digits after the decimal point in Python. What is the relevant setting to modify ?
I want that 1.0 / 3 would return 0.333, and not 0.3333333333333333 like it is the case in my Jupyter Notebook, using python 2.7.11 and Anaconda 4.0.0.
In my research, I heard about the Decimal class, but I don't want to use Decimal(x) in my code every time I display a float, neither the string formating or the round function, though I use it for the time being (because I don't want to use it every time).
I think there is a general solution, a setting computed only once.
There is no "one-time" solution to your problem.
And I think that your approach might be a little misguided.
I suppose that your interaction with Jupyter or Ipython has lead you to the conclusion that python is quite handy as a numerical calculator. Unfortunately both of the aforementioned programs are just wrappers or REPL programs and in the background come with the full programming language flexibility that Python offers.
use numpy and try this;
round(1.0/3, 3)
or
>>> 1.0/3
0.3333333333333333
>>> '{:0.3f}'.format(1.0/3)
'0.333'

Python : Float addition causing problems in conditional statement [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 7 years ago.
This might seem really silly. But I am new to python and like to use equality conditions in my program, and has hit a very surprising road block. While the practical issue here is that the last condition r==rmax is not satisfied and I will miss out on an iteration of the loop, but that is not what is worrying me.
Rather than (trivial) work arounds, can someone explain to me what is going on in simple terms? (Also why the numbers turn out the same no matter how many times I run this loop, therefore it is something systematic and not something probabilistic).
And a proper way to make sure this does not happen (What I mean by proper is a programming practice I should adopt in all my coding, so that such unintentional discrepancy does not occur ever again)? I mean such loops are omnipresent in my codes and it makes me worried.
It seems I cannot trust numbers in python, which would make it useless as a computational tool.
PS : I am working on a scientific computing project with Numpy.
>>> while r<=r_max:
... print repr(r)
... r = r + r_step
...
2.4
2.5
2.6
2.7
2.8000000000000003
2.9000000000000004
3.0000000000000004
3.1000000000000005
3.2000000000000006
3.3000000000000007
3.400000000000001
3.500000000000001
3.600000000000001
3.700000000000001
3.800000000000001
3.9000000000000012
The simple answer is that floating-point numbers, as usually represented in computing, aren't exact, and you can't treat them as if they were exact. Treat them as if they're fuzzy; see if they're within a certain range, not whether they "equal" something.
The numbers turn out the same because it's all deterministic. The calculations are being done in exactly the same way each time. This isn't a case of random errors, it's a case of the machine representing floating-point numbers in an inexact way.
Python has some exact datatypes you can use instead of inexact floats; see the decimal and fractions modules.
There's a classic article called "What Every Computer Scientist Should Know About Floating-Point Arithmetic"; google it and pick any link you like.
Pierre G. is correct. Because computer calculate number in binary, it cannot present a lot float number exactly. But it should be precise with in certain digits depends the data type you use.
For your case, I think maybe you could use round(number, digits) function to get a round number and then compare it.
It's just the matter of float arithmetic. Actually If you know about the representation of floating numbers in the computer memory, then the representation of certain numbers though we consider to be whole integer, is not stored as a whole integer. It's stored with certain precision(in terms of number of digits after decimal point) only. This problem will remain always, whenever you are doing mathematical programming. I suggest you to use comparision, which can accept tolerance value. Numpy has such methods, which facilitates such comparision.

Categories