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

Question:

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?

Asked By: clme

||

Answers:

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

Answered By: D.L

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 80 = 160 bits.

However, what NumPy provides for long double (as per @WarrenWeckesser’s comment) is platform and compiler dependent.

Therefore, the datatype you are using from NumPy may (or may not) have higher precision.

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

Note that the names here are a bit misleading as the number of bits refer to the alignment and not necessarily to the number of bits actually used for the data.

However, you do not need to do any specific casting for the above formulae 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

Eventually, you may want to compute z0 with NumPy’s higher precision data types, if that precision is available and it 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.

You can get some information with sys.getsizeof() but this will have information on the memory usage of the Python object, which includes Python’s book-keeping information.

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
---------------------------------------------------------------
Answered By: norok2
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.