U
    KvfH                     @   s:   d Z ddlZddlmZ ddlmZmZ G dd dZdS )zL
Created on Sun May 10 08:23:48 2015

Author: Josef Perktold
License: BSD-3
    N   )NonePenalty)approx_fprime_csapprox_fprimec                       s   e Zd ZdZ fddZdddZd fdd	Zd fd	d
	ZdddZd fdd	Z	d fdd	Z
dddZd fdd	Zd  fdd	Z  ZS )!PenalizedMixina  Mixin class for Maximum Penalized Likelihood

    Parameters
    ----------
    args and kwds for the model super class
    penal : None or instance of Penalized function class
        If penal is None, then NonePenalty is used.
    pen_weight : float or None
        factor for weighting the penalization term.
        If None, then pen_weight is set to nobs.


    TODO: missing **kwds or explicit keywords

    TODO: do we adjust the inherited docstrings?
    We would need templating to add the penalization parameters
    c                    s   | dd | _| dd | _tt| j|| | jd krDt| j| _| jd kr\t | _d| _| j	
ddg t| dg | _| j
ddg d S )Npenal
pen_weightr   _null_drop_keys)popr   r   superr   __init__lenZendogr   Z
_init_keysextendgetattrr	   )selfargskwds	__class__ ?/tmp/pip-unpacked-wheel-2v6byqio/statsmodels/base/_penalized.pyr   !   s    

zPenalizedMixin.__init__Nc                 K   s0   |d kr,t | dr(| |}| |}nd}|S )NZ	scaletyper   )hasattrZpredictZestimate_scale)r   paramsscaler   mur   r   r   _handle_scale8   s    

zPenalizedMixin._handle_scalec                    sX   |dkr| j }tt| j|f|}|dkrT| j|f|}|d| | | j| 8 }|S )z3
        Log-likelihood of model at params
        Nr   r   )r   r   r   logliker   r   func)r   r   r   r   llfr   r   r   r   r   D   s    zPenalizedMixin.loglikec                    sj   |dkr| j }tt| j|f|}t|jd }|dkrf| j|f|}|d| | | | j| 8 }|S )z@
        Log-likelihood of model observations at params
        Nr   r   )	r   r   r   
loglikeobsfloatshaper   r   r   )r   r   r   r   r   Znobs_llfr   r   r   r   r   R   s     zPenalizedMixin.loglikeobsfdc                    sR   dkrj  fdd}|dkr0t||S |dkrFt||ddS tddS )	z4score based on finite difference derivative
        Nc                    s   j | fdi S Nr   r   pr   r   r   r   r   <lambda>h       z.PenalizedMixin.score_numdiff.<locals>.<lambda>csr"   T)Zcenteredz-method not recognized, should be "fd" or "cs")r   r   r   
ValueError)r   r   r   methodr   r   r   r'   r   score_numdiffb   s    
zPenalizedMixin.score_numdiffc                    sX   |dkr| j }tt| j|f|}|dkrT| j|f|}|d| | | j| 8 }|S )z-
        Gradient of model at params
        Nr   r   )r   r   r   scorer   r   deriv)r   r   r   r   scr   r   r   r   r.   q   s    zPenalizedMixin.scorec                    sj   |dkr| j }tt| j|f|}t|jd }|dkrf| j|f|}|d| | | | j| 8 }|S )z:
        Gradient of model observations at params
        Nr   r   )	r   r   r   	score_obsr    r!   r   r   r/   )r   r   r   r   r0   Znobs_scr   r   r   r   r1      s     zPenalizedMixin.score_obsc                    s4   dkrj  fdd}ddlm} |||S )z6hessian based on finite difference derivative
        Nc                    s   j | fdi S r#   r$   r%   r'   r   r   r(      r)   z0PenalizedMixin.hessian_numdiff.<locals>.<lambda>r   )approx_hess)r   statsmodels.tools.numdiffr2   )r   r   r   r   r   r2   r   r'   r   hessian_numdiff   s
    zPenalizedMixin.hessian_numdiffc                    s   |dkr| j }tt| j|f|}|dkr~| j|f|}| j|}|jdkrj|d| t	||  8 }n|d| | | 8 }|S )z,
        Hessian of model at params
        Nr   r   )
r   r   r   hessianr   r   Zderiv2ndimnpZdiag)r   r   r   r   Zhessr   hr   r   r   r5      s    
zPenalizedMixin.hessianc           
         s   ddl m} ddlm} t| ||fr4|ddi |dkr@d}|dkrLd}tt| jf d|i|}|dkrr|S |d	kr~d
}t	
t	|j|k d }t	
t	|j|kd }| r| j|f|}	|	S |S dS )a  minimize negative penalized log-likelihood

        Parameters
        ----------
        method : None or str
            Method specifies the scipy optimizer as in nonlinear MLE models.
        trim : {bool, float}
            Default is False or None, which uses no trimming.
            If trim is True or a float, then small parameters are set to zero.
            If True, then a default threshold is used. If trim is a float, then
            it will be used as threshold.
            The default threshold is currently 1e-4, but it will change in
            future and become penalty function dependent.
        kwds : extra keyword arguments
            This keyword arguments are treated in the same way as in the
            fit method of the underlying model class.
            Specifically, additional optimizer keywords and cov_type related
            keywords can be added.
        r   )GLMGam)GLMZmax_start_irlsNZbfgsFr,   Tg-C6?)Z*statsmodels.gam.generalized_additive_modelr9   Z+statsmodels.genmod.generalized_linear_modelr:   
isinstanceupdater   r   fitr7   Znonzeroabsr   anyZ
_fit_zeros)
r   r,   Ztrimr   r9   r:   resZ
drop_indexZ
keep_indexZres_auxr   r   r   r=      s&    zPenalizedMixin.fit)N)N)N)Nr"   )N)N)N)N)NN)__name__
__module____qualname____doc__r   r   r   r   r-   r.   r1   r4   r5   r=   __classcell__r   r   r   r   r      s   



r   )	rD   Znumpyr7   Z
_penaltiesr   r3   r   r   r   r   r   r   r   <module>   s   