o
    }oi-                     @  s
  d dl mZ d dlZd dlZd dlZd dlZd dlmZ e	dej
 ZeeZe	dej
 ZedZd/d
dZd/ddZedd0ddZd1ddZedd0ddZd1ddZd2ddZd3ddZd4d d!Zd5d$d%Z	 	&	d6d7d+d,Z	 	&d8d9d-d.ZdS ):    )annotationsNerf      log_p
np.ndarraylog_qreturnc                 C  s   t | |S N)np	logaddexpr   r	    r   S/home/ubuntu/.local/lib/python3.10/site-packages/optuna/samplers/_tpe/_truncnorm.py_log_sum3   s   r   c                 C  s   | t t ||    S r   )r   log1pexpr   r   r   r   	_log_diff7   s   r   i  afloatc                 C  sX   | d }|dk rdt |  }|S |dk r!ddt |  }|S ddt |  }|S )N;f?g;f      ?g;f?      ?)matherfcr   )r   xyr   r   r   _ndtr_single;   s   r   c                 C  s   ddt | d   S )Nr   r   r   r   r   r   r   _ndtrI   s   r    c           	      C  s   | dkr
t |   S | dkrtt | S d| d  t|   dtdtj   }d}d}d}d}d| d  }d}d	}t|| tjjkrn|d7 }|}| }||9 }|d| d 9 }||| | 7 }t|| tjjksG|t| S )
N   i      r   r   g        r      r   )r   r   logpiabssys
float_infoepsilon)	r   log_LHS
last_totalright_hand_side	numeratordenom_factor
denom_conssignir   r   r   _log_ndtr_singleN   s*   ,r2   c                 C  s   t tdd| tS )Nr#   )r   
frompyfuncr2   astyper   r   r   r   r   	_log_ndtri   s   r5   r   c                 C  s   | d  d t  S )Nr   g       @)_norm_pdf_logC)r   r   r   r   _norm_logpdfm      r7   bc                   s   |dk}| dk}||B  }ddd d fdd	}dd
d}t j| t jt jd}| |  }jr8 ||| ||< | |  }	jrH||	|| ||< | |  }
jrX||
|| ||< t |S )z3Log of Gaussian probability mass within an intervalr   r   r   r9   r
   c                 S  s   t t|t| S r   )r   r5   r   r9   r   r   r   mass_case_leftz   r8   z'_log_gauss_mass.<locals>.mass_case_leftc                   s    | |  S r   r   r:   r;   r   r   mass_case_right}   s   z(_log_gauss_mass.<locals>.mass_case_rightc                 S  s   t t|  t|  S r   )r   r   r    r:   r   r   r   mass_case_central   s   z*_log_gauss_mass.<locals>.mass_case_central)
fill_valuedtypeNr   r   r9   r   r
   r   )r   	full_likenan
complex128sizereal)r   r9   	case_left
case_rightcase_centralr=   r>   outa_lefta_right	a_centralr   r<   r   _log_gauss_massq   s   



rN   r   c           
      C  s  | dk}|   }tt| |  ||< t| }t|dk  }d jr4td|| t   ||< t|dk }d jrPt	 tt||   ||< t
