class_docstr: GLS with stochastic restrictions
  
  TheilGLS estimates the following linear model
  
  .. math:: y = X \beta + u
  
  using additional information given by a stochastic constraint
  
  .. math:: q = R \beta + v
  
  :math:`E(u) = 0`, :math:`cov(u) = \Sigma`
  :math:`cov(u, v) = \Sigma_p`, with full rank.
  
  u and v are assumed to be independent of each other.
  If :math:`E(v) = 0`, then the estimator is unbiased.
  
  Note: The explanatory variables are not rescaled, the parameter estimates
  not scale equivariant and fitted values are not scale invariant since
  scaling changes the relative penalization weights (for given \Sigma_p).
  
  Note: GLS is not tested yet, only Sigma is identity is tested
  
  Notes
  -----
  
  The parameter estimates solves the moment equation:
  
  .. math:: (X' \Sigma X + \lambda R' \sigma^2 \Sigma_p^{-1} R) b = X' \Sigma y + \lambda R' \Sigma_p^{-1} q
  
  :math:`\lambda` is the penalization weight similar to Ridge regression.
  
  If lambda is zero, then the parameter estimate is the same as OLS. If
  lambda goes to infinity, then the restriction is imposed with equality.
  In the model `pen_weight` is used as name instead of $\lambda$
  
  R does not have to be square. The number of rows of R can be smaller
  than the number of parameters. In this case not all linear combination
  of parameters are penalized.
  
  The stochastic constraint can be interpreted in several different ways:
  
   - The prior information represents parameter estimates from independent
     prior samples.
   - We can consider it just as linear restrictions that we do not want
     to impose without uncertainty.
   - With a full rank square restriction matrix R, the parameter estimate
     is the same as a Bayesian posterior mean for the case of an informative
     normal prior, normal likelihood and known error variance Sigma. If R
     is less than full rank, then it defines a partial prior.
  
  References
  ----------
  Theil Goldberger
  
  Baum, Christopher slides for tgmixed in Stata
  
  (I do not remember what I used when I first wrote the code.)
  
  Parameters
  ----------
  endog : array_like, 1-D
      dependent or endogenous variable
  exog : array_like, 1D or 2D
      array of explanatory or exogenous variables
  r_matrix : None or array_like, 2D
      array of linear restrictions for stochastic constraint.
      default is identity matrix that does not penalize constant, if constant
      is detected to be in `exog`.
  q_matrix : None or array_like
      mean of the linear restrictions. If None, the it is set to zeros.
  sigma_prior : None or array_like
      A fully specified sigma_prior is a square matrix with the same number
      of rows and columns as there are constraints (number of rows of r_matrix).
      If sigma_prior is None, a scalar or one-dimensional, then a diagonal matrix
      is created.
  sigma : None or array_like
      Sigma is the covariance matrix of the error term that is used in the same
      way as in GLS.
docstr: find penalization factor that minimizes gcv or an information criterion
  
  Parameters
  ----------
  method : str
      the name of an attribute of the results class. Currently the following
      are available aic, aicc, bic, gc and gcv.
  start_params : float
      starting values for the minimization to find the penalization factor
      `lambd`. Not since there can be local minima, it is best to try
      different starting values.
  optim_args : None or dict
      optimization keyword arguments used with `scipy.optimize.fmin`
  
  Returns
  -------
  min_pen_weight : float
      The penalization factor at which the target criterion is (locally)
      minimized.
  
  Notes
  -----
  This uses `scipy.optimize.fmin` as optimizer.
docstr_tok: ["find","penalization","factor","that","minimizes","gcv","or","an","information","criterion","Parameters","--","--","--","--","--","method",":","str","the","name","of","an","attribute","of","the","results","class",".","Currently","the","following","are","available","aic",",","aicc",",","bic",",","gc","and","gcv",".","start_params",":","float","starting","values","for","the","minimization","to","find","the","penalization","factor","`","lambd","`",".","Not","since","there","can","be","local","minima",",","it","is","best","to","try","different","starting","values",".","optim_args",":","None","or","dict","optimization","keyword","arguments","used","with","`","scipy.optimize.fmin","`","Returns","--","--","--","-","min_pen_weight",":","float","The","penalization","factor","at","which","the","target","criterion","is","(","locally",")","minimized",".","Notes","--","--","-","This","uses","`","scipy.optimize.fmin","`","as","optimizer","."]
code: def select_pen_weight(
      self, method="aicc", start_params=1.0, optim_args=None
  ):
      """find penalization factor that minimizes gcv or an information criterion
  
      Parameters
      ----------
      method : str
          the name of an attribute of the results class. Currently the following
          are available aic, aicc, bic, gc and gcv.
      start_params : float
          starting values for the minimization to find the penalization factor
          `lambd`. Not since there can be local minima, it is best to try
          different starting values.
      optim_args : None or dict
          optimization keyword arguments used with `scipy.optimize.fmin`
  
      Returns
      -------
      min_pen_weight : float
          The penalization factor at which the target criterion is (locally)
          minimized.
  
      Notes
      -----
      This uses `scipy.optimize.fmin` as optimizer.
      """
      if optim_args is None:
          optim_args = {}
  
      # this does not make sense, since number of parameters stays unchanged
      # information criteria changes if we use df_model based on trace(hat_matrix)
      # need leave-one-out, gcv; or some penalization for weak priors
      # added extra penalization for lambd
      def get_ic(lambd):
          # this can be optimized more
          # for pure Ridge we can keep the eigenvector decomposition
          return getattr(self.fit(lambd), method)
  
      from scipy import optimize
  
      lambd = optimize.fmin(get_ic, start_params, **optim_args)
      return lambd
  
imports: from statsmodels.compat.python import lrange
  import numpy
  from statsmodels.tools.decorators import cache_readonly
  from statsmodels.regression.linear_model import OLS, GLS, RegressionResults
  from statsmodels.regression.feasible_gls import atleast_2dcols
label_desc: Use image node_id 3 for calling the TheilGLS obj's underlying member method code with example usage: obj.select_pen_weight(method, start_params, optim_args) and returns: lambd, getattr