
    M/Ph                        d 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/dZd Zd Z	 	 	 d0dZd1dZ	 	 d2dZd3dZ G d d ee                    Z G d de          Z G d de          Z G d de          Z G d d e          Z G d! d"e          Z G d# d$ ee                    Z G d% d&e          Z  G d' d(e          Z! G d) d*e          Z" G d+ d,e          Z# G d- d.e          Z$dS )4z
Spline and other smoother classes for Generalized Additive Models

Author: Luca Puggini
Author: Josef Perktold

Created on Fri Jun  5 16:32:00 2015
    )ABCMetaabstractmethod)with_metaclassN)dmatrix)_get_all_sorted_knots)transf_constraintsc                     |dz
  }|                                  }|                                 }t          j        |||          }|S )N   )minmaxnplinspace)xdfn_knotsx_minx_maxknotss         \/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/gam/smooth_basis.py_equally_spaced_knotsr      s=    1fGEEGGEEEGGEKug..EL    c                      t          j        |          }t          j         fd|                    d          D                       }|                    |j        d          S )Nc                 @    g | ]}t          j        d |z            S )d   )r   
percentile).0probr   s     r   
<listcomp>z&_R_compat_quantile.<locals>.<listcomp>#   s?     @ @ @ $ M!S4Z88 @ @ @r   C)order)r   asarrayravelreshapeshape)r   probs	quantiless   `  r   _R_compat_quantiler'       s{    JuE
 @ @ @ @(-#(>(>@ @ @ A AIU[444r   allTc                    	 ddl m} n# t          $ r t          d          w xY wt          j        t          j        |t                              }|j        dk    sJ |                                 t          |          }t          j        |           } | j        dk    r| j
        d         dk    r| d d df         } | j        dk    sJ t          j        |           t          j        |          k     s*t          j        |           t          j        |          k    rt          d          dt          |          z
  }t          |          |dz   z
  |z
  }|dv r*t          j        | j
        d         |ft                    }|}	|d	v r*t          j        | j
        d         |ft                    }
|
}	|d
v r*t          j        | j
        d         |ft                    }|}	t!          |          D ]v}t          j        ||z   f          }d|||z   <   |}|dv r || |||f          |d d |f<   |d	v r || |||fd          |
d d |f<   |d
v r || |||fd          |d d |f<   w|dk    r||
|fS |	S )Nr   )splevz#spline functionality requires scipydtype   r
   zksome data points fall outside the outermost knots, and I'm not sure how to handle them. (Patches accepted!))r(   r   )r(   r-   )r(   r
   )derr(   )scipy.interpolater*   ImportErrorr   
atleast_1dr!   floatndimsortintr$   r   r   NotImplementedErrorlenemptyrangezeros)r   r   degreederivinclude_interceptr*   k_constn_basesbasisret
der1_basis
der2_basisicoefsiis                  r   _eval_bspline_basisrG   +   s   A+++++++ A A A?@@@A
 M"*U%88899E:????	JJLLL[[F
aAv{{qwqzQaaadG6Q;;;;
 
vayy26%==  BF1IIu$=$=! #H I I 	I  #'(((G%jjFQJ''1G
!'!*g.e<<<
Xqwqz735AAA

Xqwqz735AAA
7^^ 
H 
H'G+-..a'kJ 5UE6$:;;E!!!R%LJ %a%)?Q G G GJqqq"uJ %a%)?Q G G GJqqq"u~~j*,,
s   	 #c                 
   |dz   }||z
  }t          j        |           }t          j        |           }t          j        dd|dz             dd         }t	          | |          }t          j        ||g|z  |f          }	|	|||fS )Nr-   r   r
   )r   r   r   r   r'   concatenate)
