
    3jKi                       S SK Jr  S SKJrJr  S SKJr  S SKrS"S#S jjrS"S#S jjr	S"S#S jjr
 " S	 S
\5      rS$S%S jjrS$S&S jjr " S S\R                  R                  5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r\R.                  SS4           S'S jjr\R.                  SS4           S'S jjr\R.                  SS4           S'S jjr\R.                  SS4           S'S jjr\R.                  SS4           S'S  jjr\R.                  SS4           S'S! jjrg)(    )annotations)Enummember)partialN      ?c                6   U R                  5       R                  SU-  5      nUSU-  S-
  -  S-   nUSU-  S-
  -  S-   n[        R                  " US:  U[        R                  " US:*  U[        R                  " SU R
                  U R                  S	95      5      $ )
a  Implementation of a 2nd-order polynomial kernel for Kernel density estimate (Xu et al., 2008).

Support: [-window_radius, window_radius]. Returns 0 outside this range.
Ref: "Parzen-Window Based Normalized Mutual Information for Medical Image Registration", Eq. 22.

Args:
    x (torch.Tensor): signal, any shape
    window_radius (float): radius of window for the kernel

Returns:
    torch.Tensor: transformed signal
r   gg?g?g@gffffff?      ?        )devicedtype)absmultorchwheretensorr   r   )xwindow_radiusx_abspoly1poly2s        Z/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/losses/mutual_information.py	xu_kernelr      s     EEGKKm+,ETE\C'(3.ES5[3&'#-E;;UEKKeU\\#VWV^V^fgfmfm=no     c                b    [         R                  " U 5      n [         R                  " X:*  SS5      $ )a  Implementation of a rectangular kernel.

Support: [-window_radius, window_radius]. Returns 1.0 inside this range, 0.0 otherwise.

Args:
    x (torch.Tensor): signal, any shape
    window_radius (float): radius of window for the kernel

Returns:
    torch.Tensor: transformed signal
r   r
   )r   r   r   )r   r   s     r   rectangular_kernelr   0   s'     			!A;;q)344r   c                    Un[         R                  " U 5      U:*  n[         R                  " SX-  S-  -  5      US[         R                  -  S-  -  -  n[         R                  " X4S5      $ )a[  Implementation of a truncated Gaussian kernel.

Support: [-window_radius, window_radius]. Returns Gaussian value inside this range, 0.0 otherwise.
Sigma is set to window_radius.

Args:
    x (torch.Tensor): signal, any shape
    window_radius (float): radius of window for the kernel (used as sigma)

Returns:
    torch.Tensor: transformed signal
g         r	   r
   )r   r   exppir   )r   r   sigmamaskgaussian_vals        r   truncated_gaussian_kernelr#   @   s^     E99Q<=(D99TQY1$445!ehh,SVAV9VWL;;t3//r   c                  D    \ rS rSr\" \5      r\" \5      r\" \	5      r