dD ].}t|}d|d  t }|| t||  }	||	8 }tt|	dt| k r nqT||  d	9  < |S )
a\	  
    Use the Newton method to efficiently find the root.

    `ndtri_exp(y)` returns `x` such that `y = log_ndtr(x)`, meaning that the Newton method is
    supposed to find the root of `f(x) := log_ndtr(x) - y = 0`.

    Since `df/dx = d log_ndtr(x)/dx = (ndtr(x))'/ndtr(x) = norm_pdf(x)/ndtr(x)`, the Newton update
    is x[n + 1] := x[n] - (log_ndtr(x) - y) * ndtr(x) / norm_pdf(x).

    As an initial guess, we use the Gaussian tail asymptotic approximation:
        1 - ndtr(x) \simeq norm_pdf(x) / x
        --> log(norm_pdf(x) / x) = -1/2 * x**2 - 1/2 * log(2pi) - log(x)

    First recall that y is a non-positive value and y = log_ndtr(inf) = 0 and
    y = log_ndtr(-inf) = -inf.

    If abs(y) is very small, we first derive -x such that z = log_ndtr(-x) and then flip the sign.
    Please note that the following holds:
        z = log_ndtr(-x) --> z = log(1 - ndtr(x)) = log(1 - exp(y)) = log(-expm1(y)).
    Recall that as long as ndtr(x) = exp(y) > 0.5 --> y > -log(2) = -0.693..., x becomes positive.

    ndtr(x) = exp(y) \simeq 1 + y --> -y \simeq 1 - ndtr(x). From this, we can calculate:
        log(1 - ndtr(x)) \simeq log(-y) \simeq -1/2 * x**2 - 1/2 * log(2pi) - log(x).
    Because x**2 >> log(x), we can ignore the second and third terms, leading to:
        log(-y) \simeq -1/2 * x**2 --> x \simeq sqrt(-2 log(-y)).
    where we take the positive `x` as abs(y) becomes very small only if x >> 0.
    The second order approximation version is sqrt(-2 log(-y) - log(-2 log(-y))).

    If abs(y) is very large, we use log_ndtr(x) \simeq -1/2 * x**2 - 1/2 * log(2pi) - log(x).
    To solve this equation analytically, we ignore the log term, yielding:
        log_ndtr(x) = y \simeq -1/2 * x**2 - 1/2 * log(2pi)
        --> y + 1/2 * log(2pi) = -1/2 * x**2 --> x**2 = -2 * (y + 1/2 * log(2pi))
        --> x = sqrt(-2 * (y + 1/2 * log(2pi))

    For the moderate y, we use Eq. (13), i.e., standard logistic CDF, in the following paper:

    - `Approximating the Cumulative Distribution Function of the Normal Distribution
      <https://jsr.isrt.ac.bd/wp-content/uploads/41n1_5.pdf>`__

    The standard logistic CDF approximates ndtr(x) with:
        exp(y) = ndtr(x) \simeq 1 / (1 + exp(-pi * x / sqrt(3)))
        --> exp(-y) \simeq 1 + exp(-pi * x / sqrt(3))
        --> log(exp(-y) - 1) \simeq -pi * x / sqrt(3)
        --> x \simeq -sqrt(3) / pi * log(exp(-y) - 1).
    g{Gzr   g       d   r"   r   g:0yE>)copyr   r$   expm1
empty_likenonzerorE   sqrtr6   _ndtri_exp_approx_Cranger5   r   allr&   )
r   flippedzr   
small_indsmoderate_inds_
log_ndtr_xlog_norm_pdf_xdxr   r   r   
_ndtri_exp   s$   /
 rb   qnp.ndarray | floatc                 C  s   t | ||\} }}t | ||\} }}|dk }| }t||}ddd	}dd
d}t | }| |  }	jrE||	|| || || ||< | |  }
jr[||
|| || || ||< || dk || dk< || dk || dk< tj|||k< |S )a=  
    Compute the percent point function (inverse of cdf) at q of the given truncated Gaussian.

    Namely, this function returns the value `c` such that:
        q = \int_{a}^{c} f(x) dx

    where `f(x)` is the probability density function of the truncated normal distribution with
    the lower limit `a` and the upper limit `b`.

    More precisely, this function returns `c` such that:
        ndtr(c) = ndtr(a) + q * (ndtr(b) - ndtr(a))
    for the case where `a < 0`, i.e., `case_left`. For `case_right`, we flip the sign for the
    better numerical stability.
    r   rc   r   r   r9   log_massr
   c                 S  s    t t|t| | }t|S r   )r   r5   r   r$   rb   rc   r   r9   re   	log_Phi_xr   r   r   ppf_left   s   zppf.<locals>.ppf_leftc                 S  s&   t t| t|  | }t| S r   )r   r5   r   r   rb   rf   r   r   r   	ppf_right   s   
zppf.<locals>.ppf_rightr#   N)
rc   r   r   r   r9   r   re   r   r
   r   )r   
atleast_1dbroadcast_arraysrN   rT   rE   r   rC   )rc   r   r9   rG   rH   re   rh   ri   rJ   q_leftq_rightr   r   r   ppf   s    



rn   r#   locscalerandom_statenp.random.RandomState | Nonec                 C  sD   |pt j }t | |||j}|jdd|d}t|| || | S )z
    This function generates random variates from a truncated normal distribution defined between
    `a` and `b` with the mean of `loc` and the standard deviation of `scale`.
    r   r#   )lowhighrE   )r   randomRandomState	broadcastshapeuniformrn   )r   r9   ro   rp   rq   rE   	quantilesr   r   r   rvs  s   r{   c                 C  s~   | | | } t | ||\} }}t| t|| t | }t | ||\} }}t j||k| |k | |kB gt jt j g|dS )N)default)	r   rj   r7   rN   r$   rk   selectrC   inf)r   r   r9   ro   rp   rJ   r   r   r   logpdf  s
   .r   )r   r   r	   r   r
   r   )r   r   r
   r   )r   r   r
   r   )r   r   r
   r   rA   )r   r   r
   r   )rc   r   r   rd   r9   rd   r
   r   )r   r#   N)r   r   r9   r   ro   rd   rp   rd   rq   rr   r
   r   )r   r#   )r   r   r   rd   r9   rd   ro   rd   rp   rd   r
   r   )
__future__r   	functoolsr   r'   numpyr   optuna.samplers._tpe._erfr   rV   r%   _norm_pdf_Cr$   r6   rW   _log_2r   r   	lru_cacher   r    r2   r5   r7   rN   rb   rn   r{   r   r   r   r   r   <module>   s:   !








'
H0