I hope you can help with improving my code. I am defining a function which draws out elements of a certain mass, one by one, from a distribution constrained by the function imf()
, until I have used up all the mass given to the function. The code takes a very long time between 1 minute to 45 minutes depending on the input mass. I am wondering if there is any way to make this code more effective?
In the code there are certain parameters that give trivial answers such as log10(mnorm) this was done to ensure I could in the future alter the parameters. The focus of my problem is the while loop and how it draws from the distribution given by imf()
, I have identified that this part is the root course of the long performance time for the code. Any help would be greatly appreciated.
class Mod_MyFunctions:
def __init__(self):
pass
def imf(self, x, imf_type):
# Chabrier (2003) IMF for young clusters plus disk stars: lognorm and power-law tail
mnorm = 1.0
A1 = 0.158
mc = 0.079
sigma = 0.69
A2 = 4.43e-2
x0 = -1.3
if imf_type == 0:
ml = numpy.asarray((x <= log10(mnorm)).nonzero())[0]
mh = numpy.asarray((x > log10(mnorm)).nonzero())[0]
y = numpy.zeros(len(x))
for i in ml: y[i] = A1 * exp(-(x[i] - log10(mc))**2/2./sigma**2)
for i in mh: y[i] = A2 * (10.**x[i])**(x0-1)
return y
def mass_dist(self,
mmin=0.01,
mmax=100,
Mcm=10000,
imf_type=0,
SFE=0.03):
result = []
while sum(10**(np.array(result))) < SFE*Mcm:
x=numpy.random.uniform(log10(mmin), log10(mmax),size=1)
y=numpy.random.uniform(0, 1, size=1)
result.extend(x[numpy.where(y < myf.imf(x, imf_type))])
md=numpy.array(result)
return 10**md, len(md)
I have now edited
and not improved the title of the question in accordance to the recommendations hyperlinked from the help centre (& my above comment). (There's a residualimprovising
in the first sentence.) \$\endgroup\$ – greybeard Apr 28 '20 at 8:22