
    -ji
                        S r SSKJr  SSKrSSKJr  SSKJr        S
S jr	        SS jr
      S
S jr      SS	 jrg)a  
The functions in this file are mostly based on BoTorch v0.13.0,
but they are refactored significantly from the original version.

For ``_get_upper_bound_set``, look at:
    * https://github.com/pytorch/botorch/blob/v0.13.0/botorch/utils/multi_objective/box_decompositions/utils.py#L101-L160

For ``_get_box_bounds``, look at:
    * https://github.com/pytorch/botorch/blob/v0.13.0/botorch/utils/multi_objective/box_decompositions/utils.py#L163-L193

For ``_get_non_dominated_box_bounds``, look at:
    * https://github.com/pytorch/botorch/blob/v0.13.0/botorch/utils/multi_objective/box_decompositions/non_dominated.py#L395-L430

The preprocessing for four or fewer objectives, we use the algorithm proposed by:
    Title: A Box Decomposition Algorithm to Compute the Hypervolume Indicator
    Authors: Renaud Lacour, Kathrin Klamroth, and Carlos M. Fonseca
    URL: https://arxiv.org/abs/1510.01963
We refer this paper as Lacour17 in this file.

    )annotationsN)optuna_warn)_is_pareto_frontc                f  ^^^	 U R                   u  nm[        R                  " T5      m[        R                  " T[        S9m	ST	SS2S4'   SUUU	4S jjn[        R
                  " U/5      n[        R                  " STT4[        R                  * 5      nXSTT4'   U  H  nU" XdU5      u  pEM     XE4$ )a  
This function follows Algorithm 2 of Lacour17.

Args:
    sorted_pareto_sols: Pareto solutions sorted with respect to the first objective.
    ref_point: The reference point.

Returns:
    upper_bound_set: The upper bound set, which is ``U(N)`` in the paper. The shape is
    ``(n_bounds, n_objectives)``.
    def_points: The defining points of each vector in ``U(N)``. The shape is
    ``(n_bounds, n_objectives, n_objectives)``.

NOTE:
    ``pareto_sols`` corresponds to ``N`` and ``upper_bound_set`` corresponds to ``U(N)`` in the
    paper.
    ``def_points`` (the shape is ``(n_bounds, n_objectives, n_objectives)``) is not well
    explained in the paper, but basically, ``def_points[i, j] = z[j]`` of
    ``upper_bound_set[i]``.
)dtypeTNr   c                  > [         R                  " X:  SS9n[        U5      (       d  X4$ X#   nUR                  S   nU [         R                  " [         R
                  " T[         R                  * U5      SS9:  n[         R                  " [         R                  " U5      S S 2[         R                  4   T5      U   n[         R                  " TUS45      U   nUR                  UR                  :X  d   e[         R                  " UR                  5      n	XG   n
X
X4'   X   U   nX   XU4'   [         R                  " X)    U/5      [         R                  " X#)    U
/5      4$ )Naxisr      )npallanyshapemaxwhereinftilearangenewaxissizevstack)solubsdpsis_dominateddominated_dpsn_boundsupdateubs_indices_to_updatedimensions_to_updateindices_for_sweepingnew_dpsnew_ubsn_objectivesobjective_indicesskip_ineq_judges               _/home/james-whalen/.local/lib/python3.13/site-packages/optuna/_hypervolume/box_decomposition.pyr    $_get_upper_bound_set.<locals>.update;   sL   vvcib1<  8O ) &&q) rxx"&&-PWYZZ !#		((;ArzzM(JL YZ` a!ww'88Q-HP$))-A-F-FFFF!yy)=)B)BC6>A$:;#$9:>A>W&::;yy#m,g67CDVX_C`9aaa    r   )r   
np.ndarrayr   r,   r   r,   returntuple[np.ndarray, np.ndarray])r   r   r   eyeboolasarrayfullr   )
sorted_pareto_sols	ref_point_r    upper_bound_set
def_pointssolutionr&   r'   r(   s
          @@@r)   _get_upper_bound_setr9      s    . +00Q		,/ff\6O OAqDb b8 jj)-O!\<8266'BJ:Cq#%667&&,X
&S# ' &&r+   c                   U R                   S   nUS:  d   S5       e[        R                  " S/U R                   Q75      nUS S 2SS4   USS S 2S4'   US   USS S 2S4'   [        R                  " US-
  5      u  pV[        R                  R                  USS9S S 2XVS-   4   USS S 2SS 24'   U S S 2SS 24   USS S 2SS 24'   [        R                  " US   US   :*  SS9) nUS S 2U4   $ )Nr	   r   8This function is used only for multi-objective problems.   r   r   r
   )r   r   emptydiag_indicesmaximum
accumulater   )r6   r7   r4   r&   boundsrowcol	not_emptys           r)   _get_box_boundsrE   `   s    #((,L!WWWXXq1?0012F Aq)F1a7OlF1a7O|a/0HCzz,,Zb,A!SPQ'/RF1a8&q!"u-F1a8q	VAY.R88I!Y,r+   c                    [        X5      S   * n[        R                  " USS9n[        R                  " U[        R                  5      n[        U[        USS9   US9u  pV[        XVU5      * u  pxX4$ )Nr   r
   Tassume_unique_lexsorted)r3   r4   )r9   r   unique	full_liker   r   rE   )	r3   r4   neg_upper_bound_setsorted_neg_upper_bound_setpoint_at_infinityneg_lower_bound_setneg_def_pointsbox_upper_boundsbox_lower_boundss	            r)   _get_non_dominated_box_boundsrR   p   s     00BNqQQ!#+>Q!G Y7 +?57QUV
 $	+' +:->+ *& --r+   c                "   [         R                  " [         R                  " U 5      5      (       d   S5       e[         R                  " U SS9nU[	        USS9   nU R
                  S   nUS:  d   S5       eUS	:  a  [        S
5        [        X15      $ )Nz3loss_vals must be clipped before box decomposition.r   r
   TrG   r	   r   r;      zBox decomposition (typically used by `GPSampler`) might be significantly slow for n_objectives > 4. Please consider using another sampler instead.)r   r   isfiniterI   r   r   r   rR   )	loss_valsr4   unique_lexsorted_loss_valsr3   r&   s        r)   get_non_dominated_box_boundsrX      s     66"++i())`+``)!#91!=33TR ??2&L !WWWaO	

 ));GGr+   )r3   r,   r4   r,   r-   r.   )r6   r,   r7   r,   r4   r,   r-   r,   )rV   r,   r4   r,   r-   r.   )__doc__
__future__r   numpyr   optuna._warningsr   optuna.study._multi_objectiver   r9   rE   rR   rX    r+   r)   <module>r_      s   * #  ( :?'"?'/9?'"?'D  -7 DN   ."./9.".4HH&0H"Hr+   