Ë
    þÍ:jØÃ  ã                   óæ  — d dl Z d dlZd dlmZmZ d dlZd dlmZ d dlmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ ded	ed
eeef   fd„Zded	ed
dfd„Z	 	 d3ded	ededee   ded   d
eeef   fd„Zdeded
efd„Zded
efd„Zded
dfd„Zdedeedf   d
efd„Zdeded
efd„Z	 d4dedee   deeedf      d ed
ef
d!„Z	 	 	 d5ded"eeeee   f      d#ed$   d%ed&   d
ef
d'„Z 	 	 d6ded	ed(ed)eeeeef   eeeef   f      d
eeeef   eeeeef   f   f
d*„Z!	 	 d7ded	ed+ed$   d)eeeee   f      d
ef
d,„Z"	 	 	 d8ded	ed+ed$   d)eeeee   f      d-ed
eeeeef   f   fd.„Z#e jH                  	 d9d)eeeef   eeeef   f   d/eejJ                     d
eeef   fd0„«       Z&d9d)eeef   d/eejJ                     d
eeef   fd1„Z'e jH                  d9d)eeeef   d/eejJ                     d
eeef   fd2„«       Z(y):é    N)ÚOptionalÚUnion)ÚTensor)Úconv2dÚconv3dÚpadÚunfold)ÚLiteral)Ú_check_same_shape)Ú_SCIPY_AVAILABLEÚpredsÚtargetÚreturnc                 ó†   — | j                   d   dkD  r| dd…dd…f   n| } |j                   d   dkD  r|dd…dd…f   n|}| |fS )zQIgnore the background class in the computation assuming it is the first, index 0.é   N)Úshape©r   r   s     ú/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/torchmetrics/functional/segmentation/utils.pyÚ_ignore_backgroundr      sL   € à!ŸK™K¨™N¨QÒ.ˆE’!�Q‘R�%ŠL°E€EØ$Ÿl™l¨1™o°Ò1ˆV’A�q‘r�EŠ]°v€FØ�&ˆ=Ðó    c                 ór  — | j                  «       |j                  «       dz   k(  re| j                  d   |j                  d   k7  s| j                  dd |j                  dd k7  r&t        d| j                  › d|j                  › d�«      ‚y| j                  «       dz   |j                  «       k(  re| j                  d   |j                  d   k7  s| j                  dd |j                  dd k7  r&t        d| j                  › d|j                  › d�«      ‚yt        d| j                  › d|j                  › d�«      ‚)zHCheck that predictions and target have the same shape, else raise error.r   r   é   NzAPredictions and targets are expected to have the same shape, got ú and ú.)Údimr   ÚRuntimeErrorr   s     r   Ú_check_mixed_shaper   "   sA  € à‡y�yƒ{�v—z‘z“| aÑ'Ò(Ø�;‰;�q‰>˜VŸ\™\¨!™_Ò,°·±¸A¸B°À6Ç<Á<ÐPQÐPRÐCSÒ0SÜØSÐTY×T_ÑT_ÐS`Ð`eÐfl×frÑfrÐesÐstÐuóð ð 1Tð �)‰)‹+˜‰/˜fŸj™j›lÒ	*Ø�;‰;�q‰>˜VŸ\™\¨!™_Ò,°·±¸A¸B°À6Ç<Á<ÐPQÐPRÐCSÒ0SÜØSÐTY×T_ÑT_ÐS`Ð`eÐfl×frÑfrÐesÐstÐuóð ð 1Tô
 ØOÐPU×P[ÑP[È}Ð\aÐbh×bnÑbnÐaoÐopÐqó
ð 	
r   Úinclude_backgroundÚnum_classesÚinput_format)úone-hotÚindexÚmixedc                 ó  — |dk(  rt        | |«       nt        | |«       |dk(  r…|€t        d«      ‚t        j                  j
                  j                  | |¬«      j                  dd«      } t        j                  j
                  j                  ||¬«      j                  dd«      }�n!|dk(  r&|€t        | «      }t        | |«      } t        ||«      }nö|dk(  rñ| j                  «       |j                  «       dz   k(  rU|€t        | «      }t        | |«      } t        j                  j
                  j                  ||¬«      j                  dd«      }nx| j                  «       dz   |j                  «       k(  rT|€t        |«      }t        ||«      }t        j                  j
                  j                  | |¬«      j                  dd«      } | j                  dk  rt        d	| j                  › d
�«      ‚|st        | |«      \  } }| |fS )z1Check and format inputs to the one-hot encodings.r#   r"   zDArgument `num_classes` must be provided when `input_format='index'`.©r   éÿÿÿÿr   r!   é   zJExpected both `preds` and `target` to have at least 3 dimensions, but got r   )r   r   Ú
ValueErrorÚtorchÚnnÚ
functionalÚone_hotÚmovedimÚ_get_num_classesÚ_format_logitsr   Úndimr   )r   r   r   r   r    s        r   Ú_segmentation_inputs_formatr1   4   sÙ  € ð �wÒÜ˜5 &Õ)ä˜% Ô(à�wÒØÐÜÐcÓdÐdÜ—‘×#Ñ#×+Ñ+¨E¸{Ð+ÓK×SÑSÐTVÐXYÓZˆÜ—‘×$Ñ$×,Ñ,¨VÀÐ,ÓM×UÑUÐVXÐZ[Ó\ŠØ	˜Ò	"ØÐÜ*¨5Ó1ˆKÜ˜u kÓ2ˆÜ ¨Ó4‰Ø	˜Ò	 Ø�9‰9‹;˜6Ÿ:™:›<¨!Ñ+Ò,ØÐ"Ü.¨uÓ5�Ü" 5¨+Ó6ˆEÜ—X‘X×(Ñ(×0Ñ0°À[Ð0ÓQ×YÑYÐZ\Ð^_Ó`‰FØ�i‰i‹k˜A‰o &§*¡*£,Ò.ØÐ"Ü.¨vÓ6�Ü# F¨KÓ8ˆFÜ—H‘H×'Ñ'×/Ñ/°À;Ð/ÓO×WÑWÐXZÐ\]Ó^ˆEà‡z�z�A‚~ÜÐeÐfk×fpÑfpÐeqÐqrÐsÓtÐtáÜ*¨5°&Ó9‰ˆˆvà�&ˆ=Ðr   Útensorc                 óÊ   — t        j                  | «      rM| j                  d¬«      } t         j                  j                  j                  | |¬«      j                  dd«      } | S )zATransform logits or probabilities into integer one-hot encodings.r   ©r   r%   r&   )r)   Úis_floating_pointÚargmaxr*   r+   r,   r-   )r2   r   s     r   r/   r/   `   sS   € ä×Ñ˜vÔ&Ø—‘ 1�Ó%ˆÜ—‘×$Ñ$×,Ñ,¨VÀÐ,ÓM×UÑUÐVXÐZ[Ó\ˆØ€Mr   c                 ó�   — 	 | j                   d   }|dk(  rt        d|› d�«      ‚|S # t        $ r}t        d| › d�«      |‚d}~ww xY w)z/Get num classes from a tensor if it is not set.r   z,Cannot determine `num_classes` from tensor: r   Nr   zBExpected argument `num_classes` to be a positive integer, but got )r   Ú
IndexErrorr(   )r2   r   Úerrs      r   r.   r.   h   si   € ð\Ø—l‘l 1‘oˆð �aÒÜÐ]Ð^iÐ]jÐjkÐlÓmÐmØÐøô	 ò \ÜÐGÈÀxÈqÐQÓRÐX[Ð[ûð\ús   ‚' §	A°A Á AÚxc                 óf   — t        j                  | j                  «       | k(  «      st        d«      ‚y)zÛCheck if tensor is binarized.

    Example:
        >>> from torchmetrics.functional.segmentation.utils import check_if_binarized
        >>> import torch
        >>> check_if_binarized(torch.tensor([0, 1, 1, 0]))

    zInput x should be binarizedN)r)   ÚallÚboolr(   )r:   s    r   Úcheck_if_binarizedr>   s   s+   € ô �9‰9�Q—V‘V“X ‘]Ô#ÜÐ6Ó7Ð7ð $r   Úkernel_size.c                 óž  — | j                   dd \  }}| j                  dz
  }|dk(  rt        | |«      S |d   |d   z  |d   z  }|dg|D �cg c]  }d‘Œ c}z   }t        j                  || j
                  | j                  ¬«      }  |j                  |dg|¢­Ž j                  |Ž }t        | |d¬«      }	|	j                  |||z  d«      S c c}w )a.  Unfold the input tensor to a matrix. Function supports 3d images e.g. (B, C, D, H, W).

    Inspired by:
    https://github.com/f-dangel/unfoldNd/blob/main/unfoldNd/unfold.py

    Args:
        x: Input tensor to be unfolded.
        kernel_size: The size of the sliding blocks in each dimension.

    Nr   r   r   ©ÚdeviceÚdtype)ÚweightÚbiasr&   )
