o
    .wi"                  	   @   s  d dl mZ d dlmZmZ d dl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 es:dgZnd d	lmZmZ ee jd
 d ZG dd de	jZG dd dej	jZde
de
de
fddZde
deed  de
fddZ	dde
de
deed  de
fddZdS )    )Path)ListOptionalN)Tensor)conv2d)Literal)_TORCHVISION_AVAILABLE+deep_image_structure_and_texture_similarity)VGG16_Weightsvgg16dists_modelsz
weights.ptc                	       sP   e Zd ZU dZeed< ddededed	d
f fddZded	efddZ  Z	S )	L2poolingzL2 pooling layer.filter         filter_sizestridechannelsreturnNc              	      s   t    |d d | _|| _|| _t|dd }t|d d d f |d d d f  }|t	| }| 
d|d d d d d d f | jddd d S )Nr      r   )super__init__paddingr   r   nphanningtorchr   sumregister_bufferrepeat)selfr   r   r   ag	__class__ `/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/image/dists.pyr   =   s   
&2zL2pooling.__init__tensorc                 C   s2   |d }t || j| j| j|jd d}|d  S )zForward pass of the layer.r   r   )r   r   groupsg-q=)r   r   r   r   shapesqrt)r!   r(   outr&   r&   r'   forwardG   s   zL2pooling.forward)r   r   r   )
__name__
__module____qualname____doc__r   __annotations__intr   r-   __classcell__r&   r&   r$   r'   r   8   s
   
  
r   c                	       s   e Zd ZU dZeed< eed< eed< eed< ddedd	f fd
dZdedee fddZ	ddedededefddZ
  ZS )DISTSNetworkzDISTS network.alphabetameanstdTload_weightsr   Nc                    s  t    tstdttjdj}tj	
 | _tj	
 | _tj	
 | _tj	
 | _tj	
 | _tdD ]}| jt|||  q4| jtdtdd tddD ]}| jt|||  qS| jtdtdd td	d
D ]}| jt|||  qr| jtd
tdd tddD ]}| jt|||  q| jtdtdd tddD ]}| jt|||  q|  D ]}d|_q| dtg ddddd | dtg ddddd g d| _| dt	tdt| jdd | dt	tdt| jdd | jj dd | j!j dd |rGt"# s2t$dt" t%tt"}|d | j_|d | j!_d S d S )Nz]DISTS requires torchvision to be installed. Please install it with `pip install torchvision`.)weights   @   )r   r   	      
                        Fr8   )g
ףp=
?gv/?gCl?r   r   r9   )gZd;O?gy&1?g?)r   r=   r?   rB   rE   rE   r6   r7   g?g{Gz?z!The weights file is not found in )&r   r   r   ModuleNotFoundErrorr   r
   DEFAULTfeaturesr   nn
Sequentialstage1stage2stage3stage4stage5range
add_modulestrr   
parametersrequires_gradr   r(   viewchnsregister_parameter	Parameterrandnr   r6   datanormal_r7   _PATH_WEIGHT_DISTSexistsFileNotFoundErrorload)r!   r:   vgg_pretrained_featuresxparamr;   r$   r&   r'   r   V   sR   
""
$$
zDISTSNetwork.__init__rc   c                 C   sf   || j  | j }| |}|}| |}|}| |}|}| |}|}| |}|}||||||gS )zForward pass of the network.)r8   r9   rM   rN   rO   rP   rQ   )r!   rc   h	h_relu1_2	h_relu2_2	h_relu3_3	h_relu4_3	h_relu5_3r&   r&   r'   forward_once   s   




zDISTSNetwork.forward_onceFyrequire_gradc                 C   s  |r|  |}|  |}nt  |  |}|  |}W d   n1 s&w   Y  tjd|jd}tjd|jd}d\}}	| j | j  }
tj| j|
 | j	dd}tj| j|
 | j	dd}t
t| j	D ]}|| jddgd	d
}|| jddgd	d
}d| | | |d |d  |  }||| | jdd	d
 }|| | d jddgd	d
}|| | d jddgd	d
}|| ||  jddgd	d
||  }d| |	 || |	  }||| | jdd	d
 }qhd||   S )z(Computes DISTS score between two images.Ng        )device)ư>ro   r   )dimr   r   T)keepdim)rk   r   inference_moder(   rn   r6   r   r7   splitrX   rR   lenr8   squeeze)r!   rc   rl   rm   feats0feats1dist1dist2c1c2w_sumr6   r7   kx_meany_means1x_vary_varxy_covs2r&   r&   r'   r-      s0   


$&zDISTSNetwork.forward)T)F)r.   r/   r0   r1   r   r2   boolr   r   rk   r-   r4   r&   r&   r$   r'   r5   N   s   
 /$r5   predstargetr   c                 C   s   t  | j}|| || jdS )N)rm   )r5   torn   rV   )r   r   distsr&   r&   r'   _dists_update   s   r   scores	reduction)r   r8   nonec                 C   sH   |dkr|   S |dkr|  S |d u s|dkr| S td| d| )Nr   r8   r   z	Argument z8 is not valid. Choose 'sum', 'mean' or 'none'., but got )r   r8   
ValueError)r   r   r&   r&   r'   _dists_compute   s   r   c                 C   s   t | |}t||S )a  Calculates `Deep Image Structure and Texture Similarity`_ (DISTS) score.

    Args:
        preds: Predicted image tensor.
        target: Target image tensor.
        reduction: Reduction method for the output.

    Returns:
        DISTS Similarity score between the two images.

    Example:
        >>> from torch import rand
        >>> preds = rand(5, 3, 256, 256)
        >>> target = rand(5, 3, 256, 256)
        >>> deep_image_structure_and_texture_similarity(preds, target)
        tensor([0.1285, 0.1344, 0.1356, 0.1277, 0.1276], grad_fn=<RsubBackward1>)
        >>> deep_image_structure_and_texture_similarity(preds, target, reduction='mean')
        tensor(0.1308, grad_fn=<MeanBackward0>)

    )r   r   )r   r   r   r   r&   r&   r'   r	      s   

)N)pathlibr   typingr   r   numpyr   r   torch.nnrK   r   torch.nn.functionalr   typing_extensionsr   torchmetrics.utilities.importsr   __doctest_skip__torchvision.modelsr
   r   __file__resolveparentr^   Moduler   r5   r   r   r	   r&   r&   r&   r'   <module>   s6   #d
