
    gLB                         d gZ ddlZddlmZmZmZ ddlmZ erddl	Z	d Z
d Zd Z G d d	e      Z ee      Zd
 Zde_        d Zd Zy)bs    N)have_pandasno_picklingassert_no_pickling)stateful_transformc                 L   	 ddl m} t        j                  t        j
                  |t                    }|j                  dk(  sJ |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                  |      kD  rt        d      t        |      |dz   z
  }t        j                  | j                  d   |ft              }t!        |      D ]0  }t        j"                  |f      }d||<    || |||f      |d d |f<   2 |S # t        $ r t        d      w xY w)Nr   )splevz#spline functionality requires scipy)dtype      zksome data points fall outside the outermost knots, and I'm not sure how to handle them. (Patches accepted!))scipy.interpolater	   ImportErrornp
atleast_1dasarrayfloatndimsortintshapeminmaxNotImplementedErrorlenemptyrangezeros)xknotsdegreer	   n_basesbasisicoefss           J/var/www/dash_apps/app1/venv/lib/python3.12/site-packages/patsy/splines.py_eval_bspline_basisr&      sn   A+ MM"**U%89E::??	JJL[F
aAvv{qwwqzQadG66Q;;
 
vvay266%= BFF1Iu$=!2
 	
" %jFQJ'GHHaggaj'*%8E7^ 7'$aAuf56ad7 LS  A?@@As   F F#c           
         t        j                  |      }t        j                  |j                  d      D cg c]  }t        j                  | d|z         c}      }|j	                  |j
                  d      S c c}w )NC)orderd   )r   r   ravel
percentilereshaper   )r   probsprob	quantiless       r%   _R_compat_quantiler1   B   sh    JJuE

27++C+2HI$q#*	%II U[[44 	Js    A=c                      d }  | ddgdd        | ddgdd        | ddgddgdd	g        | t        t        d            ddgd
dg       y )Nc                 H    t        j                  t        | |      |      sJ y N)r   allcloser1   )r   r/   expecteds      r%   tz"test__R_compat_quantile.<locals>.tL   s    {{-a6AAA    
      g      ?   g333333?   gffffff?   g@g333333@)listr   )r7   s    r%   test__R_compat_quantiler?   K   s^    B r2hRr2hRr2hc
