o
    /wiK                     @  s  d dl mZ d dl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 dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ erd dlmZ d dlmZ d dlZd dlm  mZ d dlm  m Z  d dl!m  m"Z" d dl#m  m$Z$ d dl%m  m&Z' d dl(m)Z) d dlm*Z* nd dl+m,Z, e,dZe,dZ'e,dZ e,dZ"e,dZe,dZ$dZ-d+dd Z.e	d!G d"d# d#eZ/d,d)d*Z0dS )-    )annotations)Any)TYPE_CHECKINGN)experimental_class)warn_experimental_argument)_CONSTRAINTS_KEY) _process_constraints_after_trial)BaseSampler)LazyRandomState)StudyDirection)_is_pareto_front)FrozenTrial)
TrialState)Callable)Sequence)BaseDistribution)Study)_LazyImporttorchzoptuna._gp.search_spacezoptuna._gp.gpzoptuna._gp.optim_mixedzoptuna._gp.acqfzoptuna._gp.priorg|=values
np.ndarrayreturn)tuple[np.ndarray, np.ndarray, np.ndarray]c                 C  sD   t | }tj|dd}tj|dd}|| tt| }|||fS )Nr   axis)gpwarn_and_convert_infnpmeanstdmaximumEPS)r   clipped_valuesmeansstdsstandardized_values r&   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/optuna/samplers/_gp/sampler.py_standardize_values0   s
   

r(   z3.6.0c                   @  sx   e Zd ZdZddddddd>ddZd?ddZd@ddZdAd"d#ZdBd)d*ZdCd-d.Z	dDd4d5Z
dEd6d7ZdFd<d=ZdS )G	GPSamplera  Sampler using Gaussian process-based Bayesian optimization.

    This sampler fits a Gaussian process (GP) to the objective function and optimizes
    the acquisition function to suggest the next parameters.

    The current implementation uses Matern kernel with nu=2.5 (twice differentiable) with automatic
    relevance determination (ARD) for the length scale of each parameter.
    The hyperparameters of the kernel are obtained by maximizing the marginal log-likelihood of the
    hyperparameters given the past trials.
    To prevent overfitting, Gamma prior is introduced for kernel scale and noise variance and
    a hand-crafted prior is introduced for inverse squared lengthscales.

    As an acquisition function, we use:

    - log expected improvement (logEI) for single-objective optimization,
    - log expected hypervolume improvement (logEHVI) for Multi-objective optimization, and
    - the summation of logEI and the logarithm of the feasible probability with the independent
      assumption of each constraint for (black-box inequality) constrained optimization.

    For further information about these acquisition functions, please refer to the following
    papers:

    - `Unexpected Improvements to Expected Improvement for Bayesian Optimization
      <https://arxiv.org/abs/2310.20708>`__
    - `Differentiable Expected Hypervolume Improvement for Parallel Multi-Objective Bayesian
      Optimization <https://arxiv.org/abs/2006.05078>`__
    - `Bayesian Optimization with Inequality Constraints
      <https://proceedings.mlr.press/v32/gardner14.pdf>`__

    The optimization of the acquisition function is performed via:

    1. Collect the best param from the past trials,
    2. Collect ``n_preliminary_samples`` points using Quasi-Monte Carlo (QMC) sampling,
    3. Choose the best point from the collected points,
    4. Choose ``n_local_search - 2`` points from the collected points using the roulette
       selection,
    5. Perform a local search for each chosen point as an initial point, and
    6. Return the point with the best acquisition function value as the next parameter.

    Note that the procedures for non single-objective optimization setups are slightly different
    from the single-objective version described above, but we omit the descriptions for the others
    for brevity.

    The local search iteratively optimizes the acquisition function by repeating:

    1. Gradient ascent using l-BFGS-B for continuous parameters, and
    2. Line search or exhaustive search for each discrete parameter independently.

    The local search is terminated if the routine stops updating the best parameter set or the
    maximum number of iterations is reached.

    We use line search instead of rounding the results from the continuous optimization since EI
    typically yields a high value between one grid and its adjacent grid.

    .. note::
        This sampler requires ``scipy`` and ``torch``.
        You can install these dependencies with ``pip install scipy torch``.

    Args:
        seed:
            Random seed to initialize internal random number generator.
            Defaults to :obj:`None` (a seed is picked randomly).
        independent_sampler:
            Sampler used for initial sampling (for the first ``n_startup_trials`` trials)
            and for conditional parameters. Defaults to :obj:`None`
            (a random sampler with the same ``seed`` is used).
        n_startup_trials:
            Number of initial trials. Defaults to 10.
        deterministic_objective:
            Whether the objective function is deterministic or not.
            If :obj:`True`, the sampler will fix the noise variance of the surrogate model to
            the minimum value (slightly above 0 to ensure numerical stability).
            Defaults to :obj:`False`. Currently, all the objectives will be assume to be
            deterministic if :obj:`True`.
        constraints_func:
            An optional function that computes the objective constraints. It must take a
            :class:`~optuna.trial.FrozenTrial` and return the constraints. The return value must
            be a sequence of :obj:`float` s. A value strictly larger than 0 means that a
            constraints is violated. A value equal to or smaller than 0 is considered feasible.
            If ``constraints_func`` returns more than one value for a trial, that trial is
            considered feasible if and only if all values are equal to 0 or smaller.

            The ``constraints_func`` will be evaluated after each successful trial.
            The function won't be called when trials fail or are pruned, but this behavior is
            subject to change in future releases.
            Currently, the ``constraints_func`` option is not supported for multi-objective
            optimization.
    N
   F)seedindependent_samplern_startup_trialsdeterministic_objectiveconstraints_funcr+   
