
    P3j                        d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZ d dl	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( d d
l)m*Z* d dl+m,Z,m-Z-m.Z. d dl+m/Z0 d dl1m2Z2m3Z3m4Z4  e5 ejl                               Z7e7D  cg c]	  }  |         c} Z8e8 e'd       e&d       e$d       e$d        e$d       e$d       e$d       e%d        e%d       e%d       e%d      gz  Z8d Z9	 ddZ:d Z;ejx                  j{                  de8e9      d        Z> e#       g dej~                   ej~                  gf e       g dej~                   ej~                  gf e'       g dej~                   ej~                  gf e&       g dej~                   ej~                  gf e!       ddgej~                   dd ej~                  gf e       ddgej~                   dd d ej~                  gf e$d      ddgej~                   ej~                  gf e$d       ddgej~                   ej~                  gf e$d!      ddgej~                   dd ej~                  gf e$d      ddgej~                   dd d ej~                  gf e$d"      ddgej~                   dd d ej~                  gf e%d      ddgej~                   ej~                  gf e%d       g d#ej~                   ej~                  gf e%d!      ddgej~                   dd ej~                  gf e%d      ddgej~                   dd d ej~                  gf e%d"      ddgej~                   dd d ej~                  gf e       g d$ej~                   d%dej~                  gf e       g ej~                   d%d&ej~                  gfgZ@ e!       d gg f e&       d gg f e$d      g d'g f e$d       d(d gg f e$d!      d gg f e%d      g d'g f e%d       d(d gg f e%d!      d gg f e       d dgg f e       g d)g fg
ZA e!       g d gf e$d      g g d*f e$d       g g d*f e$d!      g d gf e%d      g g d*f e%d       g d*g f e%d!      g d gf e       g d dgf e       dd+gd dgfg	ZBejx                  j{                  d,e@eAz         d-        ZCejx                  j{                  d.e@eBz         d/        ZDejx                  j{                  d0g  e#       d1d2d3d4df e       d1d2d5d1df e'd+      d1d2dd+df e'd      d1d2dddf e'd      d2d1d1d6df e&d+d"7      d1d2d8ddf e&d+d"7      d1dd9ddf e!       d9 ej                  d4      d4d ej                  d4      z  z
  dd4f e       d9 ej                  d4       ej                  d4      d+z   d+d+f e$d"      d9 ej                  d4      d:ddf e%d      d9d5dd ej                  d      z  z
  ddf e%d      d9d5 ej                  d      d+z
  ddf e%d"      d9d5d;ddf e       d ej                  d4       ej                  d4      d ej                  d4      z  z
  ddf e       d<d=d d d f e       d1d=d>d%d f e       d<d?d d d f e       d1d?d@d%d f e       d1dAdBd%d f e       d1dCdDdEdFf e       d<dCgdFgd"z   e       d1dGdHdEdIf e       d<dGgdIgd"z   e       d<dJdDdKdFf e       d1dJgdLgd"z   e       d<dBdBddMf e       d<dNdNddOf e       d1d>d d d f e       d<d>d>dd f e       d1dNd dPdOf e       d1dQd d d f e       d1d@d d d f e       d<d@d@dd f ed"R      d<g dS eg dS      dTz
  ddf ed"R      d1g dS eg dS      d+z
  ddf ed"R      d9g dS eg dS      dUz
  ddf ed"R      d9g dV eg dV      dWz
  ddfe9      dX        ZGejx                  j{                  de7      ejx                  j{                  dYdZd[g      ejx                  j{                  d\ej                  ej                  g      ejx                  j{                  d]ej                  ej                  g      ejx                  j{                  d^ddg      ejx                  j{                  d_ddg      ejx                  j{                  d`ddg      ejx                  j{                  daddg      db                                                         ZJejx                  j{                  de8e9      ejx                  j{                  d^ddcg      dd               ZKejx                  j{                  de8e9      ejx                  j{                  d^ddcg      de               ZLejx                  j{                  de8e9      ejx                  j{                  d^dfdgg      dh               ZMejx                  j{                  de8e9      di        ZNejx                  j{                  de8e9      ejx                  j{                  d^ddcg      dj               ZOejx                  j{                  de8e9      ejx                  j{                  d^ddcg      dk               ZPejx                  j{                  dlg dm      e4dn               ZQejx                  j{                  de8e9      ejx                  j{                  d^ddcg      do               ZRejx                  j{                  dp e#       ej                  dqf e       ej                  dqf e'd      dr dqf e!       ej                  dsf e       ej                  dtf e$       ej                  dtf e       ej                  dufg      dv        ZUdw ZVdx ZWdy ZXejx                  j{                  dz ej                  g d{       ej                  g d|      f      ejx                  j{                  d} ej                  g d~       ej                  g d      f      d               ZZejx                  j{                  de8e9      d        Z[ejx                  j{                  de7      ejx                  j{                  d^ddcg      ejx                  j{                  dej                  ej                  f      ejx                  j{                  dd      d                             Z\ejx                  j{                  de7      ejx                  j{                  ddej                  idej                   dfg      d               Z^ejx                  j{                  de'ddie_dfe'dd ie`dfe'dd&ie`dfe&ddie_dfe&dd ie`dfe&dd&ie`dfg      d        Zaejx                  j{                  de8e9      d        Zbejx                  j{                  dg d      d        Zcejx                  j{                  deefe efe"e!fgg d      ejx                  j{                  dg d      ejx                  j{                  ddZd[g      ejx                  j{                  d e.             d                             Zdejx                  j{                  d e.             d        Zed Zfyc c} w )    N)assert_allcloseassert_array_equal)approx)LinearConstraintminimizeminimize_scalarnewton)	logsumexp)config_context)_loss)IdentityLink_inclusive_low_high)_LOSSESAbsoluteErrorBaseLossHalfBinomialLossHalfBinomialLossArrayAPIHalfGammaLossHalfMultinomialLossHalfMultinomialLossArrayAPIHalfPoissonLossHalfPoissonLossArrayAPIHalfSquaredErrorHalfTweedieLossHalfTweedieLossIdentity	HuberLossPinballLoss	_log1pexp)assert_all_finite)_atol_for_typemove_to)yield_namespace_device_dtype_combinationsdevice)_array_api_for_testscreate_memmap_backed_dataskip_if_32bitg      ?)quantileg      ?      power            @c                    t        | t              r| }|j                  j                  }t        |t              r|d|j
                  j                   dz  }|S t        |t              r|d|j                   z  }|S t        |d      r3t        |j
                  d      r|d|j
                  j                   dz  }|S t        |       S )Nz
(quantile=)clossr+   z(power=)
isinstancer   	__class____name__r   r1   r(   r   hasattrr+   str)paramlossnames      J/DATA/.local/lib/python3.12/site-packages/sklearn/_loss/tests/test_loss.pyloss_instance_namer;   G   s    %"~~&&dK(j!4!4 5Q77D
 	 i(j00D  T7#

G(Dgdjj../q11D5z    c                     t         j                  j                  |      }| j                  rt        j                  || j
                  f      }|j                  |d   |d   || j
                  z        |j                  dd t        j                  |      j                  t              | j
                  z  }||fS t        | j                  t              rPt        | j                        \  }}	t        j                   ||d   g      }t        j"                  |	|d   g      }	||	f}|j                  |d   |d   |      }t        | j$                        \  }}	t'        ||d         }t)        |	|d         }	|j                  ||	|      }| j$                  j*                  dk(  r!| j$                  j,                  rd|dd|dz  <   | j$                  j.                  dk(  r!| j$                  j0                  rd|dd|dz  <   ||fS )z9Random generate y_true and raw_prediction in valid range.r   r,   )lowhighsizeNr@      )nprandomRandomStateis_multiclassempty	n_classesuniformflatarangeastypefloatr2   linkr   r   interval_y_predamaxamininterval_y_truemaxminr>   low_inclusiver?   high_inclusive)
r8   	n_samplesy_bound	raw_boundseedrngraw_predictiony_truer>   r?   s
             r:   random_y_true_raw_predictionr^   V   s    ))