Srg)MIKernelU    N)__name__
__module____qualname____firstlineno__r   r   xur   rectangularr#   truncated_gaussian__static_attributes__r'   r   r   r%   r%   U   s#    			B+,K 9:r   r%   c                    U R                  SS9u  p4U R                  SS9u  pTXS-
  R                  S5      n[        R                  " Xb:  XR                  S5      -
  U-  U-  S5      $ )Ndimr   )minmax	unsqueezer   r   )datanum_binsepsmin_val_max_valdiffs          r   _normalize_signalr>   [   sg    b!JGb!JG((,D;;tzD+<+<R+@$@D#H8#SUVWWr   c                   U nUR                  U5      nX"R                  SSS9-  nUR                  SS9nUR                  SS9n[        R                  " U* [        R                  " U5      -  SS9n[        R                  " U* [        R                  " U5      -  SS9n[        R                  " U* [        R                  " U5      -  SS9nXgU4$ )N)r1   T)r3   keepdimr@   r2   r1   )clampsumr   log)joint_histogramr9   P_xyP_xP_yH_xyH_xH_ys           r   _joint_histogram_to_entropiesrL   c   s    D::c?DHH4H00D
((r(
C
((r(
C99dUUYYt_,(;D
))SD599S>)r
2C
))SD599S>)r
2CT>r   c                  t   ^  \ rS rSrSr\R                  SS4         S	U 4S jjjrS
S jrSS jr	Sr
U =r$ )EntropyBasedLossBases   ac  A base class for entropy-based loss functions using kernel density estimation.

This class provides the foundation for computing entropy-based losses between signals
by estimating probability distributions using kernel density estimation (KDE). It
computes joint histograms and derives entropy measures that can be used to quantify
the similarity or dissimilarity between signals.

The class pre-processes a reference signal and provides methods to compute joint
histograms with other signals, from which various entropy measures (joint, marginal,
conditional, mutual information) can be derived in subclasses.
@   r   c                  > [         TU ]  5         [        R                  " UR                  5      R
                  U l        U R                  S[        XU R
                  5      5        X0l        U[        ;  a  [        S[        [        5       S35      e[        UR                  US9U l        X@l        [        R                   " U R                  U R"                  R$                  S9U l        g)a,  Initialize the entropy-based loss base module.

Args:
    reference_signal (torch.Tensor): reference signal to which
        other signals will be compared by the forward method
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): number of signal value bins in kernel
        density estimate, by default 64
    window_radius (float): radius of the kernel's support
        interval, by default 1.0

Raises:
    ValueError: If kernel_function is not a valid MIKernel member.
signalzRThe passed_kernel_function is not an accepted MIKernel, the available options are .)r   )r   N)super__init__r   finfor   r9   register_bufferr>   r8   r%   
ValueErrorlistr   valuekernel_functionr   arangerR   r   bin_centersselfreference_signalr[   r8   r   	__class__s        r   rU   EntropyBasedLossBase.__init__   s    , 	;;/556::X'89IUYU]U]'^_ (*deijresdttuv   ''<'<MZ* <<dkk>P>PQr   c                   UR                   U R                  R                   :w  a0  [        SUR                    SU R                  R                    S35      e[        XR                  US9nU R
                  R                  S5      U R                  R                  S5      -
  nU R
                  R                  S5      UR                  S5      -
  nU R                  U5      nU R                  U5      n[        R                  " SXV5      nU$ )a  Compute the joint histogram between the reference signal and another signal.

Uses kernel density estimation to estimate the joint probability distribution
between the reference signal and the provided other signal. The histogram is
computed by evaluating kernel functions at discretized signal values.

Args:
    other_signal (torch.Tensor): Signal to compare with the reference signal.
        Must have the same shape as the reference signal.
    eps (float): Epsilon value for numerical stability in computations.

Returns:
    torch.Tensor: Joint histogram tensor with shape [..., num_bins, num_bins]
        representing the estimated joint probability distribution.

Raises:
    ValueError: If other_signal has incompatible shape with reference signal.
z*The two signals have incompatible shapes: z and rS   )r8   r9   r1   r@   z...in,...jn->...ij)
shaperR   rX   r>   r8   r]   r6   r[   r   einsum)r_   other_signalr9   diff_1diff_2vals_1vals_2rE   s           r   _compute_joint_histogram-EntropyBasedLossBase._compute_joint_histogram   s    & !2!22I,J\J\I]]bcgcncnctctbuuvwxx(SVW!!++B/$++2G2G2KK!!++B/,2H2H2LL%%f-%%f-,,';VLr   c                ^    U R                  XR                  5      n[        X R                  S9$ )a  Compute entropy measures between the reference signal and another signal.

Calculates joint entropy and marginal entropies based on the joint histogram of the two signals.

Args:
    other_signal (torch.Tensor): Signal to compare with the reference signal.
        Must have the same shape as the reference_signal passed at instantiation.

Returns:
    tuple[torch.Tensor, torch.Tensor, torch.Tensor]: A tuple containing:
        - Marginal entropy H(X) of reference signal
        - Marginal entropy H(Y) of other signal
        - Joint entropy H(X,Y)

    All tensors have the same batch dimensions as the input signals.

Note:
    Subclasses should implement specific loss functions based on these entropy
    measures (e.g., mutual information).
)r9   )rk   r9   rL   )r_   rf   rE   s      r   	entropiesEntropyBasedLossBase.entropies   s'    * 77hhO,_((KKr   )r]   r9   r[   r8   r   
r`   torch.Tensorr[   r%   r8   intr   floatreturnNone)rf   rq   r9   rs   rt   rq   )rf   rq   rt   z/tuple[torch.Tensor, torch.Tensor, torch.Tensor])r(   r)   r*   r+   __doc__r%   r,   rU   rk   rn   r/   __classcell__ra   s   @r   rN   rN   s   sk    
 %-KK" R& R " R 	 R
  R 
 R  RDBL Lr   rN   c                      \ rS rSrSS jrSrg)MILossFromRef   c                >    U R                  U5      u  p#nX#-   U-
  nU* $ )a  Compute differentiable mutual information for self.signal and other_signal.

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of flat tensors shape (B,N) where B is
        the tuple of batch dimensions for self.signal, possibly empty.

Returns:
    torch.Tensor: tensor of losses, shape B as above
rn   )r_   rf   rJ   rK   rI   mis         r   forwardMILossFromRef.forward   s)     5$Ys
r   r'   Nrf   rq   rt   rq   r(   r)   r*   r+   r   r/   r'   r   r   rz   rz      s    r   rz   c                      \ rS rSrSS jrSrg)NMILossFromRef   c                >    U R                  U5      u  p#nX#-   U-  nU* $ )a  Compute differentiable normalized mutual information for self.signal and other_signal.

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of flat tensors shape (B,N) where B is
        the tuple of batch dimensions for self.signal, possibly empty.

Returns:
    torch.Tensor: tensor of losses, shape B as above
r}   )r_   rf   rJ   rK   rI   nmis         r   r   NMILossFromRef.forward   s)     5$yD tr   r'   Nr   r   r'   r   r   r   r      s    r   r   c                     ^  \ rS rSrSr\R                  SS4         S	U 4S jjjr\S
S j5       r	SU 4S jjr
SrU =r$ )MILossFromRef2Di  a`  Mutual Information loss module specifically designed for 2D image data.

This class extends MILossFromRef to handle 2D image inputs by automatically
reshaping batched 2D images into the format expected by the base entropy
computation methods. It computes mutual information between reference 2D images
and other images using kernel density estimation.
rP      c                F   > [         TU ]  U R                  U5      X#U5        g)a8  Initialize the 2D Mutual Information loss module.

Args:
    reference_signal (torch.Tensor): reference signal to which
        other signals will be compared by the forward method.
        batch of 2D images, shape (B,H,W) where B are the batch
        dimensions.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): number of signal value bins in kernel
        density estimate, by default 64
    window_radius (float): radius of the kernel's support
        interval, by default 1.0
NrT   rU   arrange_shaper^   s        r   rU   MILossFromRef2D.__init__  #    * 	++,<=Zghr   c                D    U R                  U R                  S S S-   5      $ Nr@   r1   reshaperd   r   s    r   r   MILossFromRef2D.arrange_shape&  !    ~~fll3B/%788r   c                @   > [         TU ]  U R                  U5      5      $ )a  Compute differentiable mutual information for reference_signal and other_signal (both supposed 2D).

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of flat tensors same shape (B,H,W) as
        reference_signal passed for instantiation

Returns:
    torch.Tensor: tensor of losses, shape B as above
rT   r   r   r_   rf   ra   s     r   r   MILossFromRef2D.forward*       wt11,?@@r   r'   rp   r   rq   rt   rq   r   r(   r)   r*   r+   rv   r%   r,   rU   staticmethodr   r   r/   rw   rx   s   @r   r   r     x     %-KK i&i "i 	i
 i 
i i. 9 9A Ar   r   c                     ^  \ rS rSrSr\R                  SS4         S	U 4S jjjr\S
S j5       r	SU 4S jjr
SrU =r$ )MILossFromRef3Di;  ak  Mutual Information loss module specifically designed for 3D image data.