int | Noner,   BaseSampler | Noner-   intr.   boolr/   /Callable[[FrozenTrial], Sequence[float]] | Noner   Nonec                C  s~   t || _|ptjj|d| _tj | _|| _	t
j| _t
j| _d | _d | _|| _|| _|d ur4td d| _d| _d| _d S )N)r+   r/   i   r*   g-C6?)r
   _rngoptunasamplersRandomSampler_independent_samplersearch_spaceIntersectionSearchSpace_intersection_search_space_n_startup_trialspriordefault_log_prior
_log_priorDEFAULT_MINIMUM_NOISE_VAR_minimum_noise_kernel_params_cache_list _constraints_kernel_params_cache_deterministic_constraints_funcr   _n_preliminary_samples_n_local_search_tol)selfr+   r,   r-   r.   r/   r&   r&   r'   __init__   s   
	
zGPSampler.__init__c                 C  s   | j j  | j  d S N)r6   rngr+   r:   
reseed_rng)rK   r&   r&   r'   rO      s   zGPSampler.reseed_rngstudyr   trialr   dict[str, BaseDistribution]c                 C  s4   i }| j | D ]\}}| rq
|||< q
|S rM   )r=   	calculateitemssingle)rK   rP   rQ   r;   namedistributionr&   r&   r'   infer_relative_search_space   s   
z%GPSampler.infer_relative_search_spaceacqf_paramsacqf.AcquisitionFunctionParamsbest_paramsnp.ndarray | Noner   c                 C  sB   |d u st |jdksJ tj||| j| j| j| jjd\}}|S )N   )!warmstart_normalized_params_arrayn_preliminary_samplesn_local_searchtolrN   )	lenshapeoptim_mixedoptimize_acqf_mixedrH   rI   rJ   r6   rN   )rK   rY   r[   normalized_params	_acqf_valr&   r&   r'   _optimize_acqf   s   
zGPSampler._optimize_acqfconstraint_valsinternal_search_spacegp_search_space.SearchSpacerf   $list[acqf.AcquisitionFunctionParams]c                 C  s   t |\}}}| jd urt| jd jt|jkrd | _|jtjjk}g }g }	t	t
|j||D ]=\}
\}}}| jd urA| j|
 nd }tj|||| j| j|| jd}|| |	tjtjj||||| tt| d q0|| _|	S )Nr   XYis_categorical	log_priorminimum_noiseinitial_kernel_paramsr.   	acqf_typekernel_paramsr;   rn   ro   max_Y)r(   rD   rb   inverse_squared_lengthscalesscale_typesrE   gp_search_space	ScaleTypeCATEGORICAL	enumeratezipTr   fit_kernel_paramsrA   rC   rF   appendacqfcreate_acqf_paramsAcquisitionFunctionTypeLOG_PImaxr!   )rK   ri   rj   rf   standardized_constraint_valsr#   r$   rp   constraints_kernel_paramsconstraints_acqf_paramsivalsr   r   cacherv   r&   r&   r'   _get_constraints_acqf_params   sJ   
 


	z&GPSampler._get_constraints_acqf_paramsr;   dict[str, Any]c                 C  s$  |  r| jd urtd|i kri S tjf}|jd|dd}t|| jk r(i S t	||\}}t
dd |jD }t|t
dd |D  \}	}
}
| jd urat| jd jt|jkrad | _g }|	jd	 }|jtjjk}t|D ]&}| jd ur| j| nd }|tj||	d d |f || j| j|| jd
 qs|| _| jd u r!|dkrt|dksJ tjtjj|d |||	d d df d}|t
