I am working on a simple simulator for a radio frequency application and have to deal with very low complex numbers. During the process I have a Matrix like np.array([[A,B],[C,D]], dtype=np.clongdouble)
which ensures the necessary "resolution(?)". However, I have to do stuff like
den = A B/z0 C*z0 D
s11 = A B/z0-C*z0-D)/den
s12 = 2*(A*D-B*C)/den
s21 = 2/den
s22 = (-A B/z0-C*z0 D)/den
I think Z0
is of type double
since it's calculated without numpy.
Now I wonder: Do I have to do the calculations of den
etc with numpy to achieve/keep resolution or are the 'normal' calculations sufficient enough?
CodePudding user response:
Python’s floating-point numbers are usually 64-bit floating-point numbers, nearly equivalent to np.float64.
we can actually see this from the basic types in the docs here: https://numpy.org/doc/stable/user/basics.types.html
So Python alone is satisfactory for acuracy.
CodePudding user response:
Python's complex numbers are represented "as a pair of machine-level double precision floating point numbers.". This is typically 2 x 64 = 128 bits.
NumPy's clongdouble
are represented as a pair of machine-level "extended-precision floating-point numbers".
This is typically 2 x 128 = 256 bits.
The datatype you are using from NumPy is therefore twice as much as what Python would use.
To force a number to have a specific precision, you can just cast it with np.array(..., dtype=...)
:
import numpy as np
a = 1.0j
b = np.array(a, dtype=np.clongdouble)
print(b.dtype, b.nbytes)
# complex256 32
However, you do not need to do any specific casting for the above formula to work, as the result of an operation with a higher precision and a lower precision operand would result in a higher precision result:
c = np.array(a)
print(c.dtype, c.nbytes)
# complex128 16
d = b c
print(d.dtype, d.nbytes)
# complex256 32
e = b a
print(e.dtype, e.nbytes)
# complex256 32
print(d == e)
# True
However, you may want to compute z0
with NumPy's higher precision data types, if that precision is critical to your result.
Note that this table would be your starting point to see how NumPy maps Python data types.
Note on Floating Point information
Unfortunately, you cannot easily get the information on the number of bits for the different data types that Python uses.
However, you can get some information on Python's float
with sys.float_info
:
import sys
a = 10 1.0j
print(sys.float_info)
# sys.float_info(max=1.7976931348623157e 308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
Similarly, you can get NumPy floating-point information with np.finfo()
(note that when feeding complex datatypes, you get the information on the underlying floats):
for dtype in (float, np.float_, np.double, np.cdouble, np.longdouble, np.clongdouble):
print(np.finfo(dtype))
Machine parameters for float64
---------------------------------------------------------------
precision = 15 resolution = 1.0000000000000001e-15
machep = -52 eps = 2.2204460492503131e-16
negep = -53 epsneg = 1.1102230246251565e-16
minexp = -1022 tiny = 2.2250738585072014e-308
maxexp = 1024 max = 1.7976931348623157e 308
nexp = 11 min = -max
---------------------------------------------------------------
Machine parameters for float64
---------------------------------------------------------------
precision = 15 resolution = 1.0000000000000001e-15
machep = -52 eps = 2.2204460492503131e-16
negep = -53 epsneg = 1.1102230246251565e-16
minexp = -1022 tiny = 2.2250738585072014e-308
maxexp = 1024 max = 1.7976931348623157e 308
nexp = 11 min = -max
---------------------------------------------------------------
Machine parameters for float64
---------------------------------------------------------------
precision = 15 resolution = 1.0000000000000001e-15
machep = -52 eps = 2.2204460492503131e-16
negep = -53 epsneg = 1.1102230246251565e-16
minexp = -1022 tiny = 2.2250738585072014e-308
maxexp = 1024 max = 1.7976931348623157e 308
nexp = 11 min = -max
---------------------------------------------------------------
Machine parameters for float64
---------------------------------------------------------------
precision = 15 resolution = 1.0000000000000001e-15
machep = -52 eps = 2.2204460492503131e-16
negep = -53 epsneg = 1.1102230246251565e-16
minexp = -1022 tiny = 2.2250738585072014e-308
maxexp = 1024 max = 1.7976931348623157e 308
nexp = 11 min = -max
---------------------------------------------------------------
Machine parameters for float128
---------------------------------------------------------------
precision = 18 resolution = 1e-18
machep = -63 eps = 1.084202172485504434e-19
negep = -64 epsneg = 5.42101086242752217e-20
minexp = -16382 tiny = 3.3621031431120935063e-4932
maxexp = 16384 max = 1.189731495357231765e 4932
nexp = 15 min = -max
---------------------------------------------------------------
Machine parameters for float128
---------------------------------------------------------------
precision = 18 resolution = 1e-18
machep = -63 eps = 1.084202172485504434e-19
negep = -64 epsneg = 5.42101086242752217e-20
minexp = -16382 tiny = 3.3621031431120935063e-4932
maxexp = 16384 max = 1.189731495357231765e 4932
nexp = 15 min = -max
---------------------------------------------------------------