This class extends MILossFromRef to handle 3D image inputs by automatically
reshaping batched 3D images into the format expected by the base entropy
computation methods. It computes normalized mutual information between reference 3D images
and other images using kernel density estimation.
rP   r   c                F   > [         TU ]  U R                  U5      X#U5        g)a:  Initialize the 3D Mutual Information loss module.

Args:
    reference_signal (torch.Tensor): reference signal to which
        other signals will be compared by the forward method.
        batch of 3D images, shape (B,D,H,W) where B are the
        batch dimensions.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): number of signal value bins in kernel
        density estimate, by default 64
    window_radius (float): radius of the kernel's support
        interval, by default 1.0
Nr   r^   s        r   rU   MILossFromRef3D.__init__D  r   r   c                D    U R                  U R                  S S S-   5      $ Nr   r   r   s    r   r   MILossFromRef3D.arrange_shape[  r   r   c                @   > [         TU ]  U R                  U5      5      $ )a  Compute differentiable mutual information for reference_signal and other_signal (both supposed 3D).

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of flat tensors same shape (B,D,H,W) as
        reference_signal passed for instantiation

Returns:
    torch.Tensor: tensor of losses, shape B as above
r   r   s     r   r   MILossFromRef3D.forward_  r   r   r'   rp   r   r   r   rx   s   @r   r   r   ;  r   r   r   c                     ^  \ rS rSrSr\R                  SS4         S	U 4S jjjr\S
S j5       r	SU 4S jjr
SrU =r$ )NMILossFromRef2Dip  aw  Normalized Mutual Information loss module specifically designed for 2D image data.