|	t
j f }ng }t|D ]}|tjtjj!|| |||	d d |f d qtj"j#||	d| j$j%&dd}|t'|	 dd }t|}t(| j)d |}| j$j%j*||dd}|| }ne|t|  kr2dks7J d J dt+||\}}t
,| }|rKt
j- nt
.|	| }tjtjj|d |||	d d df |d}| /|||}tj0#||}|rzd n|t
|	| t
j f }| 1||}t2||S )NzDGPSampler does not support constrained multi-objective optimization.FT)deepcopystates	use_cachec                 S  s   g | ]}|t jkrd ndqS )g      g      ?)r   MINIMIZE).0dr&   r&   r'   
<listcomp>  s    z-GPSampler.sample_relative.<locals>.<listcomp>c                 S  s   g | ]}|j qS r&   )r   r   rQ   r&   r&   r'   r     s    r   rm      )ru   rv   r;   rn   ro      i   @)acqf_params_for_objectivesro   n_qmc_samplesqmc_seed)assume_unique_lexsortedr]   )sizereplacez'Multi-objective has not been supported.rt   )3_is_multi_objectiverG   
ValueErrorr   COMPLETE_get_trialsrb   r>   rz   &get_search_space_and_normalized_paramsr   array
directionsr(   rD   rx   ry   rc   r{   r|   ranger   r   r   rA   rC   rF   r   r   r   LOG_EIargmaxnewaxisLOG_EHVI'MultiObjectiveAcquisitionFunctionParamsfrom_acqf_paramsr6   rN   randintr   minrI   choice$_get_constraint_vals_and_feasibilityanyinfr   r   $ConstrainedAcquisitionFunctionParamsrh   get_unnormalized_param)rK   rP   rQ   r;   r   trialsrj   rf   _signstandardized_score_vals_kernel_params_listn_objectivesrp   r   r   rY   r[   r   pareto_paramsn_pareto_solsr   chosen_indicesri   is_feasibleis_all_infeasiblerw   r   normalized_paramr&   r&   r'   sample_relative  s   





	
zGPSampler.sample_relative
param_namestrparam_distributionr   r   c                 C  s   | j ||||S rM   )r:   sample_independent)rK   rP   rQ   r   r   r&   r&   r'   r     s   zGPSampler.sample_independentc                 C  s   | j || d S rM   )r:   before_trial)rK   rP   rQ   r&   r&   r'   r     s   zGPSampler.before_trialstater   r   Sequence[float] | Nonec                 C  s0   | j d urt| j ||| | j|||| d S rM   )rG   r   r:   after_trial)rK   rP   rQ   r   r   r&   r&   r'   r     s   
zGPSampler.after_trial)r+   r0   r,   r1   r-   r2   r.   r3   r/   r4   r   r5   )r   r5   )rP   r   rQ   r   r   rR   )rY   rZ   r[   r\   r   r   )ri   r   rj   rk   rf   r   r   rl   )rP   r   rQ   r   r;   rR   r   r   )
rP   r   rQ   r   r   r   r   r   r   r   )rP   r   rQ   r   r   r5   )
rP   r   rQ   r   r   r   r   r   r   r5   )__name__
__module____qualname____doc__rL   rO   rX   rh   r   r   r   r   r   r&   r&   r&   r'   r)   8   s"    \




1 

r)   rP   r   r   list[FrozenTrial]tuple[np.ndarray, np.ndarray]c                   s~   fdd|D  t  fdd D rtdt }t|jdks(J dtj|dkd	d
}t|tjr;J d||fS )Nc                   s"   g | ]} j |jtd qS )r&   )_storageget_trial_system_attrs	_trial_idgetr   r   )rP   r&   r'   r     s    z8_get_constraint_vals_and_feasibility.<locals>.<listcomp>c                 3  s$    | ]}t  d  t |kV  qdS )r   N)rb   )r   c)_constraint_valsr&   r'   	<genexpr>  s   " z7_get_constraint_vals_and_feasibility.<locals>.<genexpr>z:The number of constraints must be the same for all trials.r]   z#constraint_vals must be a 2d array.r   r   r   z#MyPy Redefinition for NumPy v2.2.0.)	r   r   r   r   rb   rc   all
isinstancebool_)rP   r   ri   r   r&   )r   rP   r'   r     s   

r   )r   r   r   r   )rP   r   r   r   r   r   )1
__future__r   typingr   r   numpyr   r7   optuna._experimentalr   r   optuna.samplers._baser   r   r	   "optuna.samplers._lazy_random_stater
   optuna.studyr   optuna.study._multi_objectiver   optuna.trialr   r   collections.abcr   r   r   optuna._gp.acqf_gpr   optuna._gp.gpr   optuna._gp.optim_mixedrd   optuna._gp.priorr?   optuna._gp.search_spacer;   rz   optuna.distributionsr   r   optuna._importsr   r!   r(   r)   r   r&   r&   r&   r'   <module>   sP    
  i