Precision of awkward array #3218
-
Version of Awkward Arrayawkward1 Description and code to reproduceDear experts,
However, upon extracting the values from the array, the type is
i.e. 8*8=64bits, which is what I want. Many thanks for your help. Cheers, Roy |
Beta Was this translation helpful? Give feedback.
Replies: 18 comments
-
Hi @roy-brener-cern , Awkward arrays are immutable. I think if you want to convert a >>> narr = np.array([85.5, 69.1], dtype = np.float32)
>>> array = ak.from_numpy(narr)
>>> array
<Array [85.5, 69.1] type='2 * float32'>
>>> array_64 = array*np.float64(1.0)
>>> array_64
<Array [85.5, 69.1] type='2 * float64'> |
Beta Was this translation helpful? Give feedback.
-
Hi @ianna,
What do you think? |
Beta Was this translation helpful? Give feedback.
-
is it specific to awkward version 1? Have you tried using awkward v2? |
Beta Was this translation helpful? Give feedback.
-
Hi, yes indeed, it was a version issue. Seems to be giving the full float64 w/ version 2. |
Beta Was this translation helpful? Give feedback.
-
Please, let me know if I can close the issue. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Hi @ianna, |
Beta Was this translation helpful? Give feedback.
-
Hi @ianna,
naturally only on the floating variables ( |
Beta Was this translation helpful? Give feedback.
-
Hi @roy-brener-cern , However, please, check that the required calculations in v2 do not give you a
|
Beta Was this translation helpful? Give feedback.
-
Hi @ianna, |
Beta Was this translation helpful? Give feedback.
-
Hi @roy-brener-cern , Perhaps, this answer in the discussions is what you are looking for #1342? |
Beta Was this translation helpful? Give feedback.
-
You can call ak.values_astype on your input data as the first step. If the input to the vector calculation is (This isn't a version issue—Awkward Arrays have always supported all numerical types. Some of these functions are new or have changed names since Awkward 1—I've written all of the Awkward 2 names above.) |
Beta Was this translation helpful? Give feedback.
-
Dear @ianna and @jpivarski,
i.e. the desired, original value is After applying
Why aren't they equal? Shouldn't they be..? Cheers, Roy |
Beta Was this translation helpful? Give feedback.
-
No, floating-point numbers cannot be compared the same way as integers. |
Beta Was this translation helpful? Give feedback.
-
Hi @ianna, |
Beta Was this translation helpful? Give feedback.
-
Hi @roy-brener-cern , It's the way the IEEE 754 standard defines them. Please, check https://indico.cern.ch/event/1287965/contributions/5411743/attachments/2687210/4662439/Floating-point%20Arithmetic%20is%20not%20Real.pdf for a longish explanation. |
Beta Was this translation helpful? Give feedback.
-
Hi @ianna, |
Beta Was this translation helpful? Give feedback.
-
The key thing is that it's the file itself that has 32-bit floats. When you look at Side-note: Python's root [0] TMath::Pi()
(double) 3.1415927
root [1] std::cout << TMath::Pi() << std::endl;
3.14159
root [2] printf("%g\n", TMath::Pi());
3.14159 versus >>> np.pi
3.141592653589793
>>> print(np.pi)
3.141592653589793
>>> print("%g" % np.pi) # explicitly choose to use C's %g
3.14159 If you convert the 32-bit number from your file into a 64-bit number and then print that, it will be the closest decimal expansion to the closest 64-bit representation of the 32-bit representation. If you needed the original data to have 64-bit precision, that was lost when the file was made, but up-converting it from 32-bit to 64-bit and then doing all computations in 64-bit is the best you can make of the situation. (I doubt that you really needed the original data to be 64-bit, given experimental uncertainties in Despite the number of digits in " >>> original = np.float32(-1.38058340549468994)
>>> original
-1.3805834
>>> np.nextafter(original, np.float32(np.inf)) # the next float32 in the direction of ∞
-1.3805833
>>> np.nextafter(original, np.float32(-np.inf)) # the next float32 in the direction of -∞
-1.3805835 The >>> as64bit = np.float64(original)
>>> as64bit
-1.38058340549469 the base-2 zeros that were padded to the significand are, in base-10, " >>> np.nextafter(as64bit, np.inf)
-1.3805834054946897
>>> np.nextafter(as64bit, -np.inf)
-1.3805834054946902 (The 64-bit precision is in the last digit shown.) The >>> print("%.17f" % as64bit)
-1.38058340549468994 just as we can have it make up arbitrarily many digits past the actual precision of the number: >>> print("%.25f" % as64bit)
-1.3805834054946899414062500 But Python's default |
Beta Was this translation helpful? Give feedback.
-
Dear @ianna and @jpivarski, |
Beta Was this translation helpful? Give feedback.
You can call ak.values_astype on your input data as the first step. If the input to the vector calculation is
np.float64
, then all of the intermediate steps will be, too. If you want to make some fieldsnp.float64
while keeping other fields asnp.float32
or integers type, then you can construct a full type expression and use ak.enforce_type. The string (DataShape) representation of types is generally easier to work with, andstr
and ak.types.from_datashape will help you convert between strings and type objects.(This isn't a version issue—Awkward Arrays have always supported all numerical types. Some of these functions are new or have changed names since Awkward 1—I've written all of the A…