This class extends NMILossFromRef to handle 2D image inputs by automatically
reshaping batched 2D images into the format expected by the base entropy
computation methods. It computes normalized mutual information between reference 2D images
and other images using kernel density estimation.
rP   r   c                F   > [         TU ]  U R                  U5      X#U5        g)aC  Initialize the 2D Normalized Mutual Information loss module.

Args:
    reference_signal (torch.Tensor): reference signal to which
        other signals will be compared by the forward method.
        batch of 2D images, shape (B,H,W) where B are the batch
        dimensions.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): number of signal value bins in kernel
        density estimate, by default 64
    window_radius (float): radius of the kernel's support
        interval, by default 1.0
Nr   r^   s        r   rU   NMILossFromRef2D.__init__y  r   r   c                D    U R                  U R                  S S S-   5      $ r   r   r   s    r   r   NMILossFromRef2D.arrange_shape  r   r   c                @   > [         TU ]  U R                  U5      5      $ )a  Compute differentiable mutual information for reference_signal and other_signal (both supposed 2D).

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of tensors same shape (B,H,W) as
        reference_signal passed for instantiation

Returns:
    torch.Tensor: tensor of losses, shape B as above
r   r   s     r   r   NMILossFromRef2D.forward  r   r   r'   rp   r   r   r   rx   s   @r   r   r   p  r   r   r   c                     ^  \ rS rSrSr\R                  SS4         S	U 4S jjjr\S
S j5       r	SU 4S jjr
SrU =r$ )NMILossFromRef3Di  al  Normalized Mutual Information loss module specifically designed for 3D image data.

This class extends NMILossFromRef to handle 3D image inputs by automatically
reshaping batched 3D images into the format expected by the base entropy
computation methods. It computes mutual information between reference 3D images
and other images using kernel density estimation.
rP   r   c                F   > [         TU ]  U R                  U5      X#U5        g)aE  Initialize the 3D Normalized Mutual Information loss module.

Args:
    reference_signal (torch.Tensor): reference signal to which
        other signals will be compared by the forward method.
        batch of 3D images, shape (B,D,H,W) where B are the
        batch dimensions.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): number of signal value bins in kernel
        density estimate, by default 64
    window_radius (float): radius of the kernel's support
        interval, by default 1.0
Nr   r^   s        r   rU   NMILossFromRef3D.__init__  r   r   c                D    U R                  U R                  S S S-   5      $ r   r   r   s    r   r   NMILossFromRef3D.arrange_shape  r   r   c                @   > [         TU ]  U R                  U5      5      $ )a  Compute differentiable mutual information for reference_signal and other_signal (both supposed 3D).

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    other_signal: Batch of tensors, same shape (B,D,H,W) as
        reference_signal passed for instantiation

