
    -ji$                    z    S SK Jr  S SKrS SKJr  S	S jrS	S jrS
S jr        SS jr	 S       SS jjr
g)    )annotationsN)_is_pareto_frontc                    U R                   S   UR                   S   s=:X  a  S:X  d   e   e[        R                  " USS  U S S2S4   /5      nUS   U S S 2S4   -
  nX S S 2S4   -
  nX4-  $ )N   r      )shapenpconcatenate)sorted_pareto_solsreference_pointrect_diag_yedge_length_xedge_length_ys        Q/home/james-whalen/.local/lib/python3.13/site-packages/optuna/_hypervolume/wfg.py_compute_2dr      s    ##A&/*?*?*BGaGGGGG../!""57I#2#q&7Q!RSK#A&);AqD)AAMQT"::M((    c                   U R                   S   UR                   S   s=:X  a  S:X  d   e   eU R                   S   n[        R                  " U SS2S4   5      n[        R                  " X"4[        S9nUS   XS4   -
  XC[        R
                  " U5      4'   [        R                  R                  [        R                  R                  USS9SS9nU SS2S4   nXS4   n[        R                  " USS USS /5      U-
  n[        R                  " USS USS /5      U-
  n[        R                  " [        R                  " XH5      U5      $ )aW  
Compute hypervolume in 3D. Time complexity is O(N^2) where N is sorted_pareto_sols.shape[0].
If X, Y, Z coordinates are permutations of 0, 1, ..., N-1 and reference_point is (N, N, N), the
hypervolume is calculated as the number of voxels (x, y, z) dominated by at least one point.
If we fix x and y, this number is equal to the minimum of z' over all points (x', y', z')
satisfying x' <= x and y' <= y. This can be efficiently computed using cumulative minimum
(`np.minimum.accumulate`). Non-permutation coordinates can be transformed into permutation
coordinates by using coordinate compression.
r   r      N)dtyper   axis)
r	   r
   argsortzerosfloatarangemaximum
accumulater   dot)	r   r   ny_orderz_deltax_valsy_valsx_deltay_deltas	            r   _compute_3dr'      sA    ##A&/*?*?*BGaGGGGG  #Ajj+AqD12GhhvU+G%4Q%7:LVWZ:X%XGRYYq\!"jj##BJJ$9$9'$9$JQR#SG1%F
+FnnfQRj/"1*=>?&HGnnfQRj/!A*>?@6IG66"&&*G44r   c                  ^^
^ U R                   S   S:X  a,  Sn[        TU S   5       H  u  p4X#U-
  -  nM     [        U5      $ U R                   S   S:X  aG  Su  pVn[        TU S   U S   5       H$  u  p8n	XSU-
  -  nXcU	-
  -  nXs[        X5      -
  -  nM&     XV-   U-
  $ TU -
  R	                  SS9m
[
        R                  " U S S 2[
        R                  4   U 5      mT
S   [        U
UU4S j[        T
R                  S-
  5       5       5      -   $ )	Nr   r         ?r   )r)   r)   r)   r   r   c              3  V   >#    U  H  n[        TXS -   S24   TU   T5      v   M      g7f)r   N)_compute_exclusive_hv).0iinclusive_hvslimited_sols_arrayr   s     r   	<genexpr>_compute_hv.<locals>.<genexpr>=   s8      #.A 	0EG<mA>NP_``.s   &))r	   zipr   maxprodr
   r   newaxissumrangesize)sorted_loss_valsr   inclusive_hvrvhv1hv2intersecv1v2r.   r/   s    `        @@r   _compute_hvrB   )   s3   a A%)9!)<=DAE!L >\""				"a	' +(_.>q.ACSTUCVWIA2r6MCr6MCCK'H X y8##$'77==2=FM$4Q

]$CEUVs #}))A-.#    r   c                    U R                   S   S:  d   eU R                   S   S::  a  U[        X5      -
  $ [        U SS9nU[        X   U5      -
  $ )Nr   r   r   Tassume_unique_lexsorted)r	   rB   r   )limited_solsr:   r   on_fronts       r   r+   r+   C   sd     a A%%%!!k,HHHB  dKH+l&<oNNNr   c                R   [         R                  " X:*  5      (       d  [        S5      e[         R                  " [         R                  " U5      5      (       d  [	        S5      $ U R
                  S:X  a  gU(       d$  [         R                  " U SS9n[        USS9nX4   nOX SS2S4   R                  5          nUR                  S   S	:X  a  [        XQ5      nO*UR                  S   S
:X  a  [        XQ5      nO[        XQ5      n[         R                  " U5      (       a  U$ [	        S5      $ )a  Hypervolume calculator for any dimension.

This class exactly calculates the hypervolume for any dimension.
For 3 dimensions or higher, the WFG algorithm will be used.
Please refer to ``A Fast Way of Calculating Exact Hypervolumes`` for the WFG algorithm.

.. note::
    This class is used for computing the hypervolumes of points in multi-objective space.
    Each coordinate of each point represents a ``values`` of the multi-objective function.

.. note::
    We check that each objective is to be minimized. Transform objective values that are
    to be maximized before calling this class's ``compute`` method.

Args:
    loss_vals:
        An array of loss value vectors to calculate the hypervolume.
    reference_point:
        The reference point used to calculate the hypervolume.
    assume_pareto:
        Whether to assume the Pareto optimality to ``loss_vals``.
        In other words, if ``True``, none of loss vectors are dominated by another.
        ``assume_pareto`` is used only for speedup and it does not change the result even if
        this argument is wrongly given. If there are many non-Pareto solutions in
        ``loss_vals``, ``assume_pareto=True`` will speed up the calculation.

Returns:
    The hypervolume of the given arguments.

zAll points must dominate or equal the reference point. That is, for all points in the loss_vals and the coordinate `i`, `loss_vals[i] <= reference_point[i]`.infr   g        r   TrD   Nr   r   )r
   all
ValueErrorisfiniter   r8   uniquer   r   r	   r   r'   rB   )	loss_valsr   assume_paretounique_lexsorted_loss_valsrG   r   hvs          r   compute_hypervolumerR   n   s	   D 66).//4
 	

 66"++o.//U|~~%'YYyq%A"#$>X\]7A 'A'>'>'@AQ1$+=			q	!Q	& +=+= R22eEl2r   )r   
np.ndarrayr   rS   returnr   )r9   rS   r   rS   rT   r   )rF   rS   r:   r   r   rS   rT   r   )F)rN   rS   r   rS   rO   boolrT   r   )
__future__r   numpyr
   optuna.study._multi_objectiver   r   r'   rB   r+   rR    r   r   <module>rZ      sy    "  :)524(O(O,1(ODN(O
(OX OTG3G3,6G3GKG3
G3r   