
p7]c        	   @   s  d  Z  d d l m Z d d l m Z m Z d d l m Z d d l Z	 d d l
 Z d d l m Z d d l m Z d d l m Z d	   Z d
   Z d e d  Z d   Z d   Z d d d d d d d d d  Z d d  Z d d e d d  Z e d  Z d e e  f d     YZ d e f d     YZ d e f d     YZ  d e f d     YZ! d e f d      YZ" d! e f d"     YZ# d# e e  f d$     YZ$ d% e$ f d&     YZ% d' e$ f d(     YZ& d) e$ f d*     YZ' d+ e$ f d,     YZ( d- e$ f d.     YZ) d S(/   s   
Spline and other smoother classes for Generalized Additive Models

Author: Luca Puggini
Author: Josef Perktold

Created on Fri Jun  5 16:32:00 2015
i(   t   division(   t   ABCMetat   abstractmethod(   t   with_metaclassN(   t   dmatrix(   t   _get_all_sorted_knots(   t   transf_constraintsc         C   s;   | d } |  j    } |  j   } t j | | |  } | S(   Ni   (   t   mint   maxt   npt   linspace(   t   xt   dft   n_knotst   x_mint   x_maxt   knots(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   _equally_spaced_knots   s
    
c         C   sc   t  j |  } t  j g  | j d d  D] } t  j |  d |  ^ q(  } | j | j d d S(   Nt   ordert   Cid   (   R	   t   asarrayt   ravelt
   percentilet   reshapet   shape(   R   t   probst   probt	   quantiles(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   _R_compat_quantile"   s    	5t   allc         C   s  y d d l  m } Wn t k
 r3 t d   n Xt j t j | d t  } | j d k sg t  | j	   t
 |  } t j |   }  |  j d k r |  j d d k r |  d  d   d f }  n  |  j d k s t  t j |   t j |  k  st j |   t j |  k r't d   n  d t
 |  } t |  | d | } | d k rt j |  j d | f d t } | }	 n  | d k rt j |  j d | f d t }
 |
 }	 n  | d k rt j |  j d | f d t } | }	 n  x t |  D] } t j | | f  } d | | | <| } | d k rh| |  | | | f  | d  d   | f <n  | d k r| |  | | | f d
 d |
 d  d   | f <n  | d k r| |  | | | f d
 d | d  d   | f <qqW| d	 k r| |
 | f S|	 Sd  S(   Ni(   t   splevs#   spline functionality requires scipyt   dtypei   i   i    sk   some data points fall outside the outermost knots, and I'm not sure how to handle them. (Patches accepted!)R   t   der(   R   i    (   R   i   (   R   i   (   R   i    (   R   i   (   R   i   (   t   scipy.interpolateR   t   ImportErrorR	   t
   atleast_1dR   t   floatt   ndimt   AssertionErrort   sortt   intR   R   R   t   NotImplementedErrort   lent   emptyt   ranget   zeros(   R   R   t   degreet   derivt   include_interceptR   t   k_constt   n_basest   basist   rett
   der1_basist
   der2_basist   it   coefst   ii(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   _eval_bspline_basis-   sL    
"<"	"	"	+15c   
      C   s   | d } | | } t  j |   } t  j |   } t  j d d | d  d d !} t |  |  } t  j | | g | | f  }	 |	 | | | f S(   Ni   i    i   i(   R	   R   R   R
   R   t   concatenate(
   R   R   R.   R   t   n_inner_knotst   lower_boundt   upper_boundt   knot_quantilest   inner_knotst	   all_knots(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   compute_all_knotsp   s    

 c         C   sF   t  |  | |  \ } } } } t |  | |  \ } } } | | | f S(   s    make a spline basis for x (   RB   R:   (   R   R   R.   RA   t   _R3   t	   der_basisR6   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   make_bsplines_basis|   s    i   t   quantilec         C   su  | d k	 r | S|  j   } |  j   }	 | d k  rJ t d | f   n  t |  | k rr t d | f   n  | d k r | d k r t d   n  | d }
 | d k	 r| |
 } | d k  r t d | | | | f   n  | d k	 r+t |  | k rt d | | | t |  f   qq| d k rit j d d | d	  d d
 !} t |  |  } q| d k rt j d d | d	  d d
 !} | | |	 | } | d | d } qt d   n  | d k	 r| } n  | d k rt j |   } n  | d k rt j |   } n  | | k rAt d | | f   n  t j	 |  } | j
 d k rnt d   n  t j | | k   rt d | | | k  | f   n  t j | | k  rt d | | | k | f   n  | d k rHt j d |
 d  | } | d | d d d
  } | d
 | } t j | | | f  } n t j | | g |
 | f  } | j   | S(   s8  knots for use in B-splines

    There are two main options for the knot placement

    - quantile spacing with multiplicity of boundary knots
    - equal spacing extended to boundary or exterior knots

    The first corresponds to splines as used by patsy. the second is the
    knot spacing for P-Splines.

    i    s&   degree must be greater than 0 (not %r)s"   degree must be an integer (not %r)s   must specify either df or knotsi   s/   df=%r is too small for degree=%r; must be >= %ssA   df=%s with degree=%r implies %s knots, but %s knots were providedRF   i   it   equals   incorrect option for spacings#   lower_bound > upper_bound (%r > %r)s   knots must be 1 dimensionals1   some knot values (%s) fall below lower bound (%r)s1   some knot values (%s) fall above upper bound (%r)N(   t   NoneR   R   t
   ValueErrorR(   R*   R	   R
   R   R   R%   t   anyt   arangeR;   R'   (   R   R   R   R.   t   spacingR=   R>   RA   R   R   R   R<   R?   R@   t   gridt
   diff_knotst   diffst   lower_knotst   upper_knots(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   get_knots_bsplines   sz    

  	
c         C   s   | d } t  j |   }  t  j |  | } t  j |   } | d d  d f | } t  j |  d d  d f | j   |  d g f  } | S(   sm   add points to each subinterval defined by knots

    inserts k_points between each two consecutive knots
    i   Ni(   R	   t   uniqueRK   t   diffRH   R;   R   (   R   t   k_pointst   dxit   dxkt   dxR   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   _get_integration_points   s    
6i   i   c   
      C   s   d d l  m } |  j } t | d d } | d k rU |  j | d | d | } n | } | | d d  d d  d f | d d  d d d  f | d d	 }	 |	 S(
   s   
    Approximate integral of cross product of second derivative of smoother

    This uses scipy.integrate simps to compute an approximation to the
    integral of the smoother derivative cross-product at knots plus k_points
    in between knots.
    i(   t   simpsRU   i   R/   t   skip_ctransfNt   axisi    (   t   scipy.integrateRZ   R   RY   RH   t	   transform(
   t   smootherRU   t   integration_pointsR[   R/   RZ   R   R   t   d2t   covd2(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   get_covder2   s    		Kc   	      C   s  | r d } n d } t  |   } t j d | | d | f  } t j d | | d | f  } t j d | | d | f  } x t | | d  D]x } |  | | d d  | | f <| |  | d | d d  | | f <| | d |  | d | d d  | | f <q W| | | f S(   sj   
    given a vector x returns poly=(1, x, x^2, ..., x^degree)
    and its first and second derivative
    i    i   R   Ni   (   R*   R	   R-   R,   (	   R   R.   t	   interceptt   startt   nobsR3   RD   R6   R7   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   make_poly_basis  s    	   &2t   UnivariateGamSmootherc           B   s,   e  Z d  Z d d d  Z e d    Z RS(   s+   Base Class for single smooth component
    R   c         C   s  | |  _  | |  _ | |  _ t |  d |  _ |  _ |  j   } | d k rr | d j d  d  d  d   f } n  | d  k	 r t	 | t
  r t |  } | |  _ n t |  d  s d  |  _ n  | \ |  _ |  _ |  _ |  _ |  j d  k	 r|  j } | d d  k	 r | d j |  |  _ n  | d d  k	 rI| d j |  |  _ n  | d d  k	 rr| d j |  |  _ n  | d d  k	 r| j j | d  j |  |  _ qn  |  j j d |  _ g  t |  j  D] } |  j d t
 |  ^ q|  _ d  S(   Ni   t   centeri    t   ctransfi   i   t   _s(   R   t   constraintst   variable_nameR*   Rf   t   k_variablest!   _smooth_basis_for_single_variablet   meanRH   t
   isinstancet   strR   Rj   t   hasattrR3   RD   R6   t   cov_der2t   dott   TR   t	   dim_basisR,   t	   col_names(   t   selfR   Rl   Rm   t   base4Rj   R7   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   __init__2  s4    			&	(c         C   s   d  S(   N(    (   Ry   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo   V  s    N(   t   __name__t
   __module__t   __doc__RH   R{   R   Ro   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRh   /  s   $t   UnivariateGenericSmootherc           B   s#   e  Z d  Z d d  Z d   Z RS(   s$   Generic single smooth component
    R   c         C   sD   | |  _  | |  _ | |  _ | |  _ t t |   j | d | d  S(   NRm   (   R3   RD   R6   Rt   t   superR   R{   (   Ry   R   R3   RD   R6   Rt   Rm   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{   ^  s    				c         C   s   |  j  |  j |  j |  j f S(   N(   R3   RD   R6   Rt   (   Ry   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo   h  s    (   R|   R}   R~   R{   Ro   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   [  s   	t   UnivariatePolynomialSmootherc           B   s#   e  Z d  Z d d  Z d   Z RS(   s'   polynomial single smooth component
    R   c         C   s)   | |  _  t t |   j | d | d  S(   NRm   (   R.   R   R   R{   (   Ry   R   R.   Rm   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{   o  s    	c         C   s7  t  j d |  j |  j f  } t  j d |  j |  j f  } t  j d |  j |  j f  } x t |  j  D] } | d } |  j | | d d  | f <| |  j | d | d d  | f <| d k r | | d |  j | d | d d  | f <qj d | d d  | f <qj Wt  j | j |  } | | | | f S(   sv   
        given a vector x returns poly=(1, x, x^2, ..., x^degree)
        and its first and second derivative
        R   i   Ni   i    (   R	   R-   Rf   R.   R,   R   Ru   Rv   (   Ry   R3   RD   R6   R7   t   dgRt   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo   t  s    
%0(   R|   R}   R~   R{   Ro   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   l  s   t   UnivariateBSplinesc           B   s>   e  Z d  Z d e d d d d  Z d   Z d e d  Z RS(   sZ  B-Spline single smooth component

    This creates and holds the B-Spline basis function for one
    component.

    Parameters
    ----------
    x : array, 1-D
        underlying explanatory variable for smooth terms.
    df : int
        numer of basis functions or degrees of freedom
    degree : int
        degree of the spline
    include_intercept : bool
        If False, then the basis functions are transformed so that they
        do not include a constant. This avoids perfect collinearity if
        a constant or several components are included in the model.
    constraints : None, string or array
        Constraints are used to transform the basis functions to satisfy
        those constraints.
        `constraints = 'center'` applies a linear transform to remove the
        constant and center the basis functions.
    variable_name : None or str
        The name for the underlying explanatory variable, x, used in for
        creating the column and parameter names for the basis functions.
    covder2_kwds : None or dict
        options for computing the penalty matrix from the second derivative
        of the spline.
    knot_kwds : None or list of dict
        option for the knot selection.
        By default knots are selected in the same way as in patsy, however the
        number of knots is independent of keeping or removing the constant.
        Interior knot selection is based on quantiles of the data and is the
        same in patsy and mgcv. Boundary points are at the limits of the data
        range.
        The available options use with `get_knots_bsplines` are

        - knots : None or array
          interior knots
        - spacing : 'quantile' or 'equal'
        - lower_bound : None or float
          location of lower boundary knots, all boundary knots are at the same
          point
        - upper_bound : None or float
          location of upper boundary knots, all boundary knots are at the same
          point
        - all_knots : None or array
          If all knots are provided, then those will be taken as given and
          all other options will be ignored.

    i   R   c   	      K   sz   | |  _  | |  _ | |  _ t | d | d | | |  _ | d  k	 rK | n i  |  _ t t |   j	 | d | d | d  S(   NR.   R   Rl   Rm   (
   R.   R   R0   RR   R   RH   t   covder2_kwdsR   R   R{   (	   Ry   R   R   R.   R0   Rl   Rm   R   t	   knot_kwds(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     s    				c         C   sU   t  |  j |  j |  j d |  j \ } } } t |  d t |  j } | | | | f S(   NR0   R[   (   R:   R   R   R.   R0   Rc   t   TrueR   (   Ry   R3   RD   R6   Rt   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo     s    i    c         C   s}   | d k r |  j } n  t | |  j |  j d | d |  j } t |  d d  } | d k	 ry | ry | j |  j  } n  | S(   s  create the spline basis for new observations

        The main use of this stateful transformation is for prediction
        using the same specification of the spline basis.

        Parameters
        ----------
        x_new : array
            observations of the underlying explanatory variable
        deriv : int
            which derivative of the spline basis to compute
            This is an options for internal computation.
        skip_ctransf : bool
            whether to skip the constraint transform
            This is an options for internal computation.

        Returns
        -------
        basis : ndarray
            design matrix for the spline basis for given ``x_new``
        R/   R0   Rj   N(	   RH   R   R:   R   R.   R0   t   getattrRu   Rj   (   Ry   t   x_newR/   R[   t   exogRj   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR^     s    N(   R|   R}   R~   t   FalseRH   R{   Ro   R^   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   3
	t   UnivariateCubicSplinesc           B   s\   e  Z d  Z d
 d d d  Z e d  Z d   Z d   Z d
 d  Z	 d   Z
 d	   Z RS(   si   Cubic Spline single smooth component

    Cubic splines as described in the wood's book in chapter 3
    t   domainR   c         C   so   d |  _  | |  _ | |  _ |  j | d t |  _ } t | |  |  _ t t	 |   j
 | d | d | d  S(   Ni   t
   initializeRl   Rm   (   R.   R   t   transform_data_methodt   transform_dataR   R   R   R   R   R   R{   (   Ry   R   R   Rl   R^   Rm   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     s    			c         C   s   |  j  } | d  k r | S| t k r | d k rX | j d  |  _ | j d  |  _ nA t | t  r | d |  _ | d |  _ d |  _  n t	 d   |  j |  j |  _
 n  |  j  d k r | |  j |  j
 } | St	 d   d  S(   NR   i    i   s-   transform should be None, 'domain' or a tuples   incorrect transform_data_method(   R   RH   R   R   t
   domain_lowR   t
   domain_uppRq   t   tupleRI   t   domain_diff(   Ry   R   R   t   tm(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s"    	c         C   sD  |  j    d  d   d  d  f } |  j d k s | d  d   d d   f j d  |  _ | d  d   d d   f c |  j 8<n t j | j d  |  _ |  j   d  d  d  d  f } |  j d k s t j d t j	 t j
 |  d d  } n t j | j d  } |  j d k r+| d } n  | |  _ | d  d  | f S(   Nit   nonei   i    R\   s   no-const(   t
   _splines_xRl   Rp   t   transf_meanR	   R-   R   t
   _splines_st   diagR   t   abst   eyeRj   RH   (   Ry   R3   t   sRj   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo   %  s    "((".	c         C   sn   | d d d	 | d
 d d d } t  j | |  d d d t  j | |  d d d d } | | S(   Ni   i   i   i   i   i   g      8@g      ?gUUUUUU?g      ?gUUUUUU?g      ?g      ?g      ?gݝ?(   R	   R   (   Ry   R   t   zt   p1t   p2(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   _rk=  s    &5c   
      C   s   | d  k r |  j } n  t |  j  d } | j d } t j d | | f  } | | d  d   d f <x` t |  D]R \ } } xC t |  j  D]2 \ } } |  j | |  }	 |	 | | | d f <q Wqs W| S(   Ni   i    R   i   (	   RH   R   R*   R   R   R	   t   onest	   enumerateR   (
   Ry   R   t	   n_columnsRf   R3   R7   t   xit   jt   xkjt   s_ij(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   D  s    c         C   s   t  |  j  d } t j d | | f  } xa t |  j  D]P \ } } xA t |  j  D]0 \ } } |  j | |  | | d | d f <qW Wq; W| S(   Ni   R   (   R*   R   R	   R-   R   R   (   Ry   t   qR   R7   t   x1R   t   x2(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   R  s    ,c         C   sq   |  j  | d t } |  j |  } | d  d   d d   f c |  j 8<|  j d  k	 rm | j |  j  } n  | S(   NR   i   (   R   R   R   R   Rj   RH   Ru   (   Ry   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR^   Z  s    %N(   R|   R}   R~   RH   R{   R   R   Ro   R   R   R   R^   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   			t   UnivariateCubicCyclicSplinesc           B   sA   e  Z d  Z d d d  Z d   Z d   Z d   Z d   Z RS(   s  cyclic cubic regression spline single smooth component

    This creates and holds the Cyclic CubicSpline basis function for one
    component.

    Parameters
    ----------
    x : array, 1-D
        underlying explanatory variable for smooth terms.
    df : int
        numer of basis functions or degrees of freedom
    degree : int
        degree of the spline
    include_intercept : bool
        If False, then the basis functions are transformed so that they
        do not include a constant. This avoids perfect collinearity if
        a constant or several components are included in the model.
    constraints : None, string or array
        Constraints are used to transform the basis functions to satisfy
        those constraints.
        `constraints = 'center'` applies a linear transform to remove the
        constant and center the basis functions.
    variable_name : None or str
        The name for the underlying explanatory variable, x, used in for
        creating the column and parameter names for the basis functions.
    R   c         C   sS   d |  _  | |  _ | |  _ t | |  |  _ t t |   j | d | d | d  S(   Ni   Rl   Rm   (   R.   R   R   R   R   R   R   R{   (   Ry   R   R   Rl   Rm   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{   ~  s    			c      
   C   s   t  d t |  j  d i |  j d 6 } | j |  _ |  j d d } t |  j d | d d  d d  d	 d  } |  j |  \ } } |  j | |  } | d  d  | f S(
   Ns	   cc(x, df=s   ) - 1R   i   i   R<   R@   R=   R>   (	   R   Rr   R   R   t   design_infoR   RH   t   _get_b_and_dt   _get_s(   Ry   R3   R<   RA   t   bt   dR   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyRo     s    *c         C   s  | d | d  } | j  d } t j | | f  } t j | | f  } | | d | d d | d <| | d d | d | d f <| | d d | | d d f <d | d d | | d | d	 <d | | d | d | d f <d | | d | | d d f <x t d |  D] } | | d | | d | | | f <| | d d | | | d f <| | d d | | d | f <d | | d d | | | | | f <d | | d | | | d f <d | | d | | d | f <qW| | f S(
   sB  Returns mapping of cyclic cubic spline values to 2nd derivatives.

        .. note:: See 'Generalized Additive Models', Simon N. Wood, 2006,
           pp 146-147

        Parameters
        ----------
        knots : ndarray
            The 1-d array knots used for cubic spline parametrization,
            must be sorted in ascending order.

        Returns
        -------
        b, d: ndarrays
            arrays for mapping cyclic cubic spline values at knots to
            second derivatives.
            penalty matrix is equal to ``s = d.T.dot(b^-1).dot(d)``
        i   ii    g      @g      @g      g      ?(   i    i    (   i    i    (   t   sizeR	   R-   R,   (   Ry   R   t   ht   nR   R   R7   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s$      "  $  ( $c         C   s%   | j  j t j j |   j |  S(   N(   Rv   Ru   R	   t   linalgt   inv(   Ry   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s    c         C   sA   t  |  j i | d 6 } |  j d  k	 r= | j |  j  } n  | S(   NR   (   R   R   Rj   RH   Ru   (   Ry   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR^     s    N(	   R|   R}   R~   RH   R{   Ro   R   R   R^   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   c  s   		/	t   AdditiveGamSmootherc           B   s5   e  Z d  Z d e d  Z e d    Z d   Z RS(   s.   Base class for additive smooth components
    c   
      K   sK  t  | t j  r$ | j j   } n' t  | t j  rE | j g } n d  } t j	 |  } | j
 d k r | j   |  _ t |  d f |  j _ n	 | |  _ |  j j \ |  _ |  _ t  | t  r | g |  j |  _ n	 | |  _ | d  k r8| d  k	 r| |  _ qAg  t |  j  D] } d t |  ^ q|  _ n	 | |  _ |  j   |  _ t j t d   |  j D   |  _ |  j j d |  _ g  |  j D] } | j ^ q|  _ g  |  _ x$ |  j D] } |  j j | j  qWg  |  _  d } x[ |  j D]P } t j! t" g |  j  }	 t# |	 | | j | +| | j } |  j  j$ |	  qWd  S(   Ni   R   c         s   s   |  ] } | j  Vq d  S(   N(   R3   (   t   .0R_   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pys	   <genexpr>  s   i    (%   Rq   t   pdt	   DataFramet   columnst   tolistt   Seriest   nameRH   R	   R   R%   t   copyR   R*   R   Rf   Rn   t   boolR0   t   variable_namesR,   Rr   t   _make_smoothers_listt	   smootherst   hstackt   listR3   Rw   Rt   t   penalty_matricesRx   t   extendt   maskt   arrayR   R   t   append(
   Ry   R   R   R0   t   kwargst
   data_namesR7   R_   t   last_columnR   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     sH    		/			c         C   s   d  S(   N(    (   Ry   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s    c            s5   t  j t    f d   t   j  D   } | S(   s  create the spline basis for new observations

        The main use of this stateful transformation is for prediction
        using the same specification of the spline basis.

        Parameters
        ----------
        x_new: array
            observations of the underlying explanatory variable

        Returns
        -------
        basis : ndarray
            design matrix for the spline basis for given ``x_new``.

        c         3   s5   |  ]+ }   j  | j  d  d   | f  Vq d  S(   N(   R   R^   (   R   R7   (   Ry   R   (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pys	   <genexpr>  s   (   R	   R   R   R,   Rn   (   Ry   R   R   (    (   Ry   R   s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR^     s    N(	   R|   R}   R~   RH   R   R{   R   R   R^   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   4t   GenericSmoothersc           B   s    e  Z d  Z d   Z d   Z RS(   s9   generic class for additive smooth components for GAM
    c         C   s)   | |  _  t t |   j | d d  d  S(   NR   (   R   R   R   R{   RH   (   Ry   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{   !  s    	c         C   s   |  j  S(   N(   R   (   Ry   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   %  s    (   R|   R}   R~   R{   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   	t   PolynomialSmootherc           B   s#   e  Z d  Z d d  Z d   Z RS(   s+   additive polynomial components for GAM
    c         C   s)   | |  _  t t |   j | d | d  S(   NR   (   t   degreesR   R   R{   (   Ry   R   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{   ,  s    	c         C   sj   g  } x] t  |  j  D]L } t |  j d  d   | f d |  j | d |  j | } | j |  q W| S(   NR.   Rm   (   R,   Rn   R   R   R   R   R   (   Ry   R   t   vt   uv_smoother(    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   1  s    N(   R|   R}   R~   RH   R{   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   )  s   t   BSplinesc           B   s,   e  Z d  Z e d d d d  Z d   Z RS(   sb  additive smooth components using B-Splines

    This creates and holds the B-Spline basis function for several
    components.

    Parameters
    ----------
    x : array_like, 1-D or 2-D
        underlying explanatory variable for smooth terms.
        If 2-dimensional, then observations should be in rows and
        explanatory variables in columns.
    df :  int
        numer of basis functions or degrees of freedom
    degree : int
        degree of the spline
    include_intercept : bool
        If False, then the basis functions are transformed so that they
        do not include a constant. This avoids perfect collinearity if
        a constant or several components are included in the model.
    constraints : None, string or array
        Constraints are used to transform the basis functions to satisfy
        those constraints.
        `constraints = 'center'` applies a linear transform to remove the
        constant and center the basis functions.
    variable_names : None or list of strings
        The names for the underlying explanatory variables, x used in for
        creating the column and parameter names for the basis functions.
        If ``x`` is a pandas object, then the names will be taken from it.
    knot_kwds : None or list of dict
        option for the knot selection.
        By default knots are selected in the same way as in patsy, however the
        number of knots is independent of keeping or removing the constant.
        Interior knot selection is based on quantiles of the data and is the
        same in patsy and mgcv. Boundary points are at the limits of the data
        range.
        The available options use with `get_knots_bsplines` are

        - knots : None or array
          interior knots
        - spacing : 'quantile' or 'equal'
        - lower_bound : None or float
          location of lower boundary knots, all boundary knots are at the same
          point
        - upper_bound : None or float
          location of upper boundary knots, all boundary knots are at the same
          point
        - all_knots : None or array
          If all knots are provided, then those will be taken as given and
          all other options will be ignored.


    Attributes
    ----------
    smoothers : list of univariate smooth component instances
    basis : design matrix, array of spline bases columns for all components
    penalty_matrices : list of penalty matrices, one for each smooth term
    dim_basis : number of columns in the basis
    k_variables : number of smooth components
    col_names : created names for the basis columns

    There are additional attributes about the specification of the splines
    and some attributes mainly for internal use.

    Notes
    -----
    A constant in the spline basis function can be removed in two different
    ways.
    The first is by dropping one basis column and normalizing the
    remaining columns. This is obtained by the default
    ``include_intercept=False, constraints=None``
    The second option is by using the centering transform which is a linear
    transformation of all basis functions. As a consequence of the
    transformation, the B-spline basis functions do not have locally bounded
    support anymore. This is obtained ``constraints='center'``. In this case
    ``include_intercept`` will be automatically set to True to avoid
    dropping an additional column.


    c         C   s_   | |  _  | |  _ | |  _ | |  _ | d k r9 t } n  t t |   j | d | d | d  S(   NRi   R0   R   (   R   t   dfsR   Rl   R   R   R   R{   (   Ry   R   R   R.   R0   Rl   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     s    					c         C   s   g  } x t  |  j  D] } |  j r2 |  j | n i  } t |  j d  d   | f d |  j | d |  j | d |  j | d |  j d |  j	 | | } | j
 |  q W| S(   NR   R.   R0   Rl   Rm   (   R,   Rn   R   R   R   R   R   R0   Rl   R   R   (   Ry   R   R   t   kwdsR   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s    	N(   R|   R}   R~   R   RH   R{   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR   <  s   Ot   CubicSplinesc           B   s)   e  Z d  Z d d d d  Z d   Z RS(   s   additive smooth components using cubic splines as in Wood 2006.

    Note, these splines do NOT use the same spline basis as
    ``Cubic Regression Splines``.

    Ri   R   c         C   sA   | |  _  | |  _ | |  _ t t |   j | d | d | d  S(   NRl   R   (   R   Rl   R^   R   R   R{   (   Ry   R   R   Rl   R^   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     s
    			c         C   s|   g  } xo t  |  j  D]^ } t |  j d  d   | f d |  j | d |  j d |  j d |  j | } | j |  q W| S(   NR   Rl   R^   Rm   (	   R,   Rn   R   R   R   Rl   R^   R   R   (   Ry   R   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s    &		N(   R|   R}   R~   RH   R{   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   t   CyclicCubicSplinesc           B   s&   e  Z d  Z d d d  Z d   Z RS(   s6  additive smooth components using cyclic cubic regression splines

    This spline basis is the same as in patsy.

    Parameters
    ----------
    x : array_like, 1-D or 2-D
        underlying explanatory variable for smooth terms.
        If 2-dimensional, then observations should be in rows and
        explanatory variables in columns.
    df :  int
        numer of basis functions or degrees of freedom
    constraints : None, string or array
        Constraints are used to transform the basis functions to satisfy
        those constraints.
    variable_names : None or list of strings
        The names for the underlying explanatory variables, x used in for
        creating the column and parameter names for the basis functions.
        If ``x`` is a pandas object, then the names will be taken from it.

    c         C   s2   | |  _  | |  _ t t |   j | d | d  S(   NR   (   R   Rl   R   R   R{   (   Ry   R   R   Rl   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR{     s    		c      
   C   ss   g  } xf t  |  j  D]U } t |  j d  d   | f d |  j | d |  j d |  j | } | j |  q W| S(   NR   Rl   Rm   (   R,   Rn   R   R   R   Rl   R   R   (   Ry   R   R   R   (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s    N(   R|   R}   R~   RH   R{   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyR     s   (*   R~   t
   __future__R    t   abcR   R   t   statsmodels.compat.pythonR   t   numpyR	   t   pandasR   t   patsyR   t   patsy.mgcv_cubic_splinesR   t   statsmodels.tools.linalgR   R   R   R   R:   RB   RE   RH   RR   RY   R   Rc   Rg   Rh   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s;   lib/python2.7/site-packages/statsmodels/gam/smooth_basis.pyt   <module>	   s@   		C		^(, ohjQl