Returns:
    torch.Tensor: tensor of losses, shape B as above
r   r   s     r   r   NMILossFromRef3D.forward  r   r   r'   rp   r   r   r   rx   s   @r   r   r     r   r   r   rP   c                8    [        XX4S9nUR                  U 5      $ )aD  Compute differentiable mutual information for flat tensors.

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of flat tensors shape (B,N) where B
        is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of flat tensors, same shape as
        input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r`   r[   r8   r   )rz   r   inputtargetr[   r8   r   modules         r   mutual_information_lossr     s$    8 8F >>%  r   c                8    [        XX4S9nUR                  U 5      $ )a7  Compute differentiable mutual information for 2d tensors.

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of 2d tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of 2d tensors shape (B,H,W) where B
        is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of 2d tensors, same shape as input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r   )r   r   r   s         r   mutual_information_loss_2dr     $    6 8F >>%  r   c                8    [        XX4S9nUR                  U 5      $ )a9  Compute differentiable mutual information for 3d tensors.

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of 3d tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of 3d tensors shape (B,D,H,W) where
        B is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of 3d tensors, same shape as input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r   )r   r   r   s         r   mutual_information_loss_3dr     r   r   c                <    [        UUUUS9nUR                  U 5      $ )aP  Compute differentiable normalized mutual information for flat tensors.

nmi = (H(X) + H(Y)) / H(X,Y)
To have a loss function, the opposite is returned.
Can also handle two batches of flat tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of flat tensors shape (B,N) where B
        is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of flat tensors, same shape as
        input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r   )r   r   r   s         r   "normalized_mutual_information_lossr   >  s+    8 '#	F >>%  r   c                8    [        XX4S9nUR                  U 5      $ )aA  Compute differentiable normalized mutual information for 2d tensors.

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of 2d tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of 2d tensors shape (B,H,W) where B
        is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of 2d tensors, same shape as input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r   )r   r   r   s         r   %normalized_mutual_information_loss_2dr   c  $    6 8F >>%  r   c                8    [        XX4S9nUR                  U 5      $ )aC  Compute differentiable normalized mutual information for 3d tensors.

mi = (H(X) + H(Y) - H(X,Y))
To have a loss function, the opposite is returned.
Can also handle two batches of 3d tensors, then a batch of loss values is returned.

Args:
    input (torch.Tensor): Batch of 3d tensors shape (B,D,H,W) where
        B is any batch dimensions tuple, possibly empty.
    target (torch.Tensor): Batch of 3d tensors, same shape as input.
    kernel_function (MIKernel): Used kernel function for kernel
        density estimate, by default MIKernel.xu
    num_bins (int): The number of bins used for KDE, defaults to 64.
    window_radius (float): The smoothing window radius in KDE, in
        terms of bin width units, defaults to 1.

Returns:
    torch.Tensor: tensor of losses, shape B (common batch dims tuple
    of input and target)
r   )r   r   r   s         r   %normalized_mutual_information_loss_3dr     r   r   )r   )r   rq   r   rs   rt   rq   )g:0yE>)r7   rq   r8   rr   r9   rs   rt   rq   )rE   rq   r9   rs   rt   rq   )r   rq   r   rq   r[   r%   r8   rr   r   rs   rt   rq   )
__future__r   enumr   r   	functoolsr   r   r   r   r#   r%   r>   rL   nnModulerN   rz   r   r   r   r   r   r,   r   r   r   r   r   r   r'   r   r   <module>r      su  " #   .5 0*;t ;X fL588?? fLR( *) *2Am 2Aj2Am 2Aj2A~ 2Aj2A~ 2Ap !)!!! ! 	!
 ! !J !)!!! ! 	!
 ! !H !)!!! ! 	!
 ! !H !)"!"!"! "! 	"!
 "! "!P !)!!! ! 	!
 ! !H !)!!! ! 	!
 ! !r   