r   r0   r	   r)   ÚeyerB   rC   ÚreshapeÚrepeatr   )
r:   r?   Ú
batch_sizeÚchannelsÚnÚkernel_size_numelÚ_rH   rD   Úunfold_xs
             r   Ú_unfoldrO   €   sÜ   € ð Ÿ7™7 2 A˜;Ñ€J�Ø	�‰�‰
€AØˆA‚vÜ�a˜Ó%Ð%à# A™¨°Q©Ñ7¸+Àa¹.ÑHÐØ˜ˆ]¨Ö5 AšaÒ5Ñ5€FÜ�Y‰YÐ(°·±ÀÇÁÔI€FØFˆ^ˆV�^‰^Ð-¨qÐ?°;Ò?×FÑFÈÐO€FÜ�a ¨TÔ2€HØ×Ñ˜J¨Ð3DÑ(DÀbÓIÐIùò	 6s   Á	C
ÚrankÚconnectivityc                 ó„  — |dk  rd}| dk  r&t        j                  dgt         j                  ¬«      S t        j                  t	        | «      D �cg c]  }t        j
                  d«      ‘Œ c}d¬«      }t        j                  t        j                  |d¬«      dz
  «      }t        j                  |d¬«      }||k  S c c}w )a  Translated version of the function from scipy.ndimage.morphology.

    Args:
        rank: The rank of the structuring element.
        connectivity: The number of neighbors connected to a given pixel.

    Returns:
        The structuring element.

    Examples::
        >>> from torchmetrics.functional.segmentation.utils import generate_binary_structure
        >>> import torch
        >>> generate_binary_structure(2, 1)
        tensor([[False,  True, False],
                [ True,  True,  True],
                [False,  True, False]])
        >>> generate_binary_structure(2, 2)
        tensor([[True,  True,  True],
                [True,  True,  True],
                [True,  True,  True]])
        >>> generate_binary_structure(3, 2)  # doctest: +NORMALIZE_WHITESPACE
        tensor([[[False,  True, False],
                 [ True,  True,  True],
                 [False,  True, False]],
                [[ True,  True,  True],
                 [ True,  True,  True],
                 [ True,  True,  True]],
                [[False,  True, False],
                 [ True,  True,  True],
                 [False,  True, False]]])

    r   )rC   r'   Úij)Úindexingr   r4   )	r)   r2   Úuint8ÚmeshgridÚrangeÚarangeÚabsÚstackÚsum)rP   rQ   rM   ÚgridsÚoutputs        r   Úgenerate_binary_structurer^   ˜   s–   € ðB �aÒØˆØˆa‚xÜ�|‰|˜Q˜C¤u§{¡{Ô3Ð3Ü�N‰N´U¸4³[ÖA°œEŸL™L¨�OÒAÈDÔQ€EÜ�Y‰Y”u—{‘{ 5¨aÔ0°1Ñ4Ó5€FÜ�Y‰Y�v 1Ô%€FØ�\Ñ!Ð!ùò Bs   ÁB=ÚimageÚ	structureÚoriginÚborder_valuec                 ó‚  — t        | t        «      st        dt        | «      › �«      ‚| j                  dvrt        d| j                  › �«      ‚t        | «       |€@t        | j                  dz
  d«      j                  «       j                  | j                  «      }t        |«       |€|j                  dz  }t        | t        t        |«      «      D ��cg c]&  }||   |j                  |   ||   z
  dz
  fD ]  }|‘Œ Œ( c}}d|¬«      }t        |j!                  «       |j                  ¬	«      }t#        j$                  |«      j'                  d
«      j'                  d«      }||j                  «       z
  }	|	j)                  d¬«      \  }
}t#        j*                  |
| j                  «      dz   j-                  «       S c c}}w )a¦  Binary erosion of a tensor image.

    Implementation inspired by answer to this question: https://stackoverflow.com/questions/56235733/

    Args:
        image: The image to be eroded, must be a binary tensor with shape ``(batch_size, channels, height, width)``.
        structure: The structuring element used for the erosion. If no structuring element is provided, an element
            is generated with a square connectivity equal to one.
        origin: The origin of the structuring element.
        border_value: The value to be used for the border.

    Examples::
        >>> from torchmetrics.functional.segmentation.utils import binary_erosion
        >>> import torch
        >>> image = torch.tensor([[[[0, 0, 0, 0, 0],
        ...                         [0, 1, 1, 1, 0],
        ...                         [0, 1, 1, 1, 0],
        ...                         [0, 1, 1, 1, 0],
        ...                         [0, 0, 0, 0, 0]]]])
        >>> binary_erosion(image)
        tensor([[[[0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0],
                  [0, 0, 1, 0, 0],
                  [0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0]]]], dtype=torch.uint8)
        >>> binary_erosion(image, structure=torch.ones(4, 4))
        tensor([[[[0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0]]]], dtype=torch.uint8)

    z9Expected argument `image` to be of type Tensor but found )é   é   z>Expected argument `image` to be of rank 4 or 5 but found rank r   r   )r   Úconstant)ÚmodeÚvalue)r?   r   r&   r4   )Ú
isinstancer   Ú	TypeErrorÚtyper0   r(   r>   r^   ÚintÚtorB   r   rW   Úlenr   rO   Úfloatr)   ÚflattenÚ	unsqueezeÚminrG   Úbyte)r_   r`   ra   rb   Úir:   Ú	image_padÚimage_unfoldÚstrel_flattenÚsumsÚresultrM   s               r   Úbinary_erosionrz   Ã   s”  € ôH �eœVÔ$ÜÐSÔTXÐY^ÓT_ÐS`ÐaÓbÐbØ‡z�z˜ÑÜÐYÐZ_×ZdÑZdÐYeÐfÓgÐgÜ�uÔð ÐÜ-¨e¯j©j¸1©n¸aÓ@×DÑDÓF×IÑIÈ%Ï,É,ÓWˆ	Ü�yÔ!à€~Ø—‘ $Ñ&ˆô ØÜœ#˜f›+Ó&×`ˆq°¸±¸I¿O¹OÈAÑ<NÐQWÐXYÑQZÑ<ZÐ]^Ñ<^Ð0_Ò`¨1ŠÐ`ˆÓ`ØØô	€Iô ˜9Ÿ?™?Ó,¸)¿/¹/ÔJ€Lä—M‘M )Ó,×6Ñ6°qÓ9×CÑCÀBÓG€MØ˜-×+Ñ+Ó-Ñ-€Dð —‘˜Q�“�I€FˆAô �M‰M˜& %§+¡+Ó.°Ñ2×8Ñ8Ó:Ð:ùó 	as   Ã+F;ÚsamplingÚmetric©Ú	euclideanÚ
chessboardÚtaxicabÚengine©ÚpytorchÚscipyc                 óà  — t        | t        «      st        dt        | «      › d�«      ‚| j                  dk7  rt        d| j                  › d�«      ‚|�(t        |t
        «      st        dt        |«      › d�«      ‚|dvrt        d|› d�«      ‚|dvrt        d	|› d�«      ‚|€d
d
g}n&t        |«      dk7  rt        dt        |«      › d�«      ‚|dk(  �r¢| j                  «       } t        j                  | dk(  «      \  }}t        j                  | d
k(  «      \  }}|j                  dd
«      |j                  d
d«      z
  j                  «       }|j                  dd