r   r   r;   r    n_inner_knotslower_boundupper_boundknot_quantilesinner_knots	all_knotss
             r   compute_all_knotsrQ   n   s    QJEJM&))K&))K[A}q'899!B$?N$Q77Kk :U B + - . .Ik;;;r   c                 b    t          | ||          \  }}}}t          | ||          \  }}}|||fS )z make a spline basis for x )rQ   rG   )r   r   r;   rP   _r@   	der_basisrC   s           r   make_bsplines_basisrU   z   sC     +1b&99Iq!Q#6q)V#L#L E9j)Z''r      quantilec                    ||S |                                  }|                                 }	|dk     rt          d|d          t          |          |k    rt          d|d          ||t          d          |dz   }
|||
z
  }|dk     rt          d|d	|d
||z
            |=t	          |          |k    r)t          d|d|d|dt	          |          d	          n|dk    r2t          j        dd|dz             dd         }t          | |          }nS|dk    r>t          j        dd|dz             dd         }|||	|z
  z  z   }|d         |d         z
  }nt          d          ||}|t          j         |           }|t          j        |           }||k    rt          d|d|d          t          j        |          }|j	        dk    rt          d          t          j
        ||k               r t          d|||k              d|d          t          j
        ||k              r t          d|||k             d|d          |dk    rRt          j        d|
dz             |z  }|d         |ddd         z
  }|d         |z   }t          j        |||f          }nt          j        ||g|
z  |f          }|                                 |S )a7  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.
    Nr   z#degree must be greater than 0 (not )zdegree must be an integer (not zmust specify either df or knotsr-   zdf=z is too small for degree=z; must be >= z with degree=z	 implies z knots, but z knots were providedrW   r
   rI   equalzincorrect option for spacingzlower_bound > upper_bound (z > zknots must be 1 dimensionalzsome knot values (z) fall below lower bound (z) fall above upper bound ()r   r   
ValueErrorr5   r7   r   r   r'   r!   r3   anyarangerJ   r4   )r   r   r   r;   spacingrL   rM   rP   r   r   r    rK   rN   rO   grid
diff_knotsdiffslower_knotsupper_knotss                      r   get_knots_bsplinesrd      s    EEGGEEEGGEzzj"FF% & & 	&
6{{fj"FF% & & 	&
 
zem:;;;QJE	~U
1* "FFF !#] 2 24 5 5 5 5zz]** j$&BB$1MM3u::::"? @ @ @ +
 
""[A}q/@AA!B$GN,Q??KK;q!]Q%677"=D$%%-"88K$Q+a.8JJ;<<<fQiifQii[  j'KK6 7 7 	7*[))K!6777	vkK'(( *j'k(ABBB'KK) * * 	* 
vkK'(( *j'k(ABBB'KK) * * 	*
 '	!UQY''*4!!nuTTrT{2!"o-NKk#JKK		N[+$>$F$/$1 2 2	NNr   c                 $   |dz   }t          j        |           } t          j        |          |z  }t          j        |           }|dddf         |z  }t          j        | dddf         |z                                   | d         gf          }|S )zmadd points to each subinterval defined by knots

    inserts k_points between each two consecutive knots
    r-   NrI   )r   uniquer]   diffrJ   r"   )r   k_pointsdxidxkdxr   s         r   _get_integration_pointsrl      s    
 !|HIeE
)H


(C
'%..C	QQQW	B
ssDy)B.5577%)EFFAHr   Fr
   c                    	 ddl m} n# t          $ r	 ddl m} Y nw xY w| j        }|t          ||          }n|}|                     |||          } ||dddddf         |dddddf         z  |d          }	|	S )z
    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.
    r   )simpson)simpsN)rh   )r<   skip_ctransf)r   axis)scipy.integratern   r0   ro   r   rl   	transform)
smootherrh   integration_pointsrp   r<   rn   r   r   d2covd2s
             r   get_covder2rx      s    5+++++++ 5 5 5444444445 NE!#EH===			AU		F	FBGBqqq!!!TzNR4