%C9dnn"=>!$!1T^^+ "- "
A
 9%,,U3dnnD, >!!' dii.+D,@,@AIC''3	!-.C77D)A,/0DdI!9Q<i % 
 ((<(<=	T#wqz"4$S$Y7##q(T-A-A-O-O*+F&yA~&'$$)d.B.B.Q.Q,-F1(a()>!!r<   c                     t        j                  ||      } | |d|z  z
        } | ||z
        } | ||z         } | |d|z  z         }| d|z  z   d|z  z
  |z   d|z  z  S )z2Helper function for numerical (first) derivatives.)
fill_valuer-            (@)rC   	full_like)funcxepsh
f_minus_2h
f_minus_1h	f_plus_1h	f_plus_2hs           r:   numerical_derivativerl   {   sy     	Q3'Aa!a%iJa!eJQUIQQYIJY&Z7*DPSTTr<   r8   )idsc                    | j                   r2d}t        j                  t        j                  d|dz
  |      d      }n0t	        | j
                        \  }}t        j                  ||d      }| j
                  j                  r)t        j                  || j
                  j                  f   }| j
                  j                  r)t        j                  || j
                  j                  f   }| j                  |      sJ |j                  d   }t	        | j                        \  }}| j                   rct        j                  |f      }t        j                  |||      |dddf<   dd|dddf   z
  z  |dddf<   dd|dddf   z
  z  |dddf<   nt        j                  |||      }| j                  |      sJ | j                   j!                  |      }| j#                  ||	       y)