«      |j                  d
d«      z
  j                  «       }	| j                  \  }
}|dk(  r%|d   |z  dz  |d
   |	z  dz  z   j                  «       }|dk(  r0t        j                  |d   |z  |d
   |	z  «      j                  «       }|dk(  r|d   |z  |d
   |	z  z   j                  «       }t        j                  d
¬«      \  }}t        j                   | «      j                  d«      }||||
z  |z   <   |j                  | j                  «      S t"        st        d«      ‚ddlm} |dk(  r.|j)                  | j+                  «       j-                  «       |«      S |j/                  | j+                  «       j-                  «       ||¬«      S )a°  Calculate distance transform of a binary tensor.

    This function calculates the distance transform of a binary tensor, replacing each foreground pixel with the
    distance to the closest background pixel. The distance is calculated using the euclidean, chessboard or taxicab
    distance.

    The memory consumption of this function is in the worst cast N/2**2 where N is the number of pixel. Since we need
    to compare all foreground pixels to all background pixels, the memory consumption is quadratic in the number of
    pixels. The memory consumption can be reduced by using the ``scipy`` engine, which is more memory efficient but
    should also be slower for larger images.

    Args:
        x: The binary tensor to calculate the distance transform of.
        sampling: The sampling refers to the pixel spacing in the image, i.e. the distance between two adjacent pixels.
            If not provided, the pixel spacing is assumed to be 1.
        metric: The distance to use for the distance transform. Can be one of ``"euclidean"``, ``"chessboard"``
            or ``"taxicab"``.
        engine: The engine to use for the distance transform. Can be one of ``["pytorch", "scipy"]``. In general,
            the ``pytorch`` engine is faster, but the ``scipy`` engine is more memory efficient.

    Returns:
        The distance transform of the input tensor.

    Examples::
        >>> from torchmetrics.functional.segmentation.utils import distance_transform
        >>> import torch
        >>> x = torch.tensor([[0, 0, 0, 0, 0],
        ...                   [0, 1, 1, 1, 0],
        ...                   [0, 1, 1, 1, 0],
        ...                   [0, 1, 1, 1, 0],
        ...                   [0, 0, 0, 0, 0]])
        >>> distance_transform(x)
        tensor([[0., 0., 0., 0., 0.],
                [0., 1., 1., 1., 0.],
                [0., 1., 2., 1., 0.],
                [0., 1., 1., 1., 0.],
                [0., 0., 0., 0., 0.]])

    z<Expected argument `x` to be of type `torch.Tensor` but got `ú`.r   z4Expected argument `x` to be of rank 2 but got rank `zLExpected argument `sampling` to either be `None` or of type `list` but got `r}   zZExpected argument `metric` to be one of `['euclidean', 'chessboard', 'taxicab']` but got `r‚   zHExpected argument `engine` to be one of `['pytorch', 'scipy']` but got `r   z>Expected argument `sampling` to have length 2 but got length `rƒ   r   r&   r~   r   r€   r4   zhThe `scipy` engine requires `scipy` to be installed. Either install `scipy` or use the `pytorch` engine.)Úndimage)r|   )ri   r   r(   rk   r0   Úlistrn   ro   r)   ÚwhereÚviewrY   r   ÚsqrtÚmaxrr   Ú
zeros_liker   r„   r‡   Údistance_transform_edtÚcpuÚnumpyÚdistance_transform_cdt)r:   r{   r|   r�   Úi0Új0Úi1Új1Údis_rowÚdis_colÚhrM   ÚdisÚmindisÚzr‡   s                   r   Údistance_transformrœ   	  só  € ôZ �aœÔ ÜÐWÔX\Ð]^ÓX_ÐW`Ð`bÐcÓdÐdØ‡v�v�‚{ÜÐOÐPQ×PVÑPVÈxÐWYÐZÓ[Ð[ØÐ¤J¨x¼Ô$>ÜØZÔ[_Ð`hÓ[iÐZjÐjlÐmó
ð 	
ð Ð;Ñ;ÜØhÐioÐhpÐprÐsó
ð 	
ð Ð)Ñ)ÜÐcÐdjÐckÐkmÐnÓoÐoàÐØ�q�6‰äˆx‹=˜AÒÜÐ]Ô^aÐbjÓ^kÐ]lÐlnÐoÓpÐpà�ÓØ�G‰G‹Iˆä—‘˜Q !™VÓ$‰ˆˆBÜ—‘˜Q !™VÓ$‰ˆˆBØ—7‘7˜2˜q“> B§G¡G¨A¨r£NÑ2×7Ñ7Ó9ˆØ—7‘7˜2˜q“> B§G¡G¨A¨r£NÑ2×7Ñ7Ó9ˆð �w‰w‰ˆˆ1Ø�[Ò Ø˜Q‘K 'Ñ)¨aÑ/°8¸A±;ÀÑ3HÈQÑ2NÑN×TÑTÓVˆCØ�\Ò!Ü—)‘)˜H Q™K¨'Ñ1°8¸A±;ÀÑ3HÓI×OÑOÓQˆCØ�YÒØ˜A‘; Ñ(¨8°A©;¸Ñ+@Ñ@×GÑGÓIˆCô —I‘I˜c qÔ)‰	ˆ�Ü×Ñ˜QÓ×$Ñ$ RÓ(ˆØˆˆ"ˆq‰&�2‰+‰Ø�v‰v�a—g‘g‹ÐåÜØvó
ð 	
õ à�ÒØ×-Ñ-¨a¯e©e«g¯m©m«o¸xÓHÐHØ×)Ñ)¨!¯%©%«'¯-©-«/¸8ÈFÐ)ÓSÐSr   ÚcropÚspacingc                 ó&  — t        | |«       | j                  dvrt        d| j                  › d�«      ‚t        | «       t        |«       |r{| |z  }|j	                  «       s0t        j                  | «      t        j                  |«      }}||||fS t        | | j                  ddgz  «      t        ||j                  ddgz  «      }} |€xt        | j                  d«      j                  d«      «      j                  «       | z  }t        |j                  d«      j                  d«      «      j                  «       |z  }||fS t        || j                  ¬«      \  }	}
t        |«      }|dk(  rt        nt        }t        j                   | j                  d«      |j                  d«      gd¬«      j#                  «       } |||
j%                  |«      «      \  }}t        |	«      dz
  }|dk7  ||k7  z  }|dk7  ||k7  z  }t        j&                  |	d|j)                  d	«      j+                  «       «      j-                  |«      }t        j&                  |	d|j)                  d	«      j+                  «       «      j-                  |«      }|d   |d   |d   |d   fS )
a¬  Get the edges of binary segmentation masks.

    Args:
        preds: The predicted binary segmentation mask
        target: The ground truth binary segmentation mask
        crop: Whether to crop the edges to the region of interest. If ``True``, the edges are cropped to the bounding
        spacing: The pixel spacing of the input images. If provided, the edges are calculated using the euclidean

    Returns:
        If spacing is not provided, a 2-tuple containing the edges of the predicted and target mask respectively is
        returned. If spacing is provided, a 4-tuple containing the edges and areas of the predicted and target mask
        respectively is returned.

    )r   r'   z=Expected argument `preds` to be of rank 2 or 3 but got rank `r†   r   r   ©rB   r   r4   r&   )r   r0   r(   r>   Úanyr)   r�   r   rz   rq   ÚsqueezeÚget_neighbour_tablesrB   rn   r   r   rZ   ro   rm   Úindex_selectrŠ   rl   Úview_as)r   r   r�   rž   Úor_valÚpÚtÚbe_predÚ	be_targetÚtableÚkernelÚspatial_dimsÚconv_operatorÚvolumeÚ