^3qqAAAELs   	 c                    |rd}nd}t          |           }t          j        ||dz   |z
  f          }t          j        ||dz   |z
  f          }t          j        ||dz   |z
  f          }t          ||dz             D ]A}| |z  |dd||z
  f<   || |dz
  z  z  |dd||z
  f<   ||dz
  z  | |dz
  z  z  |dd||z
  f<   B|||fS )zj
    given a vector x returns poly=(1, x, x^2, ..., x^degree)
    and its first and second derivative
    r   r-   r$   Nr
   )r7   r   r:   r9   )	r   r;   	interceptstartnobsr@   rT   rC   rD   s	            r   make_poly_basisr~     s     q66DHD&1*u"45666Efqj5&89:::IvzE'9 :;;;J5&1*%% > >1faaaUl"#aAEl"2	!!!QY,#$A;q1u#=
111a%i<  )Z''r   c                   0    e Zd ZdZddZed             ZdS )UnivariateGamSmootherz+Base Class for single smooth component
    Nr   c                     | _         | _        | _        t          |          dc _         _                                         }|dk    r%|d                             d          d d d f         }|,t          |t                    st          |          }| _        nt           d          sd  _        |\   _         _         _         _         j         j        }|d          |d                             |           _        |d          |d                             |           _        |d          |d                             |           _        |d         8|j                            |d                                       |           _         j        j        d          _         fdt+           j                  D              _        d S )Nr-   centerr   ctransfr
   rV   c                 D    g | ]}j         d z   t          |          z   S )_s)variable_namestr)r   rD   selfs     r   r   z2UnivariateGamSmoother.__init__.<locals>.<listcomp>T  s<     : : : ,t3c!ff< : : :r   )r   constraintsr   r7   r}   k_variables!_smooth_basis_for_single_variablemean
