o
    /wi1                     @  s   d dl mZ d dlZd dlm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 erGd dlmZ n
d dlmZ edZeeZd8ddZd9ddZd:d!d"Zd;d#d$Zd%d&d'd<d+d,Zdd-d.d%dd/d=d6d7ZdS )>    )annotationsN)TYPE_CHECKING)AcquisitionFunctionParams)eval_acqf_no_gradeval_acqf_with_grad)normalize_one_param)sample_normalized_params)	ScaleType)
get_logger)_LazyImportzscipy.optimizeacqf_paramsr   initial_params
np.ndarrayinitial_fvalfloatcontinuous_indiceslengthscalestolreturntuple[np.ndarray, float, bool]c           
        s   t dkr||dfS | d fdd}tj|  d	d
 D t|dd\}}}	| |krI|	d dkrI| < | dfS ||dfS )a'  
    This function optimizes the acquisition function using preconditioning.
    Preconditioning equalizes the variances caused by each parameter and
    speeds up the convergence.

    In Optuna, acquisition functions use Matern 5/2 kernel, which is a function of `x / l`
    where `x` is `normalized_params` and `l` is the corresponding lengthscales.
    Then acquisition functions are a function of `x / l`, i.e. `f(x / l)`.
    As `l` has different values for each param, it makes the function ill-conditioned.
    By transforming `x / l` to `zl / l = z`, the function becomes `f(z)` and has
    equal variances w.r.t. `z`.
    So optimization w.r.t. `z` instead of `x` is the preconditioning here and
    speeds up the convergence.
    As the domain of `x` is [0, 1], that of `z` becomes [0, 1/l].
    r   Fscaled_xr   r   tuple[float, np.ndarray]c                   s.   |  < t  \}}| |   fS Nr   )r   fvalgradr   r   r   normalized_params S/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/optuna/_gp/optim_mixed.pynegative_acqf_with_grad6   s   z1_gradient_ascent.<locals>.negative_acqf_with_gradc                 S  s   g | ]}d d| fqS )r      r   ).0sr   r   r   
<listcomp>A   s    z$_gradient_ascent.<locals>.<listcomp>   )funcx0boundspgtolmaxiternitTN)r   r   r   r   )lencopysofmin_l_bfgs_bmathsqrt)
r   r   r   r   r   r   r    scaled_cont_x_optneg_fval_optinfor   r   r   _gradient_ascent   s   


r5   	param_idxintchoicesc           	      C  s   |||| k }t j|d d d f t|dd}||d d |f< t| |}t |}|| |kr=||d d f || dfS ||dfS )Nr   )axisTF)nprepeatr,   r   argmax)	r   r   r   r6   r8   choices_except_current
all_paramsfvalsbest_idxr   r   r   _exhaustive_searchN   s    


rA   gridsxtolc                   s   t dkr||dfS dfdd}|| }t| | s$J || i| d fd
ddfdd}d}	tj|d |	 | d |	 fd|d}
||
j}| }||kru||kru| < |dfS ||dfS )Nr!   Fxr   r   r7   c                   sR   t tt | dt d }t|  |d   t|  |  k r'|d S |S )Nr!   )r7   r:   clipsearchsortedr,   abs)rD   i)rB   r   r   find_nearest_indexn   s   "0z1_discrete_line_search.<locals>.find_nearest_indexrH   c                   s>    | }|d ur|S |  < tt  }|| < |S r   )getr   r   )rH   	cache_valnegval)r   rB   negative_fval_cacher   r6   r   r   negative_acqf_with_cachey   s   
z7_discrete_line_search.<locals>.negative_acqf_with_cachec                   s   |  d k s|  d krt jS tt t  | dt d }|d }||}} | |   |  |   }d| }|| ||  S )Nr   r!   g      ?)r:   infr7   rE   rF   r,   )rD   rightleftneg_acqf_leftneg_acqf_rightw_leftw_right)rB   rN   r   r   interpolated_negative_acqf   s   "z9_discrete_line_search.<locals>.interpolated_negative_acqfg-q=r   rO   brent)bracketmethodr   T)rD   r   r   r7   )rH   r7   r   r   )rD   r   r   r   )r,   r:   iscloser-   r.   minimize_scalarrD   )r   r   r   r6   rB   rC   rI   current_choice_irW   EPSresopt_idxfval_optr   )r   rB   rN   rM   r   r6   r   _discrete_line_searchb   s,   





