o
    yiZ                     @   sj   d dl mZ d dlZd dlmZ deddfddZdedeeef fdd	Zdedeeef fd
dZdS )    )TupleN)Tensorimgreturnc                 C   s<   t | tstdt|  | jdkrtd| j ddS )z+Validates whether img is a 4D torch Tensor.z3The `img` expects a value of <Tensor> type but got    z&The `img` expects a 4D tensor but got zD tensorN)
isinstancer   	TypeErrortypendimRuntimeErrorr    r   [/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/image/gradients.py_image_gradients_validate   s
   

r   c           	      C   s   | j \}}}}| dddddf | dddddf  }| dddddf | dddddf  }||d|g}tj|tj|| j| jdgdd}|| j }|||dg}tj|tj|| j| jdgdd}|| j }||fS )	z3Computes image gradients (dy/dx) for a given image..   N)devicedtype   )dim   )shapetorchcatzerosr   r   view)	r   
batch_sizechannelsheightwidthdydxshapeyshapexr   r   r   _compute_image_gradients   s   ,,""r$   c                 C   s   t |  t| S )as  Computes `Gradient Computation of Image`_ of a given image using finite difference.

    Args:
        img: An ``(N, C, H, W)`` input tensor where ``C`` is the number of image channels

    Return:
        Tuple of ``(dy, dx)`` with each gradient of shape ``[N, C, H, W]``

    Raises:
        TypeError:
            If ``img`` is not of the type :class:`~torch.Tensor`.
        RuntimeError:
            If ``img`` is not a 4D tensor.

    Example:
        >>> from torchmetrics.functional import image_gradients
        >>> image = torch.arange(0, 1*1*5*5, dtype=torch.float32)
        >>> image = torch.reshape(image, (1, 1, 5, 5))
        >>> dy, dx = image_gradients(image)
        >>> dy[0, 0, :, :]
        tensor([[5., 5., 5., 5., 5.],
                [5., 5., 5., 5., 5.],
                [5., 5., 5., 5., 5.],
                [5., 5., 5., 5., 5.],
                [0., 0., 0., 0., 0.]])

    .. note:: The implementation follows the 1-step finite difference method as followed
           by the TF implementation. The values are organized such that the gradient of
           [I(x+1, y)-[I(x, y)]] are at the (x, y) location
    )r   r$   r   r   r   r   image_gradients0   s   r%   )typingr   r   r   r   r$   r%   r   r   r   r   <module>   s   	