isinstancer   r   r   hasattrr@   rT   rC   cov_der2dotTr$   	dim_basisr9   	col_names)r   r   r   r   base4r   s   `     r   __init__zUnivariateGamSmoother.__init__3  s   &*&)!ffa#	4#6688(""(--**473K":k3+G+G"(55G"DLL 4++ $#EJB
DNDOT]<#lGQx#"1X\\'22
Qx#!&qg!6!6Qx#"'(,,w"7"7Qx# '	eAh 7 7 ; ;G D D)!,: : : :#(#8#8: : :r   c                     d S N r   s    r   r   z7UnivariateGamSmoother._smooth_basis_for_single_variableW  s    r   Nr   )__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   0  sN         ": ": ": ":H   ^  r   r   c                   ,     e Zd ZdZ	 d fd	Zd Z xZS )UnivariateGenericSmootherz$Generic single smooth component
    r   c                     || _         || _        || _        || _        t	                                          ||           d S N)r   )r@   rT   rC   r   superr   )r   r   r@   rT   rC   r   r   	__class__s          r   r   z"UnivariateGenericSmoother.__init___  sB    
"$ -88888r   c                 6    | j         | j        | j        | j        fS r   )r@   rT   rC   r   r   s    r   r   z;UnivariateGenericSmoother._smooth_basis_for_single_variableh  s    z4>4?DMIIr   r   r   r   r   r   r   r   __classcell__r   s   @r   r   r   \  sb           #9 9 9 9 9 9J J J J J J Jr   r   c                   *     e Zd ZdZd fd	Zd Z xZS )UnivariatePolynomialSmootherz'polynomial single smooth component
    r   c                 \    || _         t                                          ||           d S r   )r;   r   r   )r   r   r;   r   r   s       r   r   z%UnivariatePolynomialSmoother.__init__o  s-    -88888r   c                    t          j        | j        | j        f          }t          j        | j        | j        f          }t          j        | j        | j        f          }t	          | j                  D ]\}|dz   }| j        |z  |dd|f<   || j        |dz
  z  z  |dd|f<   |dk    r||dz
  z  | j        |dz
  z  z  |dd|f<   Sd|dd|f<   ]t          j        |j        |          }||||fS )zv
        given a vector x returns poly=(1, x, x^2, ..., x^degree)
        and its first and second derivative
        rz   r-   Nr
   r   )r   r:   r}   r;   r9   r   r   r   )r   r@   rT   rC   rD   dgr   s          r   r   z>UnivariatePolynomialSmoother._smooth_basis_for_single_variables  s    	4;7888HDIt{#;<<<	XTY$<===
t{## 	% 	%AQB&B,E!!!Q$K 46b1f#55IaaadOAvv#%a=46b1f3E#E
111a4  #$
111a4  6*,
33iX55r   r   r   r   s   @r   r   r   l  sV         9 9 9 9 9 96 6 6 6 6 6 6r   r   c                   8     e Zd ZdZ	 	 	 d
 fd	Zd Zdd	Z xZS )UnivariateBSplinesaW  B-Spline single smooth component

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

    Parameters
    ----------
    x : ndarray, 1-D
        underlying explanatory variable for smooth terms.
    df : int
        number 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, str, 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, 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, dict}
        options for computing the penalty matrix from the second derivative
        of the spline.
    knot_kwds : {None, list[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.
    rV   FNr   c                     || _         || _        || _        t          |f||d|| _        ||ni | _        t                                          |||           d S )N)r;   r   r   r   )r;   r   r=   rd   r   covder2_kwdsr   r   )
r   r   r   r;   r=   r   r   r   	knot_kwdsr   s
            r   r   zUnivariateBSplines.__init__  s     !2'M&RMM9MM
-9-E\\"$ 	;m 	 	
 	
 	
 	
 	
r   c                     t          | j        | j        | j        | j                  \  }}}t          | fddi| j        }||||fS )N)r=   rp   T)rG   r   r   r;   r=   rx   r   )r   r@   rT   rC   r   s        r   r   z4UnivariateBSplines._smooth_basis_for_single_variable  sk    ':FDJ"4(6 (6 (6$y*
 t 4 4$ 4!%!24 4 iX55r   r   c                     || j         }t          || j        | j        || j                  }t          | dd          }||s|                    | j                  }|S )a  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 : ndarray
            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``
        N)r<   r=   r   )r   rG   r   r;   r=   getattrr   r   )r   x_newr<   rp   exogr   s         r   rs   zUnivariateBSplines.transform  sp    . =FE"5$*dk).595KM M M
 $	400|88DL))Dr   )rV   FNr   N)r   F)r   r   r   r   r   r   rs   r   r   s   @r   r   r     sw        1 1d ;@14"
 
 
 
 
 
	6 	6 	6! ! ! ! ! ! ! !r   r   c                   P     e Zd ZdZ	 	 d fd	ZddZd Zd	 Zdd
Zd Z	d Z
 xZS )UnivariateCubicSplinesziCubic Spline single smooth component

    Cubic splines as described in the wood's book in chapter 3
    Ndomainr   c                     d| _         || _        || _        |                     |d          x| _        }t          ||          | _        t                                          |||           d S )NrV   T
initializer   )	r;   r   transform_data_methodtransform_datar   r   r   r   r   )r   r   r   r   rs   r   r   s         r   r   zUnivariateCubicSplines.__init__   s}     %."((t(<<<*1b11
;m 	 	
 	
 	
 	
 	
r   Fc                    | j         }||S |du r|dk    r5|                    d          | _        |                    d          | _        nFt          |t                    r"|d         | _        |d         | _        d| _         nt          d          | j        | j        z
  | _        | j         dk    r|| j        z
  | j        z  }|S t          d          )NTr   r   r-   z-transform should be None, 'domain' or a tuplezincorrect transform_data_method)	r   r   
domain_lowr   
domain_uppr   tupler[   domain_diff)r   r   r   tms       r   r   z%UnivariateCubicSplines.transform_data  s    ':HX~~"#%%(("#%%((B&& /"$Q%"$Q%-5**  ". / / /#@D%11T_$(88AH>???r   c                 x   |                                  d d d df         }| j        dk    sB|d d dd f                             d          | _        |d d dd fxx         | j        z  cc<   n$t	          j        |j        d                   | _        |                                 d dd df         }| j        dk    s>t	          j        dt	          j	        t	          j
        |          d          z            }nt	          j        |j        d                   }| j        dk    r
|dd          }|| _        |d d |fS )NrI   noner-   r   )rq   zno-const)
_splines_xr   r   transf_meanr   r:   r$   
_splines_sdiagr   abseyer   )r   r@   sr   s       r   r   z8UnivariateCubicSplines._smooth_basis_for_single_variable%  s8   !!!!!SbS&)6))$QQQU|0033D!!!QRR%LLLD,,LLLL!xA77DOOcrc3B3h'6))garve}}1 = = ==>>GGfU[^,,G z))abbkGdD!##r   c                     |dz
  dz  dz
  |dz
  dz  dz
  z  dz  }t          j        ||z
            dz
  dz  dt          j        ||z
            dz
  dz  z  z
  dz   dz  }||z
  S )Ng      ?r
   gUUUUUU?   gݝ?g      8@)r   r   )r   r   zp1p2s        r   _rkzUnivariateCubicSplines._rk=  s    5yQ'QY1,<v,EFJva!e}}u$*rva!e}}u,223 Bwr   c                 >   || j         }t          | j                  dz   }|j        d         }t	          j        ||f          }||d d df<   t          |          D ]?\  }}t          | j                  D ]%\  }}|                     ||          }	|	|||dz   f<   &@|S )Nr
   r   rz   r-   )r   r7   r   r$   r   ones	enumerater   )
r   r   	n_columnsr}   r@   rD   xijxkjs_ijs
             r   r   z!UnivariateCubicSplines._splines_xD  s    9A
OOa'	wqztY/000aaadq\\ 	' 	'EAr#DJ// ' '3xxC(("&aQh' r   c                    t          | j                  dz   }t          j        ||f          }t	          | j                  D ]@\  }}t	          | j                  D ]&\  }}|                     ||          ||dz   |dz   f<   'A|S )Nr
   rz   )r7   r   r   r:   r   r   )r   qr   rD   x1r   x2s          r   r   z!UnivariateCubicSplines._splines_sR  s    
OOaHAq6"""tz** 	3 	3EAr"4:.. 3 32"&((2r"2"2!a%Q,3r   c                     |                      |d          }|                     |          }|d d dd fxx         | j        z  cc<   | j        |                    | j                  }|S )NFr   r-   )r   r   r   r   r   r   r   r   s      r   rs   z UnivariateCubicSplines.transformZ  sp    ##Ee#<<u%%QQQUt''<#88DL))Dr   )Nr   r   )Fr   )r   r   r   r   r   r   r   r   r   r   rs   r   r   s   @r   r   r     s         
 ;C"
 
 
 
 
 
@ @ @ @0$ $ $0             r   r   c                   <     e Zd ZdZd	 fd	Zd Zd Zd Zd Z xZ	S )
UnivariateCubicCyclicSplinesa  cyclic cubic regression spline single smooth component

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

    Parameters
    ----------
    x : ndarray, 1-D
        underlying explanatory variable for smooth terms.
    df : int
        number 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, str, 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.
    Nr   c                     d| _         || _        || _        t          ||          | _        t                                          |||           d S )NrV   r   )r;   r   r   r   r   r   r   )r   r   r   r   r   r   s        r   r   z%UnivariateCubicCyclicSplines.__init__~  s[    *1b11
;m 	 	
 	
 	
 	
 	
r   c                 ,   t          dt          | j                  z   dz   d| j        i          }|j        | _        | j        dz
  dz   }t          | j        |d d d           }|                     |          \  }}|                     ||          }|d d |fS )Nz	cc(x, df=z) - 1r   r
   r-   )rK   rO   rL   rM   )r   r   r   r   design_infor   _get_b_and_d_get_s)r   r@   rK   rP   bdr   s          r   r   z>UnivariateCubicCyclicSplines._smooth_basis_for_single_variable  s    c$'ll2W<sDFmLL ,!a)$&6:6:N N N	   ++1KK1dD!##r   c                 
   |dd         |dd         z
  }|j         dz
  }t          j        ||f          }t          j        ||f          }||dz
           |d         z   dz  |d<   ||dz
           dz  |d|dz
  f<   ||dz
           dz  ||dz
  df<   d|d         z  d	||dz
           z  z
  |d<   d	||dz
           z  |d|dz
  f<   d	||dz
           z  ||dz
  df<   t          d|          D ]}||dz
           ||         z   dz  |||f<   ||dz
           dz  |||dz
  f<   ||dz
           dz  ||dz
  |f<   d||dz
           z  d	||         z  z
  |||f<   d	||dz
           z  |||dz
  f<   d	||dz
           z  ||dz
  |f<   ||fS )
a  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 : ndarray
            Array for mapping cyclic cubic spline values at knots to
            second derivatives.
        d : ndarray
            Array for mapping cyclic cubic spline values at knots to
            second derivatives.

        Notes
        -----
        The penalty matrix is equal to ``s = d.T.dot(b^-1).dot(d)``
        r-   NrI   r   g      @)r   r   g      @g      g      ?)sizer   r:   r9   )r   r   hnr   r   rD   s          r   r   z)UnivariateCubicCyclicSplines._get_b_and_d  s   2 !""Icrc
"JN
 HaVHaVQU8ad?b($Ahm!QU(Ahm!a%(!*rAa!eH},$1QU8m!QU(1QU8m!a%(q! 	( 	(AQx!A$",AadGAE(R-AaQhKAE(R-Aa!eQhKAa!eHnrAaDy0AadGqQx-AaQhKqQx-Aa!eQhKK!tr   c                     |j                             t          j                            |                                        |          S r   )r   r   r   linalginv)r   r   r   s      r   r   z#UnivariateCubicCyclicSplines._get_s  s2    swwry}}Q''((,,Q///r   c                 v    t          | j        d|i          }| j        |                    | j                  }|S r   )r   r   r   r   r   s      r   rs   z&UnivariateCubicCyclicSplines.transform  s8    t'#u66<#88DL))Dr   r   )
r   r   r   r   r   r   r   r   rs   r   r   s   @r   r   r   c  s         4
 
 
 
 
 
$ $ $3 3 3j0 0 0      r   r   c                   6    e Zd ZdZddZed             Zd ZdS )AdditiveGamSmootherz.Base class for additive smooth components
    NFc                    t          |t          j                  r|j                                        }n%t          |t          j                  r	|j        g}nd }t          j        |          }|j	        dk    r5|
                                | _        t          |          df| j        _        n|| _        | j        j        \  | _        | _        t          |t                     r|g| j        z  | _        n|| _        |.||| _        n+d t'          | j                  D             | _        n|| _        |                                 | _        t          j        t/          d | j        D                                 | _        | j        j        d         | _        d | j        D             | _        g | _        | j        D ]!}| j                            |j                   "g | _        d}| j        D ]R}t          j        dg| j        z            }d|||j        |z   <   ||j        z   }| j                            |           Sd S )Nr-   c                 2    g | ]}d t          |          z   S r   )r   )r   rD   s     r   r   z0AdditiveGamSmoother.__init__.<locals>.<listcomp>  s8     'I 'I 'I+, (+SVV| 'I 'I 'Ir   c              3   $   K   | ]}|j         V  d S r   )r@   r   rt   s     r   	<genexpr>z/AdditiveGamSmoother.__init__.<locals>.<genexpr>  s8       $? $?#+ %-N $? $? $? $? $? $?r   c                     g | ]	}|j         
S r   )r   r   s     r   r   z0AdditiveGamSmoother.__init__.<locals>.<listcomp>  s1     !A !A !A%- "*!2 !A !A !Ar   r   FT) r   pd	DataFramecolumnstolistSeriesnamer   r!   r3   copyr   r7   r$   r}   r   boolr=   variable_namesr9   _make_smoothers_list	smoothershstacklistr@   r   penalty_matricesr   extendmaskarrayappend)	r   r   r  r=   kwargs
data_namesrt   last_columnr  s	            r   r   zAdditiveGamSmoother.__init__  sh    a&& 	))++JJ29%% 	&JJJJqMM6Q;;VVXXDFFFA;DFLLDF&*fl#	4#'.. 	7&7%84;K%KD""%6D"!%&0##'I 'I05d6F0G0G'I 'I 'I## #1D2244Yt $? $?/3~$? $? $?  ?  ? @ @
)!,!A !A15!A !A !A 	6 	6HN!!("45555	 	# 	#H8UGdn455DAEDX/+==>%(::KIT""""		# 	#r   c                     d S r   r   r   s    r   r  z(AdditiveGamSmoother._make_smoothers_list  s    r   c                      j         dk    r! j        dk    r                    dd          t          j        t           fdt           j                  D                                 }|S )a  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: ndarray
            observations of the underlying explanatory variable

        Returns
        -------
        basis : ndarray
            design matrix for the spline basis for given ``x_new``.
        r-   rI   c              3   l   K   | ].}j         |                             d d |f                   V  /d S r   )r  rs   )r   rD   r   r   s     r   r   z0AdditiveGamSmoother.transform.<locals>.<genexpr>!  sX       ; ; #nQ/99%1+FF ; ; ; ; ; ;r   )r3   r   r#   r   r	  r
  r9   r   s   `` r   rs   zAdditiveGamSmoother.transform  s      :??t/144MM"a((Ey ; ; ; ; ;"'(8"9"9; ; ; ; ; < <r   )NF)r   r   r   r   r   r   r  rs   r   r   r   r   r     s]         2# 2# 2# 2#h   ^    r   r   c                   (     e Zd ZdZ fdZd Z xZS )GenericSmoothersz9generic class for additive smooth components for GAM
    c                 \    || _         t                                          |d            d S N)r  )r  r   r   )r   r   r  r   s      r   r   zGenericSmoothers.__init__)  s-    "400000r   c                     | j         S r   )r  r   s    r   r  z%GenericSmoothers._make_smoothers_list-  s
    ~r   r   r   r   r   r   r  r   r   s   @r   r  r  &  sQ         1 1 1 1 1      r   r  c                   *     e Zd ZdZd fd	Zd Z xZS )PolynomialSmootherz+additive polynomial components for GAM
    Nc                 \    || _         t                                          ||           d S r  )degreesr   r   )r   r   r  r  r   s       r   r   zPolynomialSmoother.__init__4  s-    >:::::r   c                     g }t          | j                  D ]N}t          | j        d d |f         | j        |         | j        |                   }|                    |           O|S )N)r;   r   )r9   r   r   r   r  r  r  r   r  vuv_smoothers       r   r  z'PolynomialSmoother._make_smoothers_list8  sy    	t'(( 	* 	*A6qqq!t|A"1!46 6 6K [))))r   r   r  r   s   @r   r  r  1  sV         ; ; ; ; ; ;      r   r  c                   .     e Zd ZdZ	 	 d fd	Zd Z xZS )BSplinesa9  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, array_like[int]}
        number of basis functions or degrees of freedom; should be equal
        in length to the number of columns of `x`; may be an integer if
        `x` has one column or is 1-D.
    degree : {int, array_like[int]}
        degree(s) of the spline; the same length and type rules apply as
        to `df`
    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, str, 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 : {list[str], None}
        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.
    FNc                 t   t          |t                    r"t          j        |gt                    | _        n|| _        t          |t                    r"t          j        |gt                    | _        n|| _        || _        || _        |dk    rd}t                      	                    |||           d S )Nr+   r   T)r=   r  )
r   r5   r   r  r  dfsr   r   r   r   )	r   r   r   r;   r=   r   r  r   r   s	           r   r   zBSplines.__init__  s    fc"" 	"8VHC888DLL!DLb# 	xC000DHHDH"&("" $/) 	 	
 	
 	
 	
 	
r   c           
      4   g }t          | j                  D ]}| j        r| j        |         ni }t          | j        d d |f         f| j        |         | j        |         | j        |         | j        | j	        |         d|}|
                    |           |S )N)r   r;   r=   r   r   )r9   r   r   r   r   r'  r  r=   r   r  r  )r   r  r"  kwdsr#  s        r   r  zBSplines._make_smoothers_list  s    	t'(( 	* 	*A(,>4>!$$BD,qqq!t>8A;t|A"&"8"; ,"1!4> >
 9=> >K [))))r   )FNNNr  r   s   @r   r%  r%  C  sa        O O` 9>BF
 
 
 
 
 
