ó
áp7]c           @   sP   d  Z  d d l Z d e f d     YZ d   Z d d d  Z d d  Z d S(   sM   
Created on Thu May 15 16:36:05 2014

Author: Josef Perktold
License: BSD-3

i˙˙˙˙Nt   TransformRestrictionc           B   s,   e  Z d  Z d d  Z d   Z d   Z RS(   s  Transformation for linear constraints `R params = q`

    Note, the transformation from the reduced to the full parameters is an
    affine and not a linear transformation if q is not zero.


    Parameters
    ----------
    R : array_like
        Linear restriction matrix
    q : arraylike or None
        values of the linear restrictions


    Notes
    -----
    The reduced parameters are not sorted with respect to constraints.

    TODO: error checking, eg. inconsistent constraints, how?

    Inconsistent constraints will raise an exception in the calculation of
    the constant or offset. However, homogeneous constraints, where q=0, will
    can have a solution where the relevant parameters are constraint to be
    zero, as in the following example::

        b1 + b2 = 0 and b1 + 2*b2 = 0, implies that b2 = 0.

    The transformation applied from full to reduced parameter space does not
    raise and exception if the constraint doesn't hold.
    TODO: maybe change this, what's the behavior in this case?


    The `reduce` transform is applied to the array of explanatory variables,
    `exog`, when transforming a linear model to impose the constraints.

    c   
      C   s  t  j |  } |  _ | d  k	 r; t  j |  } |  _ n  | j \ } } | | |  _ |  _ | | |  _	 t  j
 |  | j j t  j j |  j  } t  j j |  \ } } | |  _ | |  _ | d  d   d  |  f } |  _ | d  d   | d   f |  _ | d  k	 ry: | j j t  j j | j j | j  | j   |  _ Wqt  j j j k
 r{}	 t d |	 f   qXn	 d |  _ d  S(   Ns8   possibly inconsistent constraints. error generated by
%ri    (   t   npt
   atleast_2dt   Rt   Nonet   asarrayt   qt   shapet   k_constrt   k_varst
   k_unconstrt   eyet   Tt   dott   linalgt   pinvt   eight   evalst   evecst   Lt
   transf_matt   solvet   constantt   LinAlgErrort
   ValueError(
   t   selfR   R   R   R	   t   mR   R   R   t   e(    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   __init__3   s&    .			#:c         C   s,   t  j |  } |  j j | j  j |  j S(   s¸  transform from the reduced to the full parameter space

        Parameters
        ----------
        params_reduced : array_like
            parameters in the transformed space

        Returns
        -------
        params : array_like
            parameters in the original space

        Notes
        -----
        If the restriction is not homogeneous, i.e. q is not equal to zero,
        then this is an affine transform.

        (   R   R   R   R   R   R   (   R   t   params_reduced(    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   expandX   s    c         C   s   t  j |  } | j |  j  S(   sż  transform from the full to the reduced parameter space

        Parameters
        ----------
        params : array_like
            parameters or data in the original space

        Returns
        -------
        params_reduced : array_like
            parameters in the transformed space

        This transform can be applied to the original parameters as well
        as to the data. If params is 2-d, then each row is transformed.

        (   R   R   R   R   (   R   t   params(    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   reducen   s    N(   t   __name__t
   __module__t   __doc__R   R   R   R    (    (    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyR       s   $%	c         C   sZ   | j  |  j  | j  } | j  | j  j  t j j | | j  |   |   } |  | S(   sĄ  find the parameters that statisfy linear constraint from unconstraint

    The linear constraint R params = q is imposed.

    Parameters
    ----------
    params : array_like
        unconstraint parameters
    Sinv : ndarray, 2d, symmetric
        covariance matrix of the parameter estimate
    R : ndarray, 2d
        constraint matrix
    q : ndarray, 1d
        values of the constraint

    Returns
    -------
    params_constraint : ndarray
        parameters of the same length as params satisfying the constraint

    Notes
    -----
    This is the exact formula for OLS and other linear models. It will be
    a local approximation for nonlinear models.

    TODO: Is Sinv always the covariance matrix?
    In the linear case it can be (X'X)^{-1} or sigmahat^2 (X'X)^{-1}.

    My guess is that this is the point in the subspace that satisfies
    the constraint that has minimum Mahalanobis distance. Proof ?

    (   R   R   R   R   R   (   R   t   SinvR   R   t   rsrt	   reduction(    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   transform_params_constraint   s    "7c         C   sa  |  } | d k r i  } n  | | } } | j | j } }	 t | |  }
 |
 j |	  } |	 j |
 j j    } t | d  r | | j	 7} n  | d k	 rŽ |
 j |  } n  d d l
 } | j
 | j    } d | k rĺ | d =n  | j | | d | | } | j d | |  } |
 j | j  j   } |
 j j | j    j |
 j j  } | | | f S(   s6  fit model subject to linear equality constraints

    The constraints are of the form   `R params = q`
    where R is the constraint_matrix and q is the vector of constraint_values.

    The estimation creates a new model with transformed design matrix,
    exog, and converts the results back to the original parameterization.


    Parameters
    ----------
    model: model instance
        An instance of a model, see limitations in Notes section
    constraint_matrix : array_like, 2D
        This is R in the linear equality constraint `R params = q`.
        The number of columns needs to be the same as the number of columns
        in exog.
    constraint_values :
        This is `q` in the linear equality constraint `R params = q`
        If it is a tuple, then the constraint needs to be given by two
        arrays (constraint_matrix, constraint_value), i.e. (R, q).
        Otherwise, the constraints can be given as strings or list of
        strings.
        see t_test for details
    start_params : None or array_like
        starting values for the optimization. `start_params` needs to be
        given in the original parameter space and are internally
        transformed.
    **fit_kwds : keyword arguments
        fit_kwds are used in the optimization of the transformed model.

    Returns
    -------
    params : ndarray ?
        estimated parameters (in the original parameterization
    cov_params : ndarray
        covariance matrix of the parameter estimates. This is a reverse
        transformation of the covariance matrix of the transformed model given
        by `cov_params()`
        Note: `fit_kwds` can affect the choice of covariance, e.g. by
        specifying `cov_type`, which will be reflected in the returned
        covariance.
    res_constr : results instance
        This is the results instance for the created transformed model.


    Notes
    -----
    Limitations:

    Models where the number of parameters is different from the number of
    columns of exog are not yet supported.

    Requires a model that implement an offset option.


    t   offseti˙˙˙˙Nt   start_params(   R   t   endogt   exogR    R    R   R   t   squeezet   hasattrR(   t   copyt   _get_init_kwdst	   __class__t   fitR   R   R   t
   cov_paramsR   (   t   modelt   constraint_matrixt   constraint_valuesR)   t   fit_kwdsR   R   R   R*   R+   t   transft   exogp_stR(   R.   t	   init_kwdst
   mod_constrt
   res_constrt   params_origR2   (    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   fit_constrainedŤ   s*    <	
'c         K   s6  |  } d d l  m } | | j  j |  } | j | j } } t | | | d | d | \ }	 }
 } | j d |	 d d d t  } |	 | j	 _
 |
 | j	 _ | j d d	  } | d	 k rŇ |
 | j | j	 _ n d
 | j	 _ t |  } | j	 j | 7_ | j	 j | 8_ | | j	 _ | | j	 _ | | j	 _ | S(   sÄ  fit_constraint that returns a results instance

    This is a development version for fit_constrained methods or
    fit_constrained as standalone function.

    It will not work correctly for all models because creating a new
    results instance is not standardized for use outside the `fit` methods,
    and might need adjustements for this.

    This is the prototype for the fit_constrained method that has been added
    to Poisson and GLM.

    i˙˙˙˙(   t
   DesignInfoR)   R6   t   maxiteri    t   warn_convergencet   cov_typet	   nonrobustN(   t   patsyR>   t
   exog_namest   linear_constraintt   coefst	   constantsR=   R1   t   Falset   _resultsR   t   cov_params_defaultt   gett   scalet   normalized_cov_paramsR   t   lent   df_residt   df_modelt   constraintsR   t   results_constrained(   R3   RQ   R)   R6   R   R>   t   lcR   R   R   t   covR;   t   resRA   R   (    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   fit_constrained_wrap
  s,    	(	   R#   t   numpyR   t   objectR    R'   R   R=   RV   (    (    (    s<   lib/python2.7/site-packages/statsmodels/base/_constraints.pyt   <module>   s
   v	)^