z4Test interval ranges of y_true and y_pred in losses.rB   r   r,   num
   N      ?r-   r]   r\   )rF   rC   tilelinspacer   rR   rU   r_r>   rV   r?   in_y_true_rangeshaperO   rG   in_y_pred_rangerN   r8   )r8   rH   r]   r>   r?   ny_predr\   s           r:   test_loss_boundaryr|      s    	Q	A9EqI'(<(<=	TS$B/ ))vt337778**vt338889'''QA#D$8$89IC1i.){{3!4q!ta&A,./q!ta&A,./q!tS$A.''' YY^^F+NIIVNI;r<   )r   皙?d   r~   r   皙      ?rB   )r   r   r   r~   r   )r~   rr   ?g?)r}   r   r   r}   )              ?r-   )r   r   r   rr   z!loss, y_true_success, y_true_failc                     |D ])  }| j                  t        j                  |g            r)J  |D ])  }| j                  t        j                  |g            s)J  y)z-Test boundaries of y_true for loss functions.N)rw   rC   array)r8   y_true_successy_true_failys       r:   test_loss_boundary_y_truer      T     ##BHHaSM222 ''!666 r<   z!loss, y_pred_success, y_pred_failc                     |D ])  }| j                  t        j                  |g            r)J  |D ])  }| j                  t        j                  |g            s)J  y)z-Test boundaries of y_pred for loss functions.N)ry   rC   r   )r8   y_pred_successy_pred_failr   s       r:   test_loss_boundary_y_predr      r   r<   zDloss, y_true, raw_prediction, loss_true, gradient_true, hessian_truer   g      @ra      g      @g      п)r(   deltag      @       @g      ȿg      ?r   g@xg@xDg     @g     @@g     Bg     B@g     B%   ggT`G<g33333sBg33333sB@g)Pv.<g     B@g?gU`G<g0fՍ<gm@g       +g       gm@rH   )皙?rr   333333?r   r   )g     @r   _eG|>r   c                     | t        j                  |g      t        j                  |g            }| j                  t        j                  |g      t        j                  |g            }| j                  t        j                  |g      t        j                  |g            \  }}	| j	                  t        j                  |g      t        j                  |g            \  }
}|t        |dd      k(  sJ |t        |dd      k(  sJ |9|t        |dd      k(  sJ |	t        |dd      k(  sJ |
t        |dd      k(  sJ ||t        |dd      k(  sJ yy)z7Test losses, gradients and hessians at specific values.rs   V瞯<relabsN)rC   r   gradientloss_gradientgradient_hessianr   )r8   r]   r\   	loss_truegradient_truehessian_trueloss1grad1loss2grad2grad3hesss               r:   test_loss_on_specific_valuesr      sb   x &*288^DT;UVEMMxx!"((N;K2L  E %%xx!"((N;K2L & LE5 ''xx!"((N;K2L ( KE4 F9%U;;;;F9%U;;;; }%UCCCC}%UCCCC}%UCCCCvl5AAAA  r<   readonly_memmapFTdtype_in	dtype_outsample_weightout1out2	n_threadsc                     |        } d}t        | |ddd      \  }	}
|	j                  |      }	|
j                  |      }
|t        j                  dg|z  |      }|t        j                  |	|      }|t        j                  |
|      }|r#t        |	      }	t        |
      }
|t        |      }| j                  |	|
|||	      }|||u sJ 	 | j                  |	|
|||
      }|||u sJ 	 | j                  |	|
||||      \  }}|||u sJ 	 |||u sJ 	 |#| j                  rt        j                  |
|      }| j                  |	|
||||      \  }}|||u sJ 	 |||u sJ 	  | |	|
|       | j                  |	|       | j                  |	|       t        | d      r| j                  |
       t        | d      r-| j                  |	|
||||      \  }}|||u sJ 	 |||u sJ yyy)a0  Test acceptance of dtypes, readonly and writeable arrays in loss functions.

    Check that loss accepts if all input arrays are either all float32 or all
    float64, and all output arrays are either all float32 or all float64.

    Also check that input arrays can be readonly, e.g. memory mapped.
       r}   r   rq   *   r8   rW   rX   rY   rZ   Nr   dtype)r]   r\   r   loss_outr   )r]   r\   r   gradient_outr   )r]   r\   r   r   r   r   )r]   r\   r   r   hessian_outr   r]   r\   r   r]   r   predict_proba)r\   gradient_proba)r]   r\   r   r   	proba_outr   )r^   rL   rC   r   
empty_liker&   r8   r   r   rF   r   fit_intercept_onlyconstant_to_optimal_zeror5   r   r   )r8   r   r   r   r   r   r   r   rW   r]   r\   lgrg   ps                  r:   test_loss_dtyper     s   $ 6DI9FN ]]8$F#**84N #!2(C}}V95}}^9=*622>B$5mDM		%# 	 	A (1922d%# 	 	A (1922d%#  DAq (1922d(1922dD..}}^9=  %# ! DAq (1922d(1922d~]S6G!!}!Mt_%.9t%&"")' # 
1 !,qDy66$ ,qDy66$y 'r<   rangec                    t        | dddd      \  }}|dk(  r2t        j                  d|j                  d   |j                  d   	      }t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }	| j                  ||||
       | j                  j                  ||||
       t        ||       | j                  ||||       | j                  j                  ||||       t        ||       | j                  j                  |||||       | j                  j                  |||||       t        ||       t        ||       | j                  |||||       | j                  j                  |||||	       t        ||       t        ||	       y)z:Test that Python and Cython functions return same results.   r   r   r   r   r   r,   r   ro   r]   r\   r   r   r]   r\   r   r   r]   r\   r   r   r   r]   r\   r   r   r   N)r^   rC   ru   rx   r   r8   r1   r   r   r   r   )
r8   r   r]   r\   out_l1out_l2out_g1out_g2out_h1out_h2s
             r:   test_loss_same_as_C_functionsr     s     :FN Av||AFLLOL]]6"F]]6"F]]>*F]]>*F]]>*F]]>*FII%#	   	JJOO%#	   FF#MM%#	   	JJ%#	   FF#JJ%#   	JJ%#   FF#FF#%#   	JJ%#    FF#FF#r<   c                 F   t        | ddd|      \  }}|dk(  r2t        j                  d|j                  d   |j                  d         }t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }	t        j                  |      }
| j                  ||||	      }| j                  ||||
      }| j                  |||||      \  }}| j                  ||||	|
      \  }}t        ||       t        ||       t        j                  ||      sJ t        ||       t        j                  ||      sJ t        ||       t        ||       t        ||       t        j                  ||      sJ t        ||       t        j                  ||      sJ t        ||	       t        j                  ||	      sJ t        | d      r| j                  sJ t        j                  |      }t        j                  |      }| j                  |||||      \  }}t        ||       t        ||       t        ||       t        t        j                  |d      dd       yy)zTest that loss and gradient are the same across different functions.

    Also test that output arguments contain correct results.
    r   r   r   r   r   r,   r   ro   r   r   r   r   r   r]   r\   r   r   r   axisdy=)rtolN)r^   rC   ru   rx   r   r8   r   r   r   r   r   shares_memoryr5   rF   r   sum)r8   r   global_random_seedr]   r\   r   r   r   r   out_g3out_h3l1g1l2g2g3h3out_g4	out_probag4probas                        r:    test_loss_gradients_are_the_samer   ?  s    :FN Av||AFLLOL]]6"F]]6"F]]>*F]]>*F]]>*F]]>*F	%#	 
 