rb   c                 C  sH   d}| j j| }|tjkst||krt| ||||S t| |||||S )N   )search_spacescale_typesr
   CATEGORICALr,   rA   rb   )r   r   r   r6   r8   rC    MAX_INT_EXHAUSTIVE_SEARCH_PARAMS
scale_typer   r   r   _local_search_discrete   s   ri   g-C6?d   )r   max_iterinitial_normalized_paramsrk   tuple[np.ndarray, float]c             	     s^  | j j| j j | j jtdkd }| jj 	 }dt
||  }tdkd t} fdd|D }dd |D }	| }
tt| |
}d}d }t|D ]N}||krc|
|f  S t| |
||||\}
}}|rs|}t|||	D ]!\}}}||kr|
|f    S t| |
||||\}
}}|r|}qy|d u r|
|f  S qWtd |
|fS )	N        r   r!   c              
     s   g | ]?}| t jkrt |d f n,tt |df  |d f d|   | t |  |df  |d f f| dqS )r!   r   g      ?)param_valuerh   r(   step)r
   rf   r:   aranger   )r"   rH   r(   re   stepsr   r   r$      s    ,
z&local_search_mixed.<locals>.<listcomp>c                 S  s&   g | ]}t jt |t jd d qS ))initial   )r:   mindiffrP   )r"   r8   r   r   r   r$      s    rO   z2local_search_mixed: Local search did not converge.)rd   re   r(   rs   r:   wherekernel_paramsinverse_squared_lengthscalesdetachnumpyr1   astyper7   r-   r   r   ranger5   zipri   _loggerwarning)r   rl   r   rk   r   rz   r   discrete_indiceschoices_of_discrete_paramsdiscrete_xtolsbest_normalized_params	best_fval
CONTINUOUSlast_changed_param_updatedrH   r8   rC   r   rr   r   local_search_mixed   sZ   	


r   i   
   )!warmstart_normalized_params_arrayn_preliminary_samplesn_local_searchr   rngr   np.ndarray | Noner   r   r   np.random.RandomState | Nonec                C  sz  |pt j }| jjjd }|d u rt d|f}t||d ks%J dt|| j|d}t	| |}t
|t js:J t |}	t |||	  }
d|
|	< |
|
  }
tt |
dk}t|t| d |}||krotd t |	g}|dkr|jt||d|
d}t ||}||	d d f }t||	 }t ||d d f |gD ]}t| ||d	\}}||kr|}|}q||fS )
Nr   r!   zPWe must choose at least 1 best sampled point + given_initial_xs as start points.)r   rn   zBStudy already converged, so the number of local search is reduced.F)sizereplacep)r   )r:   randomRandomStaterd   re   shapeemptyr,   r	   r   
isinstancendarrayr<   expsumr7   count_nonzerorv   r   r   arraychoiceappendr   vstackr   )r   r   r   r   r   r   dim
sampled_xsf_valsmax_iprobsn_non_zero_probs_improvementn_additional_warmstartchosen_idxsadditional_idxsbest_xbest_fx_warmstartrD   fr   r   r   optimize_acqf_mixed  sF   



r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r6   r7   r8   r   r   r   )r   r   r   r   r   r   r6   r7   rB   r   rC   r   r   r   )r   r   r   r   r   r   r6   r7   r8   r   rC   r   r   r   )
r   r   rl   r   r   r   rk   r7   r   rm   )r   r   r   r   r   r7   r   r7   r   r   r   r   r   rm   )
__future__r   r0   typingr   r|   r:   optuna._gp.acqfr   r   r   optuna._gp.search_spacer   r	   r
   optuna.loggingr   scipy.optimizeoptimizer.   optunar   __name__r   r5   rA   rb   ri   r   r   r   r   r   r   <module>   s:    

3

CY