,      r   r%  c                   .     e Zd ZdZ	 	 d fd	Zd Z xZS )CubicSplineszadditive smooth components using cubic splines as in Wood 2006.

    Note, these splines do NOT use the same spline basis as
    ``Cubic Regression Splines``.
    r   r   Nc                 z    || _         || _        || _        t                                          |||           d S )N)r   r  )r'  r   rs   r   r   )r   r   r   r   rs   r  r   s         r   r   zCubicSplines.__init__  sK    &";~ 	 	
 	
 	
 	
 	
r   c           	          g }t          | j                  D ]Z}t          | j        d d |f         | j        |         | j        | j        | j        |                   }|                    |           [|S )N)r   r   rs   r   )	r9   r   r   r   r'  r   rs   r  r  r!  s       r   r  z!CubicSplines._make_smoothers_list  s    	t'(( 	* 	*A0 F111a4LTXa[(,(8&*n*.*=a*@	B B BK
 [))))r   )r   r   Nr  r   s   @r   r+  r+    s_         
 ?G $
 
 
 
 
 

 
 
 
 
 
 
r   r+  c                   *     e Zd ZdZd fd	Zd Z xZS )CyclicCubicSplinesa,  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, str, array}
        Constraints are used to transform the basis functions to satisfy
        those constraints.
    variable_names : {list[str], None}
        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.
    Nc                 j    || _         || _        t                                          ||           d S r  )r'  r   r   r   )r   r   r   r   r  r   s        r   r   zCyclicCubicSplines.__init__  s5    &>:::::r   c                     g }t          | j                  D ]T}t          | j        d d |f         | j        |         | j        | j        |                   }|                    |           U|S )N)r   r   r   )r9   r   r   r   r'  r   r  r  r!  s       r   r  z'CyclicCubicSplines._make_smoothers_list  s~    	t'(( 	* 	*A6qqq!t8A;D,<"1!46 6 6K [))))r   )NNr  r   s   @r   r/  r/    sV         (; ; ; ; ; ;	 	 	 	 	 	 	r   r/  )r(   T)NNNrV   rW   NNN)rV   )rV   NFr
   )T)%r   abcr   r   statsmodels.compat.pythonr   numpyr   pandasr   patsyr   patsy.mgcv_cubic_splinesr   statsmodels.tools.linalgr   r   r'   rG   rQ   rU   rd   rl   rx   r~   r   r   r   r   r   r   r   r  r  r%  r+  r/  r   r   r   <module>r9     s    ( ' ' ' ' ' ' ' 4 4 4 4 4 4               : : : : : : 7 7 7 7 7 7
  5 5 5@ @ @ @F	< 	< 	<( ( ( <=7;37\ \ \ \~    :>*+   2( ( ( (P) ) ) ) )NN733 ) ) )XJ J J J J 5 J J J 6 6 6 6 6#8 6 6 6>l l l l l. l l l^f f f f f2 f f fRn n n n n#8 n n nbO O O O O..11 O O Od    *       ,   $s s s s s" s s sl    &   8$ $ $ $ $, $ $ $ $ $r   