B 
%#	 
 
B %#   FB ""%# # FB Br6"B'''r6"B'''BBr6"B'''r6"B'''r6"B'''t%&!!!!~.MM.1	'')' ( 
	E 	F#By)u1-qu= 'r<   onesrD   c           	      n   d}t        | |dd|      \  }}|dk(  r&t        j                  |t        j                        }nNt        j                  j                  |      }|j                  |      j                  t        j                        }t        | j                  |||      || j                  ||d	      z         | j                  ||d	      \  }}| j                  |||      \  }	}
t        ||z  |	       | j                  st        ||z  |
       nt        ||d	d	d	f   z  |
       | j                  ||d	      \  }}| j                  |||      \  }
}| j                  st        ||z  |
       t        ||z  |       y	t        ||d	d	d	f   z  |
       t        ||d	d	d	f   z  |       y	)
zTest sample weights in loss, gradients and hessians.

    Make sure that passing sample weights to loss, gradient and hessian
    computation methods is equivalent to multiplying by the weights.
    r   r   r   r   r   )rx   r   rA   r   N)r^   rC   r   float64rD   rE   normalrL   r   r8   r   rF   r   )r8   r   r   rW   r]   r\   r[   lossesr   	losses_swgradient_swhessian
hessian_sws                r:   test_sample_weight_multipliesr     s    I9FN irzzBii##$67

	
299"**E		)' 	 	

 	
)))  
	
 ))% * FH
 "//%# 0 I{
 F]*I6=0+>=D#99;G--% . Hg
 #33%# 4 K
 =0+>-/<=D#99;G-4"88*Er<   c                    t        | dddd      \  }}|j                  dk(  r|dddf   }t        | j                  ||      | j                  ||             t        | j	                  ||      | j	                  ||             t        | j                  ||      | j                  ||             t        | j                  ||      | j                  ||             yy)	z5Test that reshaped raw_prediction gives same results.r   r   r   r   r   r,   Nrs   )r^   ndimr   r8   r   r   r   )r8   r]   r\   raw_prediction_2ds       r:   test_graceful_squeezingr     s     :FN a*1d73IIV4EIFIIVNIC	
 	f=NOf^L	
 	MM8IMJMMMG	
 	!!@Q!R!!!O	
  r<   c                    | j                   st        j                  g d      }t        | j                  t
              r{d}| j                  j                  }| j                  j                  s||z   }| j                  j                  }| j                  j                  s||z
  }t        j                  |||      }| j                  j                  |      }nt        j                  | j                        j                  t               }t        j"                  | j                  | j                  ft        j$                  d       t               }t        j$                  d      |j&                  dd| j                  dz   <   |dk(  r2t        j(                  d|j*                  d   |j*                  d   	      }| j-                  |||
      }| j/                  ||      }t1        || dd       y)z~Test value of perfect predictions.

    Loss of y_pred = y_true plus constant_to_optimal_zero should sums up to
    zero.
    )r   r   r   r~   rB   rq   绽|=rq   )rx   r`   r   Nr,   r   r   ro   r   r   +=r   )atolr   )rF   rC   r   r2   rN   r   rO   r>   rU   r?   rV   clipinverserK   rH   rL   rM   fullexprJ   ru   rx   r8   r   r   )	r8   r   r\   rf   r>   r?   r]   
loss_valueconstant_terms	            r:   test_loss_of_perfect_predictionr	    s    "<=dii.C&&**C''55Ci'',,D''66czWW^S$?N"">2 4>>*11%8 >>4>>2r
{

 68VVBZ1t~~112Av||AFLLOL%#  J
 11] 2 M
 JUGr<   c                 "   
 d}t         |dd|      \  dk(  r2t        j                  dj                  d   j                  d          j	                  	      \  }}|j                  j                  k(  sJ |j                  j                  k(  sJ  j
                  sV fd
}t        |d      }t        ||dd        fd}t        |d      }	 j                  ryt        ||	dd       yt         j                        D ]w  

 fd}t        |dd
f   d      }t        |dd
f   |dd       
 fd}t        |dd
f   d      }	 j                  rbt        |dd
f   |	dd       y y)zTest gradients and hessians with numerical derivatives.

    Gradient should equal the numerical derivatives of the loss function.
    Hessians should equal the numerical derivatives of gradients.
    r   r   r   r   r   r,   r   ro   r   c                 ,    j                  |       S Nr   r8   re   r8   r   r]   s    r:   	loss_funcz6test_gradients_hessians_numerically.<locals>.loss_funcG  s"    99 +   r<   ư>)rf   h㈵>r   r   r  c                 ,    j                  |       S r  r   r  s    r:   	grad_funcz6test_gradients_hessians_numerically.<locals>.grad_funcQ  s"    == + !  r<   c                 ^    j                         }| |d d f<   j                  |      S r  )copyr8   re   rawkr8   r\   r   r]   s     r:   r  z6test_gradients_hessians_numerically.<locals>.loss_funcf  s=    $))+AqD	yy!#&"/ !  r<   Nh㈵>c                 l    j                         }| |d d f<   j                  |      d d f   S r  )r  r   r  s     r:   r  z6test_gradients_hessians_numerically.<locals>.grad_funcr  sK    $))+AqD	}}!#&"/ %  Q$	 r<   )r^   rC   ru   rx   r   rF   rl   r   approx_hessianr   rH   )r8   r   r   rW   r   rg   r  	g_numericr  	h_numericr  r\   r]   s   ``        @@@r:   #test_gradients_hessians_numericallyr   (  s    I9FN Av||AFLLOL  %# ! DAq 77n*****77n*****	 )NM	94e<	 )NM	Ayt%@ t~~&A  -Yq!t8LRVWIAadGYTF  -Yq!t8LRVWI""!Q$EJ9 'r<   zloss, x0, y_true)	)squared_errorg       r   )r!  g     @]@g?)r!  r   r   )binomial_lossr   r~   )r"  ir   )r"     r   )poisson_lossrb   r   )r$  r   r   )r$  g      6g      $@c                     t            d       t        j                  gt        j                        t        j                  |gt        j                        }dt        j                  dt        j                  f fd}dt        j                  dt        j                  f fd}dt        j                  dt        j                  f fd}t        ||||d	d
      }j                         |j                         }t         j                  j                  |             t         ||      dd       t         j                  |      dd       y)ac  Test that gradients are zero at the minimum of the loss.

    We check this on a single value/sample using Halley's method with the
    first and second order derivatives computed by the Loss instance.
    Note that methods of Loss instances operate on arrays while the newton
    root finder expects a scalar or a one-element array for this purpose.
    Nr   r   re   returnc                 P    j                  |       j                        z   S )zCompute loss plus constant term.

        The constant term is such that the minimum function value is zero,
        which is required by the Newton method.
        rs   r]   )r8   r   re   r8   r]   s    r:   rd   ztest_derivatives.<locals>.func  s6     yy!  
)))89 	9r<   c                 *    j                  |       S )Nrs   r  r*  s    r:   fprimez test_derivatives.<locals>.fprime  s    }}F1}==r<   c                 0    j                  |       d   S )Nrs   r,   )r   r*  s    r:   fprime2z!test_derivatives.<locals>.fprime2  s    $$F1$EaHHr<   r   gHj>)x0r,  r.  maxitertolr   r  r  rs   gƠ>)r   rC   r   r   ndarrayr	   ravelr   rN   r  r   )r8   r/  r]   rd   r,  r.  optimums   ` `    r:   test_derivativesr6    s   4 4=t,DXXvhbjj1F	2$bjj	)B9

 9rzz 9>"** > >I2:: I"** I G \\^FmmoGDII%%g.7DM151DMMMH!RVWr<   c                     d j                   s2 j                  j                  t        j                  dd            nGt        j
                        j                  t        j                         j                  z  dddd<   dk(  rt        j                  d	d
       j                        } fd} j                   st        |dddi      } j                  t        j                  |            }|j                  t               k(  sJ |j                  j                  k(  sJ t!        |       |t#        |j$                  d      k(   |j'                         t#        dd      k(   yt)        |t        j*                   j                        dddidt-        t        j.                  d j                  f      dd            } j                  t        j0                  |df            }|j                  j                  k(  sJ t!        |       t3        ||j$                  dd       t3        |j'                  d      dd       y)zzTest that fit_intercept_only returns the argmin of the loss.

    Also test that the gradient is zero at the minimum.
    2   r   ro   r   Nr   r   r~   r-   r   c                     j                   st        j                  |       }n6t        j                  t        j                  | j
                  f            } |      S )N)rx   r`   rx   r   )rF   rC   r  ascontiguousarraybroadcast_torH   )re   r\   r8   rW   r   r]   s     r:   funz%test_loss_intercept_only.<locals>.fun  s[    !!WWI1EN11)T^^)DEN )'
 	
