import numpy as np
import astropy as ap
def mass(FWHM, lumi):
abs_lumi = bhm.L_1450(lumi)
s1 = (FWHM/1000)
s2 = ((abs_lumi)/(10**44))
s = [(s1**2)*(s2**0.53)]
#mass = np.log10((s1**2)*(s2**0.53)) + 6.66 #old way, didn't work
mass = np.log10(s) + 6.66
return mass
I'm trying to use the numpy log10 function, but I keep getting an error that reads:
AttributeError: 'float' object has no attribute 'log10'
I tried putting my argument into a list (s variable), but I got the same error message. FWHM and lumi are both numbers with decimal points (I think they're called floating point numbers).
The answer to this is a bit tricky and requires a bit of knowledge how Python handles integers and how numpy coerces types. Thanks @ali_m for your comment!
Assuming 64 bit integer the biggest representable integer is 9,223,372,036,854,775,807 (see for example Wikipedia) which is roughly 10**19. But Python falls back to unlimited integer representations as soon as this value is exceeded (like in your case 10**44). But this unlimited precision type is not nativly supported by NumPy, so results will fall back to objects and these object arrays don't support all (any?) ufuncs, like np.log10.
The solution is simple: Convert this large number to a floating point number:
>>> # Negative powers will result in floats: 44 -> -44, * instead of /
>>> np.array([10, 20]) * 10**-44
array([ 1.00000000e-43, 2.00000000e-43])
>>> # you could also make the base a float: 10 -> 10.
>>> np.array([10, 20]) / 10.**44
array([ 1.00000000e-43, 2.00000000e-43])
>>> # or make the exponent a float: 44 -> 44.
>>> np.array([10, 20]) / 10**44.
array([ 1.00000000e-43, 2.00000000e-43])
>>> # manually cast the result to a float
>>> np.array([10, 20]) / float(10**44)
array([ 1.00000000e-43, 2.00000000e-43])
>>> # not working, result is an object array which cannot be used for np.log10
>>> np.array([10, 20]) / (10**(44))
array([1e-43, 2e-43], dtype=object)
>>> # ^---------that's the problem!
All you need is to change the third line in your function:
import numpy as np
def mass(FWHM, lumi):
s1 = FWHM / 1000
s2 = lumi * 10**-44 # changed line, using the first option.
s = s1**2 * s2**0.53
mass = np.log10(s) + 6.66
return mass
This works at least with all my test inputs, for example:
>>> mass(np.array([10., 20]), np.array([10., 20]))
array([-20.13 , -19.36839411])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With