docs: def generate_bootstrap_replicates(self,
                                        num_samples,
                                        mnl_obj=None,
                                        mnl_init_vals=None,
                                        mnl_fit_kwargs=None,
                                        extract_init_vals=None,
                                        print_res=False,
                                        method="BFGS",
                                        loss_tol=1e-06,
                                        gradient_tol=1e-06,
                                        maxiter=1000,
                                        ridge=None,
                                        constrained_pos=None,
                                        boot_seed=None,
                                        weights=None):
          """
          Generates the bootstrap replicates for one's given model and dataset.
  
          Parameters
          ----------
          num_samples : positive int.
              Specifies the number of bootstrap samples that are to be drawn.
          mnl_obj : an instance of pylogit.MNL or None, optional.
              Should be the MNL model object that is used to provide starting
              values for the final model being estimated. If None, then one's
              final model should be an MNL model. Default == None.
          mnl_init_vals : 1D ndarray or None, optional.
              If the model that is being estimated is not an MNL, then
              `mnl_init_val` should be passed. Should contain the values used to
              begin the estimation process for the MNL model that is used to
              provide starting values for our desired model. Default == None.
          mnl_fit_kwargs : dict or None.
              If the model that is being estimated is not an MNL, then
              `mnl_fit_kwargs` should be passed.
          extract_init_vals : callable or None, optional.
              Should accept 3 arguments, in the following order. First, it should
              accept `orig_model_obj`. Second, it should accept a pandas Series
              of estimated parameters from the MNL model. The Series' index will
              be the names of the coefficients from `mnl_names`. Thirdly, it
              should accept an int denoting the number of parameters in the final
              choice model. The callable should return a 1D ndarray of starting
              values for the final choice model. Default == None.
          print_res : bool, optional.
              Determines whether the timing and initial and final log likelihood
              results will be printed as they they are determined.
              Default `== True`.
          method : str, optional.
              Should be a valid string for scipy.optimize.minimize. Determines
              the optimization algorithm that is used for this problem.
              Default `== 'bfgs'`.
          loss_tol : float, optional.
              Determines the tolerance on the difference in objective function
              values from one iteration to the next that is needed to determine
              convergence. Default `== 1e-06`.
          gradient_tol : float, optional.
              Determines the tolerance on the difference in gradient values from
              one iteration to the next which is needed to determine convergence.
              Default `== 1e-06`.
          maxiter : int, optional.
              Determines the maximum number of iterations used by the optimizer.
              Default `== 1000`.
          ridge : int, float, long, or None, optional.
              Determines whether or not ridge regression is performed. If a
              scalar is passed, then that scalar determines the ridge penalty for
              the optimization. The scalar should be greater than or equal to
              zero. Default `== None`.
          constrained_pos : list or None, optional.
              Denotes the positions of the array of estimated parameters that are
              not to change from their initial values. If a list is passed, the
              elements are to be integers where no such integer is greater than
              `init_vals.size.` Default == None.
          boot_seed = non-negative int or None, optional.
              Denotes the random seed to be used when generating the bootstrap
              samples. If None, the sample generation process will generally be
              non-reproducible. Default == None.
          weights : 1D ndarray or None, optional.
              Allows for the calculation of weighted log-likelihoods. The weights
              can represent various things. In stratified samples, the weights
              may be the proportion of the observations in a given strata for a
              sample in relation to the proportion of observations in that strata
              in the population. In latent class models, the weights may be the
              probability of being a particular class.
  
          Returns
          -------
          None. Will store the bootstrap replicates on the
          `self.bootstrap_replicates` attribute.
          """
          print("Generating Bootstrap Replicates")
          print(time.strftime("%a %m-%d-%Y %I:%M%p"))
          sys.stdout.flush()
          # Check the passed arguments for validity.
  
          # Create an array of the observation ids
          obs_id_array = self.model_obj.data[self.model_obj.obs_id_col].values
          # Alias the alternative IDs and the Choice Array
          alt_id_array = self.model_obj.alt_IDs
          choice_array = self.model_obj.choices
  
          # Determine how many parameters are being estimated.
          num_params = self.mle_params.shape[0]
  
          # Figure out which observations are in each bootstrap sample.
          obs_id_per_sample =\
              bs.create_cross_sectional_bootstrap_samples(obs_id_array,
                                                          alt_id_array,
                                                          choice_array,
                                                          num_samples,
                                                          seed=boot_seed)
  
          # Get the dictionary of sub-dataframes for each observation id
          dfs_by_obs_id =\
              bs.create_deepcopied_groupby_dict(self.model_obj.data,
                                                self.model_obj.obs_id_col)
  
          # Create a column name for the bootstrap id columns.
          boot_id_col = "bootstrap_id"
  
          # Initialize an array to store the bootstrapped point estimates.
          point_estimates = np.empty((num_samples, num_params), dtype=float)
  
          # Get keyword arguments for final model estimation with new data.
          fit_kwargs = {"print_res": print_res,
                        "method": method,
                        "loss_tol": loss_tol,
                        "gradient_tol": gradient_tol,
                        "maxiter": maxiter,
                        "ridge": ridge,
                        "constrained_pos": constrained_pos,
                        "just_point": True}
  
          # Get the specification and name dictionary of the MNL model.
          mnl_spec = None if mnl_obj is None else mnl_obj.specification
          mnl_names = None if mnl_obj is None else mnl_obj.name_spec
  
          # Create an iterable for iteration
          iterable_for_iteration = PROGRESS(xrange(num_samples),
                                            desc="Creating Bootstrap Replicates",
                                            total=num_samples)
  
          # Iterate through the bootstrap samples and perform the MLE
          for row in iterable_for_iteration:
              # Get the bootstrapped dataframe
              bootstrap_df =\
                  bs.create_bootstrap_dataframe(self.model_obj.data,
                                                self.model_obj.obs_id_col,
                                                obs_id_per_sample[row, :],
                                                dfs_by_obs_id,
                                                boot_id_col=boot_id_col)
  
              # Go through the necessary estimation routine to bootstrap the MLE.
              current_results =\
                  retrieve_point_est(self.model_obj,
                                     bootstrap_df,
                                     boot_id_col,
                                     num_params,
                                     mnl_spec,
                                     mnl_names,
                                     mnl_init_vals,
                                     mnl_fit_kwargs,
                                     extract_init_vals=extract_init_vals,
                                     **fit_kwargs)
  
              # Store the bootstrapped point estimate.
              point_estimates[row] = current_results["x"]
  
          # Store the point estimates as a pandas dataframe
          self.bootstrap_replicates =\
              pd.DataFrame(point_estimates, columns=self.mle_params.index)
  
          # Print a 'finished' message for users
          print("Finished Generating Bootstrap Replicates")
          print(time.strftime("%a %m-%d-%Y %I:%M%p"))
          return None