r<   gHz>r0  r   )r1  optionsr   r   -q=)r   gvIh%<=SLSQPr,   )r1  r?  methodconstraintsr  r  r   r2  )rF   rN   r  rC   ru   rK   rL   r   rH   r   r   r   rc   rx   tupler   r   r   re   r   r   zerosr   r   rt   r   )r8   r   ar>  optgradrW   r]   s   ``    @@r:   test_loss_intercept_onlyrJ    s    I""2;;r1)#DE9%,,RZZ84>>IssC	:v]KA
 cti5EF}}<<2'  

 ww%'!!!ww&,,&&&!	VCEEt$$
fQE** HHdnn&$(!T^^1D)Eq!L
 }}771y!n5'  

 ww&,,&&&!355t%8a(!%8r<   zloss, func, random_distr   c                 0    t        j                  | d      S )N   )q)rC   
percentile)re   s    r:   <lambda>rO    s    r}}Q"/Er<   poissonexponentialbinomialc                 ^   t         j                  j                  |      }|dk(  r|j                  ddd      }n t	        ||      d      }| j                  |      }t        |       |t        | j                  j                   ||                  k(  sJ | j                  j                  |      t         ||            k(  sJ t        | t              r%t        | j                  j                  |      |       | j                  j                  rB|j                  | j                  j                          | j                  |      }t        |       | j                  j"                  rC|j                  | j                  j$                         | j                  |      }t        |       yy)zTest that fit_intercept_only returns the correct functional.

    We test the functional for specific, meaningful distributions, e.g.
    squared error estimates the expectation of a probability distribution.
    rR  r,   rr   r   rA   r)  N)rC   rD   rE   rR  getattrr   r   r   rN   r  r2   r   r   rR   rU   fillr>   rV   r?   )r8   rd   random_distr   r[   y_trainbaseline_predictions          r:    test_specific_fit_intercept_onlyrY    sf   $ ))

 2
