code: def sample(self, n, mass_min=0.1, mass_max=10., steps=10000, seed=None):
          
          if seed is not None: np.random.seed(seed)
          d_mass = (mass_max - mass_min) / float(steps)
          mass = np.linspace(mass_min, mass_max, steps)
          cdf = np.insert(np.cumsum(d_mass * self.pdf(mass[1:], log_mode=False)), 0, 0.)
          cdf = cdf / cdf[-1]
          f = scipy.interpolate.interp1d(cdf, mass)
          return f(np.random.uniform(size=n))
docs: Sample initial mass values between mass_min and mass_max,
          following the IMF distribution.
  
          ADW: Should this be `sample` or `simulate`?
  
          Parameters:
          -----------
          n : number of samples to draw
          mass_min : minimum mass to sample from
          mass_max : maximum mass to sample from
          steps    : number of steps for isochrone sampling
          seed     : random seed (passed to np.random.seed)
  
          Returns:
          --------
          mass     : array of randomly sampled mass values