o
    €o™iâ  ã                   @   sL   d dl Z d dlmZ d dlZd dlmZmZmZmZm	Z	 G dd„ deƒZ
dS )é    N)ÚTuple)ÚModuleÚTensorÚcosÚsinÚzerosc                	       sŒ   e Zd ZU dZeed< ddedeeef dedd	f‡ fd
d„Z	deeef defdd„Z
deeef dd	fdd„Zdedefdd„Z‡  ZS )ÚPositionEncodingSinezHA sinusoidal position encoding that generalized to 2-dimensional images.Úpe©é   r   TÚd_modelÚ	max_shapeÚtemp_bug_fixÚreturnNc                    s4   t ƒ  ¡  || _|| _|  |¡}| jd|dd dS )aY  Construct sinusoidal positional encoding.

        Args:
        d_model: Dimensions of model input.
        max_shape (tuple): for 1/8 featmap, the max length of 256 corresponds to 2048 pixels
        temp_bug_fix (bool): As noted in this [issue](https://github.com/zju3dv/LoFTR/issues/41),
            the original implementation of LoFTR includes a bug in the pos-enc impl, which has little impact
            on the final performance. For now, we keep both impls for backward compatibility.
            We will remove the buggy impl after re-training all variants of our released models.

        r	   F)Ú
persistentN)ÚsuperÚ__init__r   r   Ú_create_position_encodingÚregister_buffer)Úselfr   r   r   r	   ©Ú	__class__© ú`/home/ubuntu/.local/lib/python3.10/site-packages/kornia/feature/loftr/utils/position_encoding.pyr      s
   

zPositionEncodingSine.__init__c                 C   sb  t | jg|¢R ƒ}t |¡ d¡ ¡  d¡}t |¡ d¡ ¡  d¡}| jrAt t 	d| jd d¡ ¡ t
 d¡ | jd   ¡}nt t 	d| jd d¡ ¡ t
 d¡ | j d  ¡}|dd…ddf }t|| ƒ|ddd…dd…dd…f< t|| ƒ|ddd…dd…dd…f< t|| ƒ|ddd…dd…dd…f< t|| ƒ|ddd…dd…dd…f< | d¡S )zÈCreate a position encoding from scratch.

        For 1/8 feature map (which is standard): If the input image size is H, W (both divisible by 8), the max_shape
        should be (H//8, W//8).
        r   é   é   g     ˆÃ@Né   é   )r   r   ÚtorchÚonesÚcumsumÚfloatÚ	unsqueezer   ÚexpÚarangeÚmathÚlogr   r   )r   r   r	   Ú
y_positionÚ
x_positionÚdiv_termr   r   r   r   2   s    ,ÿ,ÿ$$$$
z.PositionEncodingSine._create_position_encodingc                 C   s   |   |¡ | jj¡| _dS )zÊUpdate position encoding to new max_shape.

        For 1/8 feature map (which is standard): If the input image size is H, W (both divisible by 8), the max_shape
        should be (H//8, W//8).
        N)r   Útor	   Údevice)r   r   r   r   r   Úupdate_position_encoding_sizeJ   s   z2PositionEncodingSine.update_position_encoding_sizeÚxc              	   C   s˜   |  d¡| j  d¡ks|  d¡| j  d¡kr3t|  d¡| j  d¡ƒt|  d¡| j  d¡ƒf}|  |¡ || jdd…dd…d|  d¡…d|  d¡…f  S )z=Run forward.

        Args:
        x: [N, C, H, W]

        r   r   N)Úsizer	   Úmaxr,   )r   r-   r   r   r   r   ÚforwardR   s   ,0
2zPositionEncodingSine.forward)r
   T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__Úintr   Úboolr   r   r,   r0   Ú__classcell__r   r   r   r   r      s   
 (r   )r%   Útypingr   r   Úkornia.corer   r   r   r   r   r   r   r   r   r   Ú<module>   s
   