3Cj ,,q#C,0+'#{+5111A )*&W)F"GGGG9901VDM5JJJJ$%		))*=>@ST ))T))--."55W5E-.**T))../"55W5E-. +r<   c            	         t         j                  j                  d      } d}t        |      }| j	                  d|dz   d      j                  t         j                        }|j                  |      }|j                  |fk(  sJ t        j                  ||j                        }t        |      D ]  }||k(  j                         ||<    t        |t        j                  |      t        j                  t        j                  |            z
         t        |d	d	d	f   |j                  j                  |d	d	d	f                t        j                  d
      t        j                   d
      fD ]Y  }|j                  t         j                        }|j                  |      }|j                  |j                  k(  sJ t#        |       [ y	)zATest that fit_intercept_only returns the mean functional for CCE.r   r   r   r,   r   rA   r)  r   Nrq   r;  )rC   rD   rE   r   randintrL   r   r   rx   rF  r   r   meanr   logrN   r   r   )r[   rH   r8   rW  rX  r   r  s          r:   (test_multinomial_loss_fit_intercept_onlyr^  1  sk   
))


"CI3D kk!Y]k5<<RZZHG111A$$444
'--0A91""$! 'RWWRVVAY5G)GH'a0$))..472LMHH2&b(9:..,"55W5E"((GMM999-.	 ;r<   c                     d}d}t        |      }t        |||       \  }}t        j                  dd|      }|j                  j                  |||      }|j                  |||      }t        ||       y	)
a  Test that Multinomial cy_gradient gives the same result as gradient.

    CyHalfMultinomialLoss does not inherit from CyLossFunction and has a different API.
    As a consequence, the functions like `loss` and `gradient` do not rely on `cy_loss`
    and `cy_gradient`.
    r   r   r   r8   rW   rZ   r~   r-   ro   r   N)r   r^   rC   ru   r1   _test_cy_gradientr   r   )	r   rW   rH   r8   r]   r\   r   r   r   s	            r:   test_multinomial_cy_gradientrb  H  s     II3D9FN
 KKQI6MJJ((%# ) E
 MM%#  E
 E5!r<   c                    t         j                  j                  |       }d}t               }t	        d      }|j                  dd|      j                  t         j                        }|j                  |      }t        j                  |df      }d|z  |dddf<   d|z  |ddd	f<   t        |j                  ||
      |j                  ||
             y)zKTest that multinomial loss with n_classes = 2 is the same as binomial loss.r   r-   r   r   rA   g      Nrr   r,   rs   )rC   rD   rE   r   r   r[  rL   r   r   rG   r   r8   )r   r[   rW   binommultinomrW  r\   raw_multinoms           r:   "test_binomial_and_multinomial_lossrg  f  s    
))

 2
3CIE"Q/Hkk!QYk/66rzzBGZZYZ/N88YN+L.LA~-LA

'.
AW\Br<   r]   )r   r   r   )r   r,   r,   r{   )g      r   r   )r.   rB   rB   c                     d }d }t               }| j                  |      } |j                  |      }| |f} || t         ||       k(  sJ t         |j                  |  ||        y)a  Test that both formulations of the binomial deviance agree.

    Often, the binomial deviance or log loss is written in terms of a variable
    z in {-1, +1}, but we use y in {0, 1}, hence z = 2 * y - 1.
    ESL II Eq. (10.18):

        -loglike(z, f) = log(1 + exp(-2 * z * f))

    Note:
        - ESL 2*f = raw_prediction, hence the factor 2 of ESL disappears.
        - Deviance = -2*loglike + .., but HalfBinomialLoss is half of the
          deviance, hence the factor of 2 cancels in the comparison.
    c           	          d| z  dz
  }t        j                  t        j                  dt        j                  | |z        z               S Nr-   r,   )rC   r\  r]  r  r   raw_predzs      r:   alt_lossz:test_binomial_vs_alternative_formulation.<locals>.alt_loss  s;    EAIwwrvva"&&!h"77899r<   c                 P    d| z  dz
  }| dt        j                  ||z        z   z  S rj  )rC   r  rk  s      r:   alt_gradientz>test_binomial_vs_alternative_formulation.<locals>.alt_gradient  s.    EAIrQH--..r<   N)r   rL   r   r   r   )r]   r{   global_dtypern  rp  bin_lossdatums          r:   (test_binomial_vs_alternative_formulationrt  w  sv    ":/
  !H]]<(F]]<(FVEUvh&67777%H%%u-|U/CDr<   c           
         d}t        | |dd|      \  }}t        | d      rU| j                  |      }|j                  || j                  fk(  sJ t        j                  |d      t        dd	      k(  sJ t        | d
      rddt        j                  |      ft        j                  |      dft        j                  |      t        j                  |      ffD ]  \  }}| j                  ||d||      \  }}|j                  || j                  fk(  sJ t        j                  |d      t        dd	      k(  sJ t        || j                  ||dd              yy)z<Test that predict_proba and gradient_proba work as expected.r   r   r   r   r   r,   r   r   r@  r   )NNNr   r   )r^   r5   r   rx   rH   rC   r   r   r   r   r   r   )r8   r   rW   r]   r\   r   rI  s          r:   test_predict_probarv    sl    I9FN t_%"">2{{y$..9999vve!$qe(<<<<t%&2==01]]>*D1]]>*BMM.,IJ	
