o
    .wi                     @   s  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ed	ed
eded ded ddfddZ		d dededed	eded ded deeef fddZd!deded
edefddZ				d"dededed	ed
eded ded defddZdS )#    )TupleN)Tensor)Literal)_ignore_background)_check_same_shape)_safe_dividenum_classesinclude_background	per_classweight_typesquaresimplelinearinput_formatone-hotindexreturnc                 C   s   t | tr	| dkrtd|  dt |tstd| dt |ts+td| d|dvr7td| d|dvrCtd	| dd
S )z%Validate the arguments of the metric.r   zDExpected argument `num_classes` must be a positive integer, but got .zBExpected argument `include_background` must be a boolean, but got z9Expected argument `per_class` must be a boolean, but got r   zSExpected argument `weight_type` to be one of 'square', 'simple', 'linear', but got r   zJExpected argument `input_format` to be one of 'one-hot', 'index', but got N)
isinstanceint
ValueErrorbool)r   r	   r
   r   r    r   r/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/segmentation/generalized_dice.py_generalized_dice_validate_args   s   


r   r   r   predstargetc                 C   sx  t | | |dkr#tjjj| |ddd} tjjj||ddd}| jdk r1td| j d|s:t| |\} }t	t
d|j}tj| | |d	}tj||d	}tj| |d	}	||	 }
|d
krfd| }n|dkrpt|}n|dkr{d|d  }ntd| d|j}| }t|}d||< t|dj|d dj }|| ||< ||}d| | }|
| }||fS )z8Update the state with the current prediction and target.r   )r         zJExpected both `preds` and `target` to have at least 3 dimensions, but got r      )dimr   g      ?r   r   zSExpected argument `weight_type` to be one of 'simple', 'linear', 'square', but got r   g       @)r   torchnn
functionalone_hotmovedimndimr   r   listrangesum	ones_likeshapeflattenisinfmaxvaluesrepeatTreshape)r   r   r   r	   r   r   reduce_axisintersection
target_sumpred_sumcardinalityweightsw_shapeweights_flatteninfsw_max	numeratordenominatorr   r   r   _generalized_dice_update/   s@   
	



 
rB   Tr@   rA   c                 C   s&   |st | d} t |d}t| |S )z#Compute the generalized dice score.r    )r$   r,   r   )r@   rA   r
   r   r   r   _generalized_dice_computea   s   
rC   Fc           	      C   s2   t ||||| t| |||||\}}t|||S )a  Compute the Generalized Dice Score for semantic segmentation.

    Args:
        preds: Predictions from model
        target: Ground truth values
        num_classes: Number of classes
        include_background: Whether to include the background class in the computation
        per_class: Whether to compute the score for each class separately, else average over all classes
        weight_type: Type of weight factor to apply to the classes. One of ``"square"``, ``"simple"``, or ``"linear"``
        input_format: What kind of input the function receives. Choose between ``"one-hot"`` for one-hot encoded tensors
            or ``"index"`` for index tensors

    Returns:
        The Generalized Dice Score

    Example (with one-hot encoded tensors):
        >>> from torch import randint
        >>> from torchmetrics.functional.segmentation import generalized_dice_score
        >>> preds = randint(0, 2, (4, 5, 16, 16))  # 4 samples, 5 classes, 16x16 prediction
        >>> target = randint(0, 2, (4, 5, 16, 16))  # 4 samples, 5 classes, 16x16 target
        >>> generalized_dice_score(preds, target, num_classes=5)
        tensor([0.4830, 0.4935, 0.5044, 0.4880])
        >>> generalized_dice_score(preds, target, num_classes=5, per_class=True)
        tensor([[0.4724, 0.5185, 0.4710, 0.5062, 0.4500],
                [0.4571, 0.4980, 0.5191, 0.4380, 0.5649],
                [0.5428, 0.4904, 0.5358, 0.4830, 0.4724],
                [0.4715, 0.4925, 0.4797, 0.5267, 0.4788]])

    Example (with index tensors):
        >>> from torch import randint
        >>> from torchmetrics.functional.segmentation import generalized_dice_score
        >>> preds = randint(0, 5, (4, 16, 16))  # 4 samples, 5 classes, 16x16 prediction
        >>> target = randint(0, 5, (4, 16, 16))  # 4 samples, 5 classes, 16x16 target
        >>> generalized_dice_score(preds, target, num_classes=5, input_format="index")
        tensor([0.1991, 0.1971, 0.2350, 0.2216])
        >>> generalized_dice_score(preds, target, num_classes=5, per_class=True, input_format="index")
        tensor([[0.1714, 0.2500, 0.1304, 0.2524, 0.2069],
                [0.1837, 0.2162, 0.0962, 0.2692, 0.1895],
                [0.3866, 0.1348, 0.2526, 0.2301, 0.2083],
                [0.1978, 0.2804, 0.1714, 0.1915, 0.2783]])

    )r   rB   rC   )	r   r   r   r	   r
   r   r   r@   rA   r   r   r   generalized_dice_scorei   s
   3rD   )r   r   )T)TFr   r   )typingr   r$   r   typing_extensionsr   *torchmetrics.functional.segmentation.utilsr   torchmetrics.utilities.checksr   torchmetrics.utilities.computer   r   r   r   rB   rC   rD   r   r   r   r   <module>   sv   


2