docs: def run_encoder(self,param_dict, encoder_dict):
          """
          run the encoder on a supplied param_dict
          """
          X_dict = {}
          Xcol_dict = {}
          # put each column of X in Xbycol_dict
          Xbycol_dict = {}
          for key in encoder_dict:
              if (key != 'twoway') and (key != 'threeway') and (key != 'trimmed_columns'):
                  encoder = encoder_dict[key]
                  param_values = param_dict[key]
                  Xsub,names = encoder(key,param_values)
                  X_dict[key] = Xsub
                  Xcol_dict[key] = names
                  for i in np.arange(0,len(names)):
                      Xbycol_dict[names[i]] = Xsub[:,i]
  
          # now do interactions
          inter_list = self._inter_list
          for interaction in inter_list:
              if 'twoway' in encoder_dict.keys():
                  encoder = encoder_dict['twoway']
                  param_name1 = interaction[0]
                  param_name2 = interaction[1]
                  col_names1 = Xcol_dict[param_name1]
                  col_names2 = Xcol_dict[param_name2]
                  X_int, names = encoder(param_name1,param_name2, \
                                         col_names1,col_names2, X_dict)
  
                  # put columns into Xbycol_dict
                  for i in np.arange(0,len(names)):
                      Xbycol_dict[names[i]] = X_int[:,i]
  
              if 'threeway' in encoder_dict.keys():
                  encoder = encoder_dict['threeway']
                  param_name1 = interaction[0]
                  param_name2 = interaction[1]
                  param_name3 = interaction[2]
                  col_names1 = Xcol_dict[param_name1]
                  col_names2 = Xcol_dict[param_name2]
                  col_names3 = Xcol_dict[param_name3]
                  X_int, names = encoder(param_name1,param_name2,param_name3, \
                                         col_names1,col_names2,col_names3, X_dict)
  
                  # put columns into Xbycol_dict
                  for i in np.arange(0,len(names)):
                      Xbycol_dict[names[i]] = X_int[:,i]
  
          # remove columns that were trimmed (if any)
          trimmed_columns = encoder_dict['trimmed_columns']
          full_columns = Xbycol_dict.keys()
          used_columns = [x for x in full_columns if x not in trimmed_columns]
          # make design matrix array
          X = []
          for name in used_columns:
              X.append(Xbycol_dict[name])
          # always add intercept column last
          X.insert(0,np.ones(np.shape(X[0])))
          used_columns.insert(0,'Intercept')
          # final design matrix
          X = np.vstack(X).T
          return X, used_columns