KD% ---"! . KD% ;;9dnn"====66%a(F1%,@@@@!#1"&!%	  
 'r<   r   order)CFc                    d}|dk(  rt        j                  |      } | |      } | j                  |||      \  }}| j                  r#|j                  |fk(  sJ |j                  dk(  slJ | j
                  r:|j                  || j                  fk(  sJ |j                  || j                  fk(  s&J |j                  |fk(  sJ |j                  |fk(  sJ |j                  |k(  sJ |j                  |k(  sJ |dk(  r1|j                  j                  sJ |j                  j                  sJ y|j                  j                  sJ |j                  j                  sJ y)zTest that init_gradient_and_hessian works as expected.

    passing sample_weight to a loss correctly influences the constant_hessian
    attribute, and consequently the shape of the hessian array.
    r   r   r&  )rW   r   rw  )r,   rx  N)rC   r   init_gradient_and_hessianconstant_hessianrx   rF   rH   r   flagsc_contiguousf_contiguous)r8   r   r   rw  rW   r   r   s          r:   test_init_gradient_and_hessiansr    s[    I	*m,D66 7 Hg
 ~~)---}}$$$			~~)T^^!<<<<}}DNN ;;;;}},,,}},,,>>U"""==E!!!|~~****}}))))~~****}}))))r<   zparams, err_msgz+Valid options for 'dtype' are .* Got dtype=z	 instead.c                      |        } t        j                  t        t        f|      5   | j                  dddi|\  }}ddd       y# 1 sw Y   yxY w)zDTest that init_gradient_and_hessian raises errors for invalid input.matchrW   r   N )pytestraises
ValueError	TypeErrorr{  )r8   paramserr_msgr   r   s        r:   %test_init_gradient_and_hessian_raisesr    sI     6D	
I.g	>:D::QQQ&Q' 
?	>	>s   A

Azloss, params, err_type, err_msgr(   z4quantile must be an instance of float, not NoneType.zquantile == 0, must be > 0.zquantile == 1.1, must be < 1.c                 l    t        j                  ||      5   | di | ddd       y# 1 sw Y   yxY w)z/Test that loss raises errors for invalid input.r  Nr  )r  r  )r8   r  err_typer  s       r:   #test_loss_init_parameter_validationr     s(    B 
xw	/v 
0	/	/s   	*3c                     d}t        | |ddd      \  }}t        j                  |       }t        j                  |      } | ||      t	         |||            k(  sJ y)z Test that losses can be pickled.r   r   r   r   r   rs   N)r^   pickledumpsloadsr   )r8   rW   r]   r\   pickled_lossunpickled_losss         r:   test_loss_pickler  %  sp     I9FN <<%L\\,/Nvn=f^DB   r<   r   )r)   r   r,   r   r-   rB   c                    t        |       }t        |       }d}t        ||d      \  }}|j                  j	                  |      }|j                  ||      |j                  |      z   }|j                  ||      |j                  |      z   }t        ||       |j                  ||      \  }	}
|j                  ||      \  }}t        |	||z         t        |
||z  |dz  |z  z          y)zCTest for identical losses when only the link function is different.r*   rq   r   r`  rs   r-   N)	r   r   r^   rN   r  r8   r   r   r   )r   half_tweedie_loghalf_tweedie_identityrW   r]   r\   r{   loss_logloss_identitygradient_loghessian_loggradient_identityhessian_identitys                r:   %test_tweedie_log_identity_consistencyr  7  s2    'Q/3!<I9FN ""**>:F  $$n % 11&9:H *..f / 66v>?M Hm, !1 A An !B !L+ +@*P*Pf +Q +'' L&+<"<=V//&!)>N2NNr<   z array_api_loss_class, loss_class)r   r   r   method_name)__call__r   r8   r   use_sample_weightz"namespace, device_name, dtype_namec           
      d   d }t        |||      \  }}	t        |      }
|dk(  rdnd}d}d} | ||	      } |       }t        ||dd	|
      \  }}|j                  |      }|j                  |      }|j	                  ||	      }|j	                  ||	      }|rft
        j                  j                  |      }|j                  dd|      j                  dd       j                  |      }|j	                  ||	      }nd }d }t        ||      }t        ||      } ||||      }t        d      5   ||||      }|dk(  rt        j                  ||      sCJ t        |t              r#t        ||      D ]  \  }} |||||||
        n |||||||
       d d d        y # 1 sw Y   y xY w)Nc                     t        t        | t        d      |||       | j                  |j                  k(  sJ t	        |       t	        |      k(  sJ y )Ncpuxpr$   r  )r   r!   rC   r   array_api_device	result_xp	result_npraw_prediction_xpr  r   r  s         r:   _assert_array_api_resultz5test_loss_array_api.<locals>._assert_array_api_result~  sT     	I"U3YTPT	
 "3"9"9999	*.>?P.QQQQr<   float32r  r   r   r   r  r   )ir8  r   r#   r   r   rA   r   r   T)array_api_dispatchr  r  )r%   r    r^   rL   asarrayrC   rD   rE   rI   r  rT  r   iscloser2   rE  zip)array_api_loss_class
loss_classr  r  	namespacedevice_name
dtype_namer  r  r$   r  r   random_seedrW   array_api_loss_instanceloss_instancer]   r\   	y_true_xpr  r[   sample_weight_npsample_weight_xprC  array_api_methodr  r  res_xpres_nps                                r:   test_loss_array_apir  d  s   4R &ijIJB*%D*4DKI2bHLM9FN ]]:&F#**:6N

6&
1I

>&
Aii##K0KKAIK.33At<CCJO 	 ::&6v:F]K0F6DnDTI 
4	0$,*
	 :%::i333)U+&))Y&?NFF,"("(*;!! '@ )''&7- 
1	0	0s   3A*F&&F/c           	      *   t        j                  d      }d|j                  _        t	        j
                  ddd      }t        | ||      \  }}|D ]  }|dk(  r|j                  ||j                  |      }n|j                  ||j                  |      }t        t        ||j                  |      |            }	t        |j                  d	|j                  |      z               }
|
d
kD  sJ |	t        j                  |
|dk(  rdndd
      k(  rJ  y )Nmpmathr   i(   i,  r  )r   r$   )r\   raw_prediction_expr  r,   r   r  rA  r   )r  importorskipmpprecrC   ru   r%   r  r  r   rM   r   r  r]  r   )r  r  r  r  values_to_testr  r$   valuere   r  result_mpmaths              r:   test_log1pexpr    s   
   *FFIIN[[b#.N%ijIJB"

5

6
BA

5

6
BA #%66!9
	 fjjVZZ->)>?@q   FMM"i/U
 
 	
 
!  r<   c                  >   t        j                  t        t         j                        D  cg c]  \  } }| j	                  d      r| }} }t        |      dkD  sJ d       |D ]2  }|j                  dk(  rJ |j                   d|j                  d        yc c}} w )a  Check that Cython extension types in _loss have the correct __module__.

    When _loss_cython_tree in meson.build is missing __init__.py files, Cython
    can not detect the package hierarchy and set __module__ = '_loss' instead
    of 'sklearn._loss._loss' on all Cy* extension types, e.g.
    `CyHalfMultinomialLoss`. This breaks downstream tools like skops that rely
    on __module__ for serialization.
    Cyr   z+No Cy* classes found in sklearn._loss._losszsklearn._loss._lossz.__module__ == z , expected 'sklearn._loss._loss'N)inspect
getmembers_loss_moduleisclass
startswithlen
__module__r4   )r9   obj
cy_classesclss       r:   test_cy_loss_classes_moduler    s     !++L'//JJID#??4  	J  
 z?QM MM~~!66 	
||nOCNN+= >- .	
6 s   B)r   r   r   )gr  r  numpyrC   r  numpy.testingr   r   r   scipy.optimizer   r   r   r	   scipy.specialr
   sklearnr   sklearn._lossr   r  sklearn._loss.linkr   r   sklearn._loss.lossr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   sklearn.utilsr   sklearn.utils._array_apir    r!   r"   r$   r  sklearn.utils._testingr%   r&   r'   listvalues
ALL_LOSSESLOSS_INSTANCESr;   r^   rl   markparametrizer|   infY_COMMON_PARAMSY_TRUE_PARAMSY_PRED_PARAMSr   r   r]  log1pr   r  r   r   r   r   r   r   r	  r   r6  rJ  r\  medianrY  r^  rb  rg  r   rt  rv  r  int64r  r  r  r  r  r  r  r  r  r  s   0r:   <module>r     s        =   $ " / @    $ , 
  .'.."#
%/0ZT$&Z0 t$!!!#!$!$!$#&   CE""JU 5GH < I <L ,w.?@_)RVVGRVV+<=]'266'266):;[%'89c
bffWb$$?@_sCjBFF7Ba"@A2c
bffWbff,=>1SzRVVGRVV+<=3#srvvgr4-HI1SzRVVGRq"&&+IJ1SzRVVGRq"&&+IJ2&c
bffWbff4EF1%'>"&&"&&@QR3'#srvvgr45PQ1%SzRVVGRq"&&3QR1%SzRVVGRq"&&3QRBFF7B266*BCB"&&"c266 :;'2 R [1#r241ay"-3!b)2&<1%ay"53'!b1!Q$M2. QC 2M21r=13aS)2&M:1%}b93'aS1aV$S#JA/ 'm#7	7 'm#7	7 Js		S#q!Q/s	#sCd3s 
c	"Cad;s 
d	#S#~xN	s
 
d	#S#xEs 
Cq	)3_dDQs 
Cq	)3ZtLs 
	CAFBFF1I,=uaHs 
#vrvvay&"&&)e*;YNs 
q	!3q	3DdDQs 
!q	)3QVRVVAY5FdSs 
!q	)3VRVVAY5FdSs $!,)	
s, BFF1IBHHQK$**	
+sr 
	S%Aq1sst 
	S%r15usv 
	S$1a0wsx 
	S$R3ysz 
	S%r15{s| 
	S%Y8MN}s~ 
	S%F+@*AA*EFs@ 
	S%y:OPAsB 
	S%F+@*AA*EFCsD 
	S$I7LMEsF 
	S$E*?)@1)DEGsH 
	S$a1FGIsJ 
	S%3JKKsL 
	S$1a0MsN 
	S$a3OsR $#	
Qs` 
	S%Aq1asb 
	S#q!Q/csd 
	S#sAq1esh  !,o&,	
gsx  !,o&,	
wsH  !,o&,	
GsX  !,n%.	
Wsh 	m  wpBqwpB6 ,*UDM:bjj"**%=>rzz2::&>?4)4$+$+q!f-Y7 . , , 5 @ ? ; -Y7x 5GH4/:K$ ; IK$\ 5GH4/:L> ; IL>^ 5GH68*<=BF > IBFJ 5GH
 I
< 5GH4/:-H ; I-H` 5GH4/:VK ; IVKr " +X #$+X\ 5GH4/:>9 ; I>9B 		RWWh/	"))X.	d	#%ExP		BGGY/	"''=1		BGG]3		RWWj1//>/."<" HBHH[$98288K;P#QRHBHH^$<hbhh{>S#TUE V SED 5GH( I(V ,4/:2::rzz":;*-!* . < ; -!*H , bhh9"((9M	
R -R % B		
 O)		
 
z3'5TUB		
 O)		
 
Z%z3RS5>?> 5GH I" 56) 7)X &	!#34	$&9:	 /2
 	G   D ,udm<(-/P	 ="Pf (-/
	
8
e- 1s   ${