code_predsÚcode_targetÚall_onesÚedges_predsÚedges_targetÚareas_predsÚareas_targets                        r   Ú
mask_edgesr·   m  s_  € ô( �e˜VÔ$Ø‡z�z˜ÑÜÐXÐY^×YcÑYcÐXdÐdfÐgÓhÐhÜ�uÔÜ�vÔáØ˜‘ˆØ�z‰zŒ|Ü×#Ñ# EÓ*¬E×,<Ñ,<¸VÓ,DˆqˆAØ�a˜˜A�:Ðä˜E 5§:¡:°°A°Ñ#6Ó7¼¸VÀVÇ[Á[ÐTUÐWXÐSYÑEYÓ9Zˆvˆà€ä  §¡°Ó!3×!=Ñ!=¸aÓ!@ÓA×IÑIÓKÈeÑSˆÜ" 6×#3Ñ#3°AÓ#6×#@Ñ#@ÀÓ#CÓD×LÑLÓNÐQWÑWˆ	Ø˜	Ð!Ð!ô )¨¸¿¹ÔF�M€Eˆ6Ü�w“<€LØ*¨aÒ/•F´V€MÜ�[‰[˜%Ÿ/™/¨!Ó,¨f×.>Ñ.>¸qÓ.AÐBÈÔJ×PÑPÓR€FÙ+¨F°F·I±I¸fÓ4EÓFÑ€J�ô �5‹z˜A‰~€HØ ‘? z°XÑ'=Ñ>€KØ 1Ñ$¨¸Ñ)@ÑA€Lô ×$Ñ$ U¨A¨z¯©¸rÓ/B×/FÑ/FÓ/HÓI×QÑQÐR\Ó]€KÜ×%Ñ% e¨Q°×0@Ñ0@ÀÓ0D×0HÑ0HÓ0JÓK×SÑSÐT_Ó`€LØ�q‰>˜<¨™?¨K¸©N¸LÈ¹OÐKÐKr   Údistance_metricc                 óê  — | j                   t        j                  k(  r|j                   t        j                  k(  s&t        d| j                   › d|j                   › d�«      ‚t        j                  |«      s+t        j
                  t        j                  |«      z  }||    S t        j                  | «      s+t        j
                  t        j                  | «      z  }||   S t        | ||¬«      }||    S )aä  Calculate the surface distance between two binary edge masks.

    May return infinity if the predicted mask is empty and the target mask is not, or vice versa.

    Args:
        preds: The predicted binary edge mask.
        target: The target binary edge mask.
        distance_metric: The distance metric to use. One of `["euclidean", "chessboard", "taxicab"]`.
        spacing: The spacing between pixels along each spatial dimension.

    Returns:
        A tensor with length equal to the number of edges in predictions e.g. `preds.sum()`. Each element is the
        distance from the corresponding edge in `preds` to the closest edge in `target`.

    Example::
        >>> import torch
        >>> from torchmetrics.functional.segmentation.utils import surface_distance
        >>> preds = torch.tensor([[1, 1, 1, 1, 1],
        ...                       [1, 0, 0, 0, 1],
        ...                       [1, 0, 0, 0, 1],
        ...                       [1, 0, 0, 0, 1],
        ...                       [1, 1, 1, 1, 1]], dtype=torch.bool)
        >>> target = torch.tensor([[1, 1, 1, 1, 0],
        ...                        [1, 0, 0, 1, 0],
        ...                        [1, 0, 0, 1, 0],
        ...                        [1, 0, 0, 1, 0],
        ...                        [1, 1, 1, 1, 0]], dtype=torch.bool)
        >>> surface_distance(preds, target, distance_metric="euclidean", spacing=[1, 1])
        tensor([0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 1., 0., 0., 0., 0., 1.])

    z9Expected both inputs to be of type `torch.bool`, but got r   r   )r{   r|   )rC   r)   r=   r(   r¡   ÚinfÚ	ones_likerœ   )r   r   r¸   rž   r™   s        r   Úsurface_distancer¼   §  sÉ   € ðJ �K‰Kœ5Ÿ:™:Ò%¨&¯,©,¼%¿*¹*Ò*DÜÐTÐUZ×U`ÑU`ÐTaÐafÐgm×gsÑgsÐftÐtuÐvÓwÐwä�9‰9�VÔÜ�i‰iœ%Ÿ/™/¨&Ó1Ñ1ˆð ˆu‰:Ðô	 �y‰y˜ÔÜ—)‘)œeŸo™o¨eÓ4Ñ4ˆCØ�v‘;ÐÜ  & °7À?ÔSˆØˆu‰:Ðr   Ú	symmetricc                 óÄ   — t        | |«      }|d   j                  «       |d   j                  «       }}|rt        ||||¬«      t        ||||¬«      fS t        ||||¬«      S )a5  Extracts the edges from the input masks and calculates the surface distance between them.

    Args:
        preds: The predicted binary edge mask.
        target: The target binary edge mask.
        distance_metric: The distance metric to use. One of `["euclidean", "chessboard", "taxicab"]`.
        spacing: The spacing between pixels along each spatial dimension.
        symmetric: Whether to calculate the symmetric distance between the edges.

    Returns:
        A tensor with length equal to the number of edges in predictions e.g. `preds.sum()`. Each element is the
        distance from the corresponding edge in `preds` to the closest edge in `target`. If `symmetric` is `True`, the
        function returns a tuple containing the distances from the predicted edges to the target edges and vice versa.

    r   r   )r¸   rž   )r·   r=   r¼   )r   r   r¸   rž   r½   r]   r³   r´   s           r   Úedge_surface_distancer¿   Ù  sn   € ô, ˜˜vÓ&€FØ & q¡	§¡Ó 0°&¸±)·.±.Ó2B�€KÙä˜[¨,ÈÐahÔiÜ˜\¨;ÈÐahÔið
ð 	
ô ˜K¨ÀÐ`gÔhÐhr   rB   c                 óÀ   — t        | t        «      rt        | «      dk(  rt        | |«      S t        | t        «      rt        | «      dk(  rt	        | |«      S t        d«      ‚)aÿ  Create a table that maps neighbour codes to the contour length or surface area of the corresponding contour.

    Args:
        spacing: The spacing between pixels along each spatial dimension.
        device: The device on which the table should be created.

    Returns:
        A tuple containing as its first element the table that maps neighbour codes to the contour length or surface
        area of the corresponding contour and as its second element the kernel used to compute the neighbour codes.

    r   r'   z-The spacing must be a tuple of length 2 or 3.)ri   Útuplern   Útable_contour_lengthÚtable_surface_arear(   )rž   rB   s     r   r£   r£   ù  sT   € ô �'œ5Ô!¤c¨'£l°aÒ&7Ü# G¨VÓ4Ð4Ü�'œ5Ô!¤c¨'£l°aÒ&7Ü! '¨6Ó2Ð2Ü
ÐDÓ
EÐEr   c                 ó˜  — t        | t        «      st        | «      dk7  rt        d«      ‚| \  }}dt	        j
                  |dz  |dz  z   «      z  }t        j                  dt        j                  |¬«      }dD ]  }|||<   Œ	 dD ]  }|||<   Œ	 dD ]  }|||<   Œ	 d	D ]
  }d|z  ||<   Œ t        j                  d
dgddgggg|¬«      }||fS )a  Create a table that maps neighbour codes to the contour length of the corresponding contour.

    Adopted from:
    https://github.com/deepmind/surface-distance/blob/master/surface_distance/lookup_tables.py

    Args:
        spacing: The spacing between pixels along each spatial dimension. Should be a tuple of length 2.
        device: The device on which the table should be created.

    Returns:
        A tuple containing as its first element the table that maps neighbour codes to the contour length of the
        corresponding contour and as its second element the kernel used to compute the neighbour codes.

    Example::
        >>> from torchmetrics.functional.segmentation.utils import table_contour_length
        >>> table, kernel = table_contour_length((2,2))
        >>> table
        tensor([0.0000, 1.4142, 1.4142, 2.0000, 1.4142, 2.0000, 2.8284, 1.4142, 1.4142,
                2.8284, 2.0000, 1.4142, 2.0000, 1.4142, 1.4142, 0.0000])
        >>> kernel
        tensor([[[[8, 4],
                  [2, 1]]]])

    r   z(The spacing must be a tuple of length 2.ç      à?é   ©rC   rB   )r   r   rd   é   é   é   é   é   )r'   é   )re   é
   )é   é	   rÉ   rd   r   r    )
ri   rÁ   rn   r(   Úmathr‹   r)   ÚzerosÚfloat32Ú	as_tensor)rž   rB   ÚfirstÚsecondÚdiagr«   rt   r¬   s           r   rÂ   rÂ     sõ   € ô2 �gœuÔ%¬#¨g«,¸!Ò*;ÜÐCÓDÐDà�M€Eˆ6Ø”—‘˜5 !™8 f¨a¡iÑ/Ó0Ñ0€DÜ�K‰K˜¤%§-¡-¸Ô?€EØ(ò ˆØˆˆaŠðàò ˆØˆˆaŠðàò ˆØˆˆaŠðàò ˆØ�t‘8ˆˆaŠðä�_‰_  A ¨¨A¨Ð/Ð0Ð1¸&ÔA€FØ�&ˆ=Ðr   c                 ó\  — t        | t        «      st        | «      dk7  rt        d«      ‚g d¢}t	        j
                  g ||||g‘g d¢|||g‘g d¢|||g‘g d¢g d¢||g‘g d¢|||g‘g d	¢g d
¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d ¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢g d!¢g d"¢|g‘g d¢g d¢||g‘g d¢g d	¢g d
¢|g‘g d¢g d¢g d¢|g‘g d#¢g d$¢g d!¢g d	¢g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d%¢g d¢g d¢|g‘g d"¢g d"¢g d!¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d&¢g d¢g d'¢g‘g d¢g d¢g d¢|g‘g d¢g d ¢||g‘g d(¢g d¢g d¢|g‘g d(¢g d¢g d)¢|g‘g d(¢g d¢||g‘g d¢g d ¢g d¢|g‘g d*¢g d¢g d¢g d ¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d ¢|g‘g d(¢g d"¢g d¢g d¢g‘g d+¢g d¢g d¢g d¢g‘g d(¢g d"¢g d¢|g‘g d¢g d ¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d,¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d-¢g d¢g d¢g d'¢g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d.¢g d)¢g d¢|g‘g d)¢g d)¢g d¢g d¢g‘g d/¢g d&¢g d¢g d¢g‘g d¢g d)¢g d¢|g‘g d¢g d0¢||g‘g d%¢g d¢g d¢|g‘g d¢g d¢g d0¢|g‘g d	¢g d1¢g d¢g d¢g‘g d¢g d"¢g d¢|g‘g d%¢g d,¢||g‘g d¢g d¢g d¢g d,¢g‘g d¢g d¢g d,¢|g‘g d¢g d0¢g d¢|g‘g d%¢g d¢g d¢g d¢g‘g d¢g d¢g d¢g d0¢g‘g d¢g d
¢g d
¢|g‘g d
¢g d#¢g d ¢g d¢g‘g d%¢g d¢g d¢|g‘g d¢g d
¢g d
¢|g‘g d
¢g d
¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d!¢g d"¢g d¢g‘g d¢g d¢g d¢|g‘g d,¢g d¢g d¢g d¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d%¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d.¢g d)¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d2¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d-¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d#¢g d¢g d¢g d¢g‘g d¢g d¢g d,¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d	¢g d
¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢|||g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d	¢g d
¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d,¢|g‘g d#¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d-¢g d¢g d¢g d¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d2¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d.¢g d)¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d%¢g d¢g d¢g d¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d,¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d!¢g d"¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d
¢g d
¢||g‘g d¢g d
¢g d
¢|g‘g d%¢g d¢g d¢|g‘g d
¢g d#¢g d ¢g d¢g‘g d¢g d
¢g d
¢|g‘g d	¢g d
¢g d
¢g d
¢g‘g d%¢g d¢g d¢g d¢g‘g d¢g d0¢g d¢|g‘g d¢g d¢g d,¢|g‘g d¢g d¢g d¢g d,¢g‘g d%¢g d,¢||g‘g d¢g d"¢g d¢|g‘g d	¢g d1¢g d¢g d¢g‘g d¢g d¢g d0¢|g‘g d%¢g d¢g d¢|g‘g d¢g d0¢||g‘g d¢g d)¢g d¢|g‘g d/¢g d&¢g d¢g d¢g‘g d)¢g d)¢g d¢g d¢g‘g d.¢g d)¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d-¢g d¢g d¢g d'¢g‘g d¢g d¢g d¢|g‘g d,¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d(¢g d"¢g d¢|g‘g d+¢g d¢g d¢g d¢g‘g d(¢g d"¢g d¢g d¢g‘g d¢g d¢g d ¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d*¢g d¢g d¢g d ¢g‘g d¢g d ¢g d¢|g‘g d(¢g d¢||g‘g d(¢g d¢g d)¢|g‘g d(¢g d¢g d¢|g‘g d¢g d ¢||g‘g d¢g d¢g d¢|g‘g d¢g d&¢g d¢g d'¢g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d"¢g d"¢g d!¢g d¢g‘g d%¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d#¢g d$¢g d!¢g d	¢g‘g d¢g d¢g d¢|g‘g d¢g d	¢g d
¢|g‘g d¢g d¢||g‘g d¢g d!¢g d"¢|g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢g d ¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢g d¢g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d¢g d¢||g‘g d¢|||g‘g d¢g d¢g d¢|g‘g d¢g d¢||g‘g d	¢g d
¢||g‘g d¢|||g‘g d¢g d¢||g‘g d¢|||g‘g d¢|||g‘||||g‘t        j                  |¬3«      }t	        j                  | d4   | d5   z  | d6   | d5   z  | d6   | d4   z  ggg||j                  ¬7«      }t        j                  j                  ||z  d8¬9«      }|j                  d8«      }t	        j                  d:d;gd<d=ggd>d?gd5d4ggggg|¬@«      }||fS )Aa€  Create a table that maps neighbour codes to the surface area of the corresponding surface.

    Adopted from:
    https://github.com/deepmind/surface-distance/blob/master/surface_distance/lookup_tables.py

    Args:
        spacing: The spacing between pixels along each spatial dimension. Should be a tuple of length 3.
        device: The device on which the table should be created.

    Returns:
        A tuple containing as its first element the table that maps neighbour codes to the surface area of the
        corresponding surface and as its second element the kernel used to compute the neighbour codes.

    Example::
        >>> from torchmetrics.functional.segmentation.utils import table_surface_area
        >>> table, kernel = table_surface_area((2,2,2))
        >>> table
        tensor([0.0000, 0.8660, 0.8660, 2.8284, 0.8660, 2.8284, 1.7321, 4.5981, 0.8660,
                1.7321, 2.8284, 4.5981, 2.8284, 4.5981, 4.5981, 4.0000, 0.8660, 2.8284,
                1.7321, 4.5981, 1.7321, 4.5981, 2.5981, 5.1962, 1.7321, 3.6945, 3.6945,
                6.2925, 3.6945, 6.2925, 5.4641, 4.5981, 0.8660, 1.7321, 2.8284, 4.5981,
                1.7321, 3.6945, 3.6945, 6.2925, 1.7321, 2.5981, 4.5981, 5.1962, 3.6945,
                5.4641, 6.2925, 4.5981, 2.8284, 4.5981, 4.5981, 4.0000, 3.6945, 6.2925,
                5.4641, 4.5981, 3.6945, 5.4641, 6.2925, 4.5981, 5.6569, 3.6945, 3.6945,
                2.8284, 0.8660, 1.7321, 1.7321, 3.6945, 2.8284, 4.5981, 3.6945, 6.2925,
                1.7321, 2.5981, 3.6945, 5.4641, 4.5981, 5.1962, 6.2925, 4.5981, 2.8284,
                4.5981, 3.6945, 6.2925, 4.5981, 4.0000, 5.4641, 4.5981, 3.6945, 5.4641,
                5.6569, 3.6945, 6.2925, 4.5981, 3.6945, 2.8284, 1.7321, 2.5981, 3.6945,
                5.4641, 3.6945, 5.4641, 5.6569, 3.6945, 2.5981, 3.4641, 5.4641, 2.5981,
                5.4641, 2.5981, 3.6945, 1.7321, 4.5981, 5.1962, 6.2925, 4.5981, 6.2925,
                4.5981, 3.6945, 2.8284, 5.4641, 2.5981, 3.6945, 1.7321, 3.6945, 1.7321,
                1.7321, 0.8660, 0.8660, 1.7321, 1.7321, 3.6945, 1.7321, 3.6945, 2.5981,
                5.4641, 2.8284, 3.6945, 4.5981, 6.2925, 4.5981, 6.2925, 5.1962, 4.5981,
                1.7321, 3.6945, 2.5981, 5.4641, 2.5981, 5.4641, 3.4641, 2.5981, 3.6945,
                5.6569, 5.4641, 3.6945, 5.4641, 3.6945, 2.5981, 1.7321, 2.8284, 3.6945,
                4.5981, 6.2925, 3.6945, 5.6569, 5.4641, 3.6945, 4.5981, 5.4641, 4.0000,
                4.5981, 6.2925, 3.6945, 4.5981, 2.8284, 4.5981, 6.2925, 5.1962, 4.5981,
                5.4641, 3.6945, 2.5981, 1.7321, 6.2925, 3.6945, 4.5981, 2.8284, 3.6945,
                1.7321, 1.7321, 0.8660, 2.8284, 3.6945, 3.6945, 5.6569, 4.5981, 6.2925,
                5.4641, 3.6945, 4.5981, 5.4641, 6.2925, 3.6945, 4.0000, 4.5981, 4.5981,
                2.8284, 4.5981, 6.2925, 5.4641, 3.6945, 5.1962, 4.5981, 2.5981, 1.7321,
                6.2925, 3.6945, 3.6945, 1.7321, 4.5981, 2.8284, 1.7321, 0.8660, 4.5981,
                5.4641, 6.2925, 3.6945, 6.2925, 3.6945, 3.6945, 1.7321, 5.1962, 2.5981,
                4.5981, 1.7321, 4.5981, 1.7321, 2.8284, 0.8660, 4.0000, 4.5981, 4.5981,
                2.8284, 4.5981, 2.8284, 1.7321, 0.8660, 4.5981, 1.7321, 2.8284, 0.8660,
                2.8284, 0.8660, 0.8660, 0.0000])
        >>> kernel
        tensor([[[[[128,  64],
                   [ 32,  16]],
                  [[  8,   4],
                   [  2,   1]]]]])

    r'   z(The spacing must be a tuple of length 3.)ç        rÙ   rÙ   )ç      À?rÚ   rÚ   )ç      À¿rÛ   rÚ   )ç      Ð¿rÜ   rÙ   )ç      Ð?rÝ   ç       €)rÚ   rÛ   rÚ   )rÜ   rÞ   rÜ   )rÝ   rÙ   rÝ   )rÅ   rÙ   rÞ   )rÝ   rÝ   rÝ   )rÛ   rÚ   rÚ   )rÜ   rÙ   rÝ   )rÅ   rÙ   rÙ   )rÜ   rÜ   rÝ   )rÝ   rÜ   rÙ   )rÝ   rÜ   rÝ   )rÛ   rÚ   rÛ   )ç      à¿rÙ   rÙ   )rÜ   rÝ   rÝ   )rÚ   rÛ   rÛ   )rÙ   rÜ   rÜ   )rÙ   rÝ   rÝ   )rÙ   rß   rÙ   )rÙ   rÙ   rß   )rÛ   rÛ   rÛ   )rÜ   rÜ   rÜ   )ç      Ø?rà   rà   )rÙ   rÜ   rÝ   )rÙ   rÝ   rÜ   )rÜ   rÝ   rÙ   )rÚ   rÚ   rÛ   )rÝ   rÝ   rÜ   )ç      Ø¿rá   rà   )rÞ   rÝ   rÝ   )rÞ   rÙ   rÅ   )rà   rá   rá   )rÝ   rÝ   rÙ   )rÙ   rÅ   rÙ   )rÜ   rÝ   rÜ   )rá   rá   rá   )rá   rà   rá   )rÙ   rÙ   rÅ   )rà   rá   rà   )rÞ   rÅ   rÙ   )rÜ   rÙ   rÜ   )rÝ   rÙ   rÜ   )rá   rà   rà   )rÝ   rÜ   rÜ   rÇ   r   r   r   rA   r&   r4   é€   é@   é    rÆ   rÉ   rd   r    )ri   rÁ   rn   r(   r)   r2   rÓ   rÔ   rC   ÚlinalgÚnormr[   )rž   rB   rÒ   r«   Úspaceræ   r¬   s          r   rÃ   rÃ   :  sµ  € ôn �gœuÔ%¬#¨g«,¸!Ò*;ÜÐCÓDÐDâ€EÜ�L‰LðA	
Ø�E˜5 %Ð(ðA	
â" E¨5°%Ð8ðA	
ò % e¨U°EÐ:ðA	
ò !Ò"4°e¸UÐCð	A	
ò
 $ U¨E°5Ð9ðA	
ò "Ò#4°e¸UÐCðA	
ò $Ò%<¸eÀUÐKðA	
ò Ò1Ò3HÈ%ÐPðA	
ò $ U¨E°5Ð9ðA	
ò #Ò$:¸EÀ5ÐIðA	
ò  Ò!3°U¸EÐBðA	
ò Ò2Ò4KÈUÐSðA	
ò  Ò!3°U¸EÐBðA	
ò Ò1Ò3JÈEÐRðA	
ò Ò2Ò4JÈEÐRðA	
ò  šo¨u°eÐ<ð!A	
ò" % e¨U°EÐ:ð#A	
ò$ !Ò"3°U¸EÐBð%A	
ò& %Ò&=¸uÀeÐLð'A	
ò( Ò1Ò3HÈ%ÐPð)A	
ò* $Ò%<¸eÀUÐKð+A	
ò, Ò1Ò3KÈUÐSð-A	
ò. %Ò&<Ò>UÐW\Ð]ð/A	
ò0 &Ò'<Ò>PÒRgÐhð1A	
ò2 $Ò%<¸eÀUÐKð3A	
ò4 !Ò"3Ò5KÈUÐSð5A	
ò6  Ò!3Ò5LÈeÐTð7A	
ò8 #Ò$9Ò;MÒOaÐbð9A	
ò: %Ò&8Ò:LÈeÐTð;A	
ò< #Ò$6Ò8PÒRdÐeð=A	
ò> Ò7Ò9NÒPeÐfð?A	
ò@ Ò7Ò9NÐPUÐVðAA	
òB $ U¨E°5Ð9ðCA	
òD #Ò$:¸EÀ5ÐIðEA	
òF  Ò!3°U¸EÐBðGA	
òH Ò5Ò7JÈEÐRðIA	
òJ $Ò%;¸UÀEÐJðKA	
òL $Ò%9Ò;LÈeÐTðMA	
òN  Ò!3Ò5KÈUÐSðOA	
òP %Ò&8Ò:PÒRfÐgðQA	
òR $Ò%;¸UÀEÐJðSA	
òT #Ò$:Ò<RÐTYÐZðUA	
òV Ò3Ò5LÈeÐTðWA	
òX !Ò"5Ò7MÒOfÐgðYA	
òZ $Ò%7Ò9KÈUÐSð[A	
ò\ Ò1Ò3JÒLbÐcð]A	
ò^  Ò!8Ò:PÒRcÐdð_A	
ò` Ò3Ò5LÈeÐTðaA	
òb  Ò!3°U¸EÐBðcA	
òd Ò1Ò3JÈEÐRðeA	
òf Ò4Ò6JÈEÐRðgA	
òh Ò.°°uÐ=ðiA	
òj  Ò!3Ò5KÈUÐSðkA	
òl &Ò'9Ò;SÒUgÐhðmA	
òn #Ò$4Ò6KÒMeÐfðoA	
òp Ò4Ò6NÐPUÐVðqA	
òr $Ò%7Ò9KÈUÐSðsA	
òt Ò1Ò3JÒLcÐdðuA	
òv %Ò&9Ò;RÒTfÐgðwA	
òx Ò1Ò3JÈEÐRðyA	
òz  Ò!3Ò5GÒI[Ð\ð{A	
ò| !Ò"5Ò7NÐPUÐVð}A	
ò~ #Ò$7Ò9LÈeÐTðA	
ò@ !Ò"5°u¸eÐDðAA	
òB % e¨U°EÐ:ðCA	
òD #Ò$;¸UÀEÐJðEA	
òF %Ò&=¸uÀeÐLðGA	
òH %Ò&9Ò;MÈuÐUðIA	
òJ  Ò!3°U¸EÐBðKA	
òL Ò1Ò3IÈ5ÐQðMA	
òN  Ò!3Ò5LÈeÐTðOA	
òP $Ò%8Ò:QÒSdÐeðQA	
òR %Ò&<¸eÀUÐKðSA	
òT #Ò$;Ò=SÐUZÐ[ðUA	
òV %Ò&8Ò:LÈeÐTðWA	
òX Ò2Ò4KÒMdÐeðYA	
òZ Ò3Ò5KÈUÐSð[A	
ò\ "Ò#7Ò9PÒRiÐjð]A	
ò^ !Ò"9Ò;MÒOeÐfð_A	
ò` Ò2Ò4JÈEÐRðaA	
òb  Ò!3°U¸EÐBðcA	
òd Ò2Ò4JÈEÐRðeA	
òf %Ò&8Ò:LÈeÐTðgA	
òh "Ò#9Ò;NÒPfÐgðiA	
òj Ò2Ò4KÈUÐSðkA	
òl š°°uÐ=ðmA	
òn #Ò$9Ò;MÊÐ_ðoA	
òp #Ò$6ºÈÐOðqA	
òr  Ò!3Ò5KÈUÐSðsA	
òt Ò2Ò4JÒLbÐcðuA	
òv  Ò!3Ò5GÒI[Ð\ðwA	
òx $Ò%6Ò8IÈ5ÐQðyA	
òz Ò 7Ò9KÒMdÐeð{A	
ò| Ò2Ò4JÈEÐRð}A	
ò~ #Ò$5Ò7HÈ%ÐPðA	
ò@ Ò 1°5¸%Ð@ðAA	
òB %Ò&<¸eÀUÐKðCA	
òD #Ò$;Ò=SÐUZÐ[ðEA	
òF %Ò&8Ò:LÈeÐTðGA	
òH Ò5Ò7JÒLcÐdðIA	
òJ  Ò!3Ò5KÈUÐSðKA	
òL Ò1Ò3IÒKaÐbðMA	
òN  Ò!3Ò5GÒI[Ð\ðOA	
òP Ò 1Ò3JÈEÐRðQA	
òR $Ò%;Ò=TÐV[Ð\ðSA	
òT $Ò%;Ò=TÒVkÐlðUA	
òV Ò3Ò5LÒNeÐfðWA	
òX #Ò$:Ò<SÐUZÐ[ðYA	
òZ Ò3Ò5KÒMcÐdð[A	
ò\ #Ò$;Ò=TÐV[Ð\ð]A	
ò^ !Ò"3Ò5JÈEÐRð_A	
ò` #Ò$;¸UÀEÐJðaA	
òb Ò3Ò5LÈeÐTðcA	
òd !Ò"8Ò:MÒOfÐgðeA	
òf $Ò%6Ò8OÒQcÐdðgA	
òh Ò2Ò4JÈEÐRðiA	
òj %Ò&8Ò:KÒMdÐeðkA	
òl $Ò%8º/È5ÐQðmA	
òn #Ò$5Ò7HÈ%ÐPðoA	
òp Ò 1°5¸%Ð@ðqA	
òr Ò1Ò3HÒJ_Ð`ðsA	
òt $Ò%<Ò>SÐUZÐ[ðuA	
òv "Ò#4Ò6KÈUÐSðwA	
òx #Ò$:¸EÀ5ÐIðyA	
òz !Ò"4Ò6KÈUÐSð{A	
ò| #Ò$;¸UÀEÐJð}A	
ò~ #Ò$9¸5À%ÐHðA	
ò@ # E¨5°%Ð8ðAA	
òB # E¨5°%Ð8ðCA	
òD #Ò$9¸5À%ÐHðEA	
òF #Ò$;¸UÀEÐJðGA	
òH !Ò"4Ò6KÈUÐSðIA	
òJ #Ò$:¸EÀ5ÐIðKA	
òL "Ò#4Ò6KÈUÐSðMA	
òN $Ò%<Ò>SÐUZÐ[ðOA	
òP Ò1Ò3HÒJ_Ð`ðQA	
òR Ò 1°5¸%Ð@ðSA	
òT #Ò$5Ò7HÈ%ÐPðUA	
òV $Ò%8º/È5ÐQðWA	
òX %Ò&8Ò:KÒMdÐeðYA	
òZ Ò2Ò4JÈEÐRð[A	
ò\ $Ò%6Ò8OÒQcÐdð]A	
ò^ !Ò"8Ò:MÒOfÐgð_A	
ò` Ò3Ò5LÈeÐTðaA	
òb #Ò$;¸UÀEÐJðcA	
òd !Ò"3Ò5JÈEÐRðeA	
òf #Ò$;Ò=TÐV[Ð\ðgA	
òh Ò3Ò5KÒMcÐdðiA	
òj #Ò$:Ò<SÐUZÐ[ðkA	
òl Ò3Ò5LÒNeÐfðmA	
òn $Ò%;Ò=TÒVkÐlðoA	
òp $Ò%;Ò=TÐV[Ð\ðqA	
òr Ò 1Ò3JÈEÐRðsA	
òt !Ò"3Ò5FÒHYÐZðuA	
òv Ò1Ò3IÒKaÐbðwA	
òx  Ò!3Ò5KÈUÐSðyA	
òz Ò5Ò7JÒLcÐdð{A	
ò| %Ò&8Ò:LÈeÐTð}A	
ò~ #Ò$;Ò=SÐUZÐ[ðA	
ò@ %Ò&<¸eÀUÐKðAA	
òB Ò 1°5¸%Ð@ðCA	
òD #Ò$5Ò7HÈ%ÐPðEA	
òF Ò2Ò4JÈEÐRðGA	
òH Ò 7Ò9KÒMdÐeðIA	
òJ $Ò%6Ò8IÈ5ÐQðKA	
òL "Ò#4Ò6GÒIZÐ[ðMA	
òN Ò2Ò4JÒLbÐcðOA	
òP  Ò!3Ò5KÈUÐSðQA	
òR #Ò$6ºÈÐOðSA	
òT #Ò$9Ò;MÊÐ_ðUA	
òV š°°uÐ=ðWA	
òX Ò2Ò4KÈUÐSðYA	
òZ "Ò#9Ò;NÒPfÐgð[A	
ò\ %Ò&8Ò:LÈeÐTð]A	
ò^ Ò2Ò4JÈEÐRð_A	
ò`  Ò!3°U¸EÐBðaA	
òb Ò2Ò4JÈEÐRðcA	
òd !Ò"9Ò;MÒOeÐfðeA	
òf "Ò#7Ò9PÒRiÐjðgA	
òh Ò3Ò5KÈUÐSðiA	
òj Ò2Ò4KÒMdÐeðkA	
òl %Ò&8Ò:LÈeÐTðmA	
òn #Ò$;Ò=SÐUZÐ[ðoA	
òp %Ò&<¸eÀUÐKðqA	
òr $Ò%8Ò:QÒSdÐeðsA	
òt  Ò!3Ò5LÈeÐTðuA	
òv Ò1Ò3IÈ5ÐQðwA	
òx  Ò!3°U¸EÐBðyA	
òz %Ò&9Ò;MÈuÐUð{A	
ò| %Ò&=¸uÀeÐLð}A	
ò~ #Ò$;¸UÀEÐJðA	
ò@ % e¨U°EÐ:ðAA	
òB !Ò"5°u¸eÐDðCA	
òD #Ò$7Ò9LÈeÐTðEA	
òF !Ò"5Ò7NÐPUÐVðGA	
òH !Ò"5Ò7JÒL^Ð_ðIA	
òJ Ò1Ò3JÈEÐRðKA	
òL %Ò&9Ò;RÒTfÐgðMA	
òN Ò1Ò3JÒLcÐdðOA	
òP $Ò%7Ò9KÈUÐSðQA	
òR Ò4Ò6NÐPUÐVðSA	
òT #Ò$4Ò6KÒMeÐfðUA	
òV &Ò'9Ò;SÒUgÐhðWA	
òX  Ò!3Ò5KÈUÐSðYA	
òZ Ò.°°uÐ=ð[A	
ò\ Ò4Ò6JÈEÐRð]A	
ò^ Ò1Ò3JÈEÐRð_A	
ò`  Ò!3°U¸EÐBðaA	
òb Ò3Ò5LÈeÐTðcA	
òd  Ò!8Ò:PÒRcÐdðeA	
òf Ò1Ò3JÒLbÐcðgA	
òh $Ò%7Ò9KÈUÐSðiA	
òj !Ò"5Ò7MÒOfÐgðkA	
òl Ò3Ò5LÈeÐTðmA	
òn #Ò$:Ò<RÐTYÐZðoA	
òp $Ò%;¸UÀEÐJðqA	
òr %Ò&8Ò:PÒRfÐgðsA	
òt  Ò!3Ò5KÈUÐSðuA	
òv $Ò%9Ò;LÈeÐTðwA	
òx $Ò%;¸UÀEÐJðyA	
òz Ò5Ò7JÈEÐRð{A	
ò|  Ò!3°U¸EÐBð}A	
ò~ #Ò$:¸EÀ5ÐIðA	
ò@ $ U¨E°5Ð9ðAA	
òB Ò7Ò9NÐPUÐVðCA	
òD Ò7Ò9NÒPeÐfðEA	
òF #Ò$6Ò8PÒRdÐeðGA	
òH %Ò&8Ò:LÈeÐTðIA	
òJ #Ò$9Ò;MÒOaÐbðKA	
òL  Ò!3Ò5LÈeÐTðMA	
òN !Ò"3Ò5KÈUÐSðOA	
òP $Ò%<¸eÀUÐKðQA	
òR &Ò'<Ò>PÒRgÐhðSA	
òT %Ò&<Ò>UÐW\Ð]ðUA	
òV Ò1Ò3KÈUÐSðWA	
òX $Ò%<¸eÀUÐKðYA	
òZ Ò1Ò3HÈ%ÐPð[A	
ò\ %Ò&=¸uÀeÐLð]A	
ò^ !Ò"3°U¸EÐBð_A	
ò` % e¨U°EÐ:ðaA	
òb šo¨u°eÐ<ðcA	
òd Ò2Ò4JÈEÐRðeA	
òf Ò1Ò3JÈEÐRðgA	
òh  Ò!3°U¸EÐBðiA	
òj Ò2Ò4KÈUÐSðkA	
òl  Ò!3°U¸EÐBðmA	
òn #Ò$:¸EÀ5ÐIðoA	
òp $ U¨E°5Ð9ðqA	
òr Ò1Ò3HÈ%ÐPðsA	
òt $Ò%<¸eÀUÐKðuA	
òv "Ò#4°e¸UÐCðwA	
òx # E¨5°%Ð8ðyA	
òz !Ò"4°e¸UÐCð{A	
ò| # E¨5°%Ð8ð}A	
ò~ # E¨5°%Ð8ðA	
ð@ �E˜5 %Ð(ðAA	
ôD �m‰mØôIE€EôN �O‰OØ�1‰:˜ ™
Ñ" G¨A¡J°¸±Ñ$;¸WÀQ¹ZÈ'ÐRSÉ*Ñ=TÐ
UÐ	VÐWØØ�k‰kô€Eô
 �<‰<×Ñ˜U U™]°ÐÓ3€DØ�H‰H�R‹L€EÜ�_‰_ # r ¨R°¨HÐ 5¸¸A¸ÀÀAÀÐ7GÐHÐIÐJÐSYÔZ€FØ�&ˆ=Ðr   )Nr!   )NNr   )Nr~   rƒ   )TN)r~   N)r~   NF)N))Ú	functoolsrÑ   Útypingr   r   r)   r   Útorch.nn.functionalr   r   r   r	   Útyping_extensionsr
   Útorchmetrics.utilities.checksr   Útorchmetrics.utilities.importsr   rÁ   r   r   r=   rl   r1   r/   r.   r>   rO   r^   rz   rˆ   ro   rœ   r·   r¼   r¿   Ú	lru_cacherB   r£   rÂ   rÃ   © r   r   ú<module>rð      sE  ðó Û ß "ã Ý ß ;Ó ;Ý %å ;Ý ;ð˜fð ¨fð ¸¸vÀv¸~Ñ9Nó ð
˜fð 
¨fð 
¸ó 
ð, "&Ø9Bñ)Øð)àð)ð ð)ð ˜#‘ð	)ð
 Ð5Ñ6ð)ð ˆ6�6ˆ>Ñó)ðX˜6ð °ð ¸ó ð˜Vð ¨ó ð
8˜&ð 
8 Tó 
8ðJˆvð J E¨#¨s¨(¡Oð J¸ó Jð0(" Cð ("°sð ("¸vó ("ðX vwñC;ØðC;Ø& vÑ.ðC;Ø?GÈÈcÐSVÈhÉÑ?XðC;ØorðC;àóC;ðP 6:Ø<GØ*3ñ	aTØðaTà�u˜V T¨%¡[Ð0Ñ1Ñ2ðaTð Ð8Ñ9ðaTð Ð&Ñ'ð	aTð
 óaTðN ØFJñ	7LØð7Làð7Lð ð7Lð �e˜E # s (™O¨U°3¸¸S°=Ñ-AÐAÑBÑCð	7Lð
 ˆ5�˜�Ñ  %¨°¸ÀÐ(FÑ"GÐGÑHó7Lðz FQØ48ñ	/Øð/àð/ð ÐAÑBð/ð �e˜F D¨¡KÐ/Ñ0Ñ1ð	/ð
 ó/ðj FQØ48ØñiØðiàðið ÐAÑBðið �e˜F D¨¡KÐ/Ñ0Ñ1ð	ið
 ðið ˆ6�5˜ ˜Ñ(Ð(Ñ)óið@ ×Ñà\`ñFØ�5˜˜c˜‘? E¨#¨s°C¨-Ñ$8Ð8Ñ9ðFØCKÈEÏLÉLÑCYðFà
ˆ6�6ˆ>ÑòFó ðFñ*( %¨¨S¨¡/ð (¸8ÀEÇLÁLÑ;Qð (Ð]bÐciÐkqÐcqÑ]ró (ðV ×ÑñI  c¨3° mÑ 4ð I¸hÀuÇ|Á|Ñ>Tð IÐ`eÐflÐntÐftÑ`uò Ió ñIr   