o
    yi                     @   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eef fddZ		dded	ededed d
ef
ddZ		dded	ededed d
ef
ddZdS )    )TupleN)Tensor)Literal)universal_image_quality_index)_check_same_shape)reducepredstargetreturnc                 C   s`   | j |j krtd| j  d|j  dt| | t| jdkr,td| j d|j d| |fS )zUpdates and returns variables required to compute Spectral Distortion Index. Checks for same shape and type
    of the input tensors.

    Args:
        preds: Low resolution multispectral image
        target: High resolution fused image
    z>Expected `ms` and `fused` to have the same data type. Got ms: z and fused: .   z@Expected `preds` and `target` to have BxCxHxW shape. Got preds: z and target: )dtype	TypeErrorr   lenshape
ValueError)r   r	    r   Z/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/image/d_lambda.py!_spectral_distortion_index_update   s   	
r      elementwise_meanp	reduction)r   sumnonec              
   C   s`  | j d }t||f}t||f}t|D ]h}t||D ]`}t|dd||d ddddf |dd||d ddddf  |||f< |||f< t| dd||d ddddf | dd||d ddddf  |||f< |||f< qqtt|| |}	|dkrt|	d| }
ntd||d   t|	 d| }
t|
|S )a  Computes Spectral Distortion Index (SpectralDistortionIndex_)

    Args:
        preds: Low resolution multispectral image
        target: High resolution fused image
        p: a parameter to emphasize large spectral difference
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'``: no reduction will be applied

    Example:
        >>> _ = torch.manual_seed(42)
        >>> preds = torch.rand([16, 3, 16, 16])
        >>> target = torch.rand([16, 3, 16, 16])
        >>> preds, target = _spectral_distortion_index_update(preds, target)
        >>> _spectral_distortion_index_compute(preds, target)
        tensor(0.0234)
    r   Ng      ?)	r   torchzerosranger   powabsr   r   )r   r	   r   r   lengthm1m2krdiffoutputr   r   r   "_spectral_distortion_index_compute/   s   
^`&
r'   c                 C   s>   t |tr	|dkrtd| dt| |\} }t| |||S )a  Calculates `Spectral Distortion Index`_ (SpectralDistortionIndex_) also known as D_lambda that is used to
    compare the spectral distortion between two images.

    Args:
        preds: Low resolution multispectral image
        target: High resolution fused image
        p: Large spectral differences
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'``: no reduction will be applied

    Return:
        Tensor with SpectralDistortionIndex score

    Raises:
        TypeError:
            If ``preds`` and ``target`` don't have the same data type.
        ValueError:
            If ``preds`` and ``target`` don't have ``BxCxHxW shape``.
        ValueError:
            If ``p`` is not a positive integer.

    Example:
        >>> from torchmetrics.functional import spectral_distortion_index
        >>> _ = torch.manual_seed(42)
        >>> preds = torch.rand([16, 3, 16, 16])
        >>> target = torch.rand([16, 3, 16, 16])
        >>> spectral_distortion_index(preds, target)
        tensor(0.0234)
    r   z.Expected `p` to be a positive integer. Got p: r   )
isinstanceintr   r   r'   )r   r	   r   r   r   r   r   spectral_distortion_index[   s   &r*   )r   r   )typingr   r   r   typing_extensionsr   !torchmetrics.functional.image.uqir   torchmetrics.utilities.checksr   "torchmetrics.utilities.distributedr   r   r)   r'   r*   r   r   r   r   <module>   sD   
/