Home > Net >  are numpys dtypes kept even for non-numpy multiplications/divisions/sums?
are numpys dtypes kept even for non-numpy multiplications/divisions/sums?

Time:08-18

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
---------------------------------------------------------------
  • Related