U
    žPÓhã  ã                   @  sT   d dl mZ d dlmZ d dlZd dlmZ G dd„ deƒZddddd	œd
d„ZdS )é    )Úannotations)ÚCallableN)ÚMetricc                      s<   e Zd ZdZddddœ‡ fdd„Zdddd	œd
d„Z‡  ZS )Ú	MMDMetricaÅ  
    Unbiased Maximum Mean Discrepancy (MMD) is a kernel-based method for measuring the similarity between two
    distributions. It is a non-negative metric where a smaller value indicates a closer match between the two
    distributions.

    Gretton, A., et al,, 2012.  A kernel two-sample test. The Journal of Machine Learning Research, 13(1), pp.723-773.

    Args:
        y_mapping: Callable to transform the y tensors before computing the metric. It is usually a Gaussian or Laplace
            filter, but it can be any function that takes a tensor as input and returns a tensor as output such as a
            feature extractor or an Identity function., e.g. `y_mapping = lambda x: x.square()`.
    NúCallable | NoneÚNone)Ú	y_mappingÚreturnc                   s   t ƒ  ¡  || _d S ©N)ÚsuperÚ__init__r   )Úselfr   ©Ú	__class__© úF/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/metrics/mmd.pyr   #   s    
zMMDMetric.__init__útorch.Tensor)ÚyÚy_predr	   c                 C  s   t ||| jƒS r
   )Úcompute_mmdr   )r   r   r   r   r   r   Ú__call__'   s    zMMDMetric.__call__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__classcell__r   r   r   r   r      s   r   r   r   )r   r   r   r	   c                 C  s‚  |j d dks| j d dkr$tdƒ‚|dk	r<|| ƒ} ||ƒ}|j | j kr`td|j › d| j › ƒ‚tt| j ƒd ddƒD ]}| j|d} |j|d}qv|  | j d d¡} | |j d d¡}t | |  ¡ ¡}t || ¡ ¡}t ||  ¡ ¡}| j d }|j d }d||d   }	t 	|t 
t |¡¡ ¡}
d||d   }t 	|t 
t |¡¡ ¡}d	||  }t 	|¡}|	|
 ||  ||  }|S )
a-  
    Args:
        y: first sample (e.g., the reference image). Its shape is (B,C,W,H) for 2D data and (B,C,W,H,D) for 3D.
        y_pred: second sample (e.g., the reconstructed image). It has similar shape as y.
        y_mapping: Callable to transform the y tensors before computing the metric.
    r   é   z9MMD metric requires at least two samples in y and y_pred.Nz[y_pred and y shapes dont match after being processed by their transforms, received y_pred: z and y: éÿÿÿÿ)Údimé   )ÚshapeÚ
ValueErrorÚrangeÚlenÚsqueezeÚviewÚtorchÚmmÚtÚsumÚdiagÚdiagonal)r   r   r   ÚdZy_yZy_pred_y_predZy_pred_yÚmÚnÚc1ÚaÚc2ÚbÚc3ÚcÚmmdr   r   r   r   +   s6    ÿ


r   )	Ú
__future__r   Úcollections.abcr   r&   Zmonai.metrics.metricr   r   r   r   r   r   r   Ú<module>   s
   