RH%d59oSzC:.r8   c                   H    e Zd ZdZd Z	 	 	 	 	 	 ddZd Z	 	 	 	 	 	 ddZeZ	y)BSa3  bs(x, df=None, knots=None, degree=3, include_intercept=False, lower_bound=None, upper_bound=None)

    Generates a B-spline basis for ``x``, allowing non-linear fits. The usual
    usage is something like::

      y ~ 1 + bs(x, 4)

    to fit ``y`` as a smooth function of ``x``, with 4 degrees of freedom
    given to the smooth.

    :arg df: The number of degrees of freedom to use for this spline. The
      return value will have this many columns. You must specify at least one
      of ``df`` and ``knots``.
    :arg knots: The interior knots to use for the spline. If unspecified, then
      equally spaced quantiles of the input data are used. You must specify at
      least one of ``df`` and ``knots``.
    :arg degree: The degree of the spline to use.
    :arg include_intercept: If ``True``, then the resulting
      spline basis will span the intercept term (i.e., the constant
      function). If ``False`` (the default) then this will not be the case,
      which is useful for avoiding overspecification in models that include
      multiple spline terms and/or an intercept term.
    :arg lower_bound: The lower exterior knot location.
    :arg upper_bound: The upper exterior knot location.

    A spline with ``degree=0`` is piecewise constant with breakpoints at each
    knot, and the default knot positions are quantiles of the input. So if you
    find yourself in the situation of wanting to quantize a continuous
    variable into ``num_bins`` equal-sized bins with a constant effect across
    each bin, you can use ``bs(x, num_bins - 1, degree=0)``. (The ``- 1`` is
    because one degree of freedom will be taken by the intercept;
    alternatively, you could leave the intercept term out of your model and
    use ``bs(x, num_bins, degree=0, include_intercept=True)``.

    A spline with ``degree=1`` is piecewise linear with breakpoints at each
    knot.

    The default is ``degree=3``, which gives a cubic b-spline.

    This is a stateful transform (for details see
    :ref:`stateful-transforms`). If ``knots``, ``lower_bound``, or
    ``upper_bound`` are not specified, they will be calculated from the data
    and then the chosen values will be remembered and re-used for prediction
    from the fitted model.

    Using this function requires scipy be installed.

    .. note:: This function is very similar to the R function of the same
      name. In cases where both return output at all (e.g., R's ``bs`` will
      raise an error if ``degree=0``, while patsy's will not), they should
      produce identical output given identical input and parameter settings.

    .. warning:: I'm not sure on what the proper handling of points outside
      the lower/upper bounds is, so for now attempting to evaluate a spline
      basis at such points produces an error. Patches gratefully accepted.

    .. versionadded:: 0.2.0
    c                 .    i | _         d | _        d | _        y r4   )_tmp_degree
_all_knots)selfs    r%   __init__zBS.__init__   s    	r8   Nc                 <   ||||||d}|| j                   d<   t        j                  |      }|j                  dk(  r|j                  d   dk(  r	|d d df   }|j                  dkD  rt        d      | j                   j                  dg       j                  |       y )N)dfr   r    include_interceptlower_boundupper_boundargsr   r   r   z1input to 'bs' must be 1-d, or a 2-d column vectorxs)rC   r   r   r   r   
ValueError
setdefaultappend)	rF   r   rI   r   r    rJ   rK   rL   rM   s	            r%   memorize_chunkzBS.memorize_chunk   s     !2&&
 !		&MM!66Q;1771:?!Q$A66A:STT 			T2&--a0r8   c                    | j                   }|d   }| ` |d   dk  rt        d|d   d      t        |d         |d   k7  rt        d| j                  d      t	        j
                  |d         }|d   |d	   t        d
      |d   dz   }|d   |d   |z
  }|d   s|dz  }|dk  r&t        d|d   d|d   d|d   d|d   |z
        |d	   ;t        |d	         |k7  rSt        d|d   d|d   d|dt        |d	         d	      t	        j                  dd|dz         dd }t        ||      }|d	   |d	   }|d   |d   }nt	        j                  |      }|d   |d   }	nt	        j                  |      }	||	kD  rt        d|d|	d      t	        j                        }|j                  dkD  rt        d      t	        j                  ||k        rt        d|||k     d|d      t	        j                  ||	kD        rt        d|||	kD     d|	d      t	        j
                  ||	g|z  |f      }
|
j                          |d   | _        |
| _        y )NrM   r    r   z#degree must be greater than 0 (not )zdegree must be an integer (not rN   rI   r   zmust specify either df or knotsr   rJ   zdf=z is too small for degree=z and include_intercept=z; must be >= z with degree=z	 implies z knots, but z knots were providedr   rK   rL   zlower_bound > upper_bound (z > zknots must be 1 dimensionalzsome knot values (z) fall below lower bound (z) fall above upper bound ()rC   rO   r   rD   r   concatenater   linspacer1   r   r   r   r   anyr   rE   )rF   tmprM   r   r)   n_inner_knotsknot_quantilesinner_knotsrK   rL   	all_knotss              r%   memorize_finishzBS.memorize_finish   s   ii6{I>A<@NL  tH~$x.0T\\STT NN3t9%:$w-"7>??X":! J.M+,"q   T
X01 T
]2
  G}(tG}%6$ !J N)W.	 	 "$Q=13D!Ea!K0NC=$w-K*}-K&&)K*}-K&&)K$9DkR  jj-a:;;66++,%kK&?@+O  66++,%kK&?@+O  NN[+$>$F#TU	H~#r8   c                    t        || j                  | j                        }|s|d d dd f   }t        rPt	        |t
        j                  t
        j                  f      r&t        j                  |      }|j                  |_        |S )Nr   )	r&   rE   rD   r   
isinstancepandasSeries	DataFrameindex)	rF   r   rI   r   r    rJ   rK   rL   r"   s	            r%   	transformzBS.transform  sh     $AtE !QR%LE!fmmV-=-=>?((/ggr8   )NN   FNN)
__name__
__module____qualname____doc__rG   rR   r^   re   r   __getstate__ r8   r%   rA   rA   U   sM    9v 1:R$n & Lr8   rA   c                  l   ddl m}  ddlm}m}m} |j                  d      }d}|j                  d      }	 ||   dk(  sn|dz  }|j                  d|      }||| }i }	|D ]  }
|
j                  dd      \  }}||	|<    t        |	d	         t        |	d
         t        |	d         d}|	d   dk7  rt        |	d         \  }}||d<   ||d<   |	d   dk(  |d<   t        j                  t        |	d               }|d
   |j                  d   |d
   k(  sJ  | t        d||fi | |dz  }|dz   }||k(  sJ y )Nr   )check_stateful)R_bs_test_xR_bs_test_dataR_bs_num_tests
z--BEGIN TEST CASE--r   z--END TEST CASE--=r    rI   r   )r    rI   r   zBoundary.knotsNonerK   rL   	interceptTRUErJ   outputF)patsy.test_statern   patsy.test_splines_bs_dataro   rp   rq   splitrd   r   evalr   r   r   rA   )rn   ro   rp   rq   lines	tests_ran	start_idxstop_idxblock	test_datalinekeyvaluekwargslowerupperrw   s                    r%   test_bs_compatr      s   /VV  &EI12I
Y#88Q	;;2I>i)	 	#DC+JC"IcN	#
 )H-.y')G,-
 %&&0	*: ;<LE5$)F=!$)F=!&/&<&F"#
 D8!456$<#<<?fTl222r5+v@@Q	qL	E F &&&r8   r   c                     t        j                  ddd      } t        | ddgdd      }|j                  d   dk(  sJ t        j                  d      }d|| dk  <   t        j
                  |d d df   |      sJ t        j                  d      }d|| dk\  | dk  z  <   t        j
                  |d d df   |      sJ t        j                  d      }d|| dk\  <   t        j
                  |d d d	f   |      sJ t        j
                  t        g d
ddgd      ddgddgddgg      sJ t        | ddgdd      }t        | ddgdd      }t        j
                  |d d dd f   |      sJ y )NrU   r   r9      r   T)r   r    rJ   rf   r   )r   r   r   )r    r   rJ   F)r   logspacer   r   r   array_equal)r   result
expected_0
expected_1
expected_2
result_intresult_no_ints          r%   test_bs_0degreer   R  ss   
B2A!QTBF<<?a"JJq1u>>&A,
333"J%&JQ1q5!">>&A,
333"JJqAv>>&A,
333
 >>
9QqcTB
Q!Q!Q   
 AaVAFJqAqEJM>>*QU+];;;r8   c            	         dd l } t        j                  ddd      }| j                  t        t
        |dd       | j                  t        t
        |dd       | j                  t        t
        |       t        |dddgd	z  
       t        |dddgdz  
       t        |dddgdz  d       t        |dddgdz  d       | j                  t        t
        |dddgdz  
       | j                  t        t
        |dddgd	z  
       | j                  t        t
        |dddgdz  d       | j                  t        t
        |dddgdz  d       | j                  t        t
        |dddgdz  
       | j                  t        t
        |dddgdz  
       | j                  t        t
        |dddgdz  d       | j                  t        t
        |dddgd	z  d       | j                  t        t
        |dd       | j                  t        t
        |dd       | j                  t        t
        |dd       | j                  t        t
        |dd       | j                  t        t
        |ddd       | j                  t        t
        t        j                  ||f      d       t        j                  t        |ddg      t        |ddg            sJ | j                  t        t
        |dgdgg       | j                  t        t
        |ddg       | j                  t        t
        |ddgd       | j                  t        t
        |ddg       | j                  t        t
        |ddgd       y )Nr   ir9   r:   rf   )rK   )rL   F   )rI   rJ   r   T   	   r   )rI   rJ   r   r          )rI   r    rU   g      ?)rK   rL   r   )r   )r   rL   i)r   rK   )	pytestr   rW   raisesr   r   rO   column_stackr   )r   r   s     r%   test_bs_errorsr   m  s   
CR A MM%r1aQM?
MM%r1aQM?
MM*b!$ qR5a8qR4sQw7qR5aBqR4sQwqA
MM*b!eA3QR7MS
MM*b!d1#PQ'MR
MMBbE!rRS   MMBbDaPQ   MM*b!eA3QR7MS
MM*b!d1#PQ'MR
MMBbE!qQR   MMBbDaPQ   MM*b!!M4
MM*b!!M4
MM*b!2M6
MM*b!3M7
MM*b!QA2MF
MM*b"//1a&"91=>>"Qq!f-r!Aq6/BCCC
MM*b!QC";M7
MM*b!Ar7M3
MM*b!Aq6qMA
MM*b!C8M4
MM*b!B7MCr8   )__all__numpyr   
patsy.utilr   r   r   patsy.stater   ra   r&   r1   r?   objectrA   r   r   slowr   r   rl   r8   r%   <module>r      sf    &  C C *,^5/E EP *'Z  
<65Dr8   