o
    oiG5                     @  s   d dl mZ d dlmZmZ d dlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ d dlmZmZmZ d dlmZmZmZ d dlmZ d dlmZ dddZG dd deZdS )    )annotations)Optionaloverload)DeviceDtypeModule	ParameterTensorconcatenatepadrandstacktensorwhere
zeros_like)KORNIA_CHECKKORNIA_CHECK_SAME_DEVICESKORNIA_CHECK_TYPE)check_se2_omega_shapecheck_se2_t_shapecheck_v_shape)So2)Vector2rr   tr	   returnNonec                 C  sb   | j j}t|dkrt|jdkst|dkr$t|jdkr$t| d S td| j j d|j )N      r   zKInvalid input, both the inputs should be either batched or unbatched. Got: z and )zshapelenr   
ValueError)r   r   z_shape r$   P/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/liegroup/se2.py_check_se2_r_t_shape,   s   4r&   c                      sV  e Zd ZdZdK fdd	ZdLddZdMddZdNddZedNddZ	edOddZ	dPddZ	e
dQddZe
dQddZe
dRdd Ze
dQd!d"Ze
dRd#d$ZedSd&d'ZdTd(d)ZedUd*d+ZedVd-d.ZedWdXd6d7ZdTd8d9ZedYd;d<ZdZd=d>ZedWdXd?d@Zed[dCdDZed\dEdFZed]dGdHZdTdIdJZ  ZS )^Se2a  Base class to represent the Se2 group.

    The SE(2) is the group of rigid body transformations about the origin of two-dimensional Euclidean
    space :math:`R^2` under the operation of composition.
    See more:

    Example:
        >>> so2 = So2.identity(1)
        >>> t = torch.ones((1, 2))
        >>> se2 = Se2(so2, t)
        >>> se2
        rotation: Parameter containing:
        tensor([1.+0.j], requires_grad=True)
        translation: Parameter containing:
        tensor([[1., 1.]], requires_grad=True)

    rotationr   translationVector2 | Tensorr   r   c                   sj   t    t|t t|ttfstdt| |  || _	t|tr0t
|| t|| _dS || _dS )aa  Construct the base class.

        Internally represented by a complex number `z` and a translation 2-vector.

        Args:
            rotation: So2 group encompassing a rotation.
            translation: translation vector with the shape of :math:`(B, 2)`.

        Example:
            >>> so2 = So2.identity(1)
            >>> t = torch.ones((1, 2))
            >>> se2 = Se2(so2, t)
            >>> se2
            rotation: Parameter containing:
            tensor([1.+0.j], requires_grad=True)
            translation: Parameter containing:
            tensor([[1., 1.]], requires_grad=True)

        ztranslation type is N)super__init__r   r   
isinstancer   r	   	TypeErrortype	_rotationr&   r   _translation)selfr(   r)   	__class__r$   r%   r,   I   s   




zSe2.__init__strc                 C  s   d| j  d| j S )Nz
rotation: z
translation: )r   r   r2   r$   r$   r%   __repr__k   s   zSe2.__repr__idxint | slicec                 C  s   t | j| | j| S N)r'   r0   r1   )r2   r8   r$   r$   r%   __getitem__n   s   zSe2.__getitem__rightc                 C  s.   | j }| j}||j  }|||j  }t||S r:   )so2r   r'   )r2   r<   r=   r   _r_tr$   r$   r%   _mul_se2q   s
   

zSe2._mul_se2c                 C     d S r:   r$   r2   r<   r$   r$   r%   __mul__x      zSe2.__mul__r	   c                 C  rA   r:   r$   rB   r$   r$   r%   rC   {   rD   Se2 | Tensorc                 C  sV   | j }| j}t|trt|t | |S t|ttfr"|| | S tdt	| )zCompose two Se2 transformations.

        Args:
            right: the other Se2 transformation.

        Return:
            The resulting Se2 transformation.

        zUnsupported type: )
r=   r   r-   r'   r   r@   r   r	   r.   r/   )r2   r<   r=   r   r$   r$   r%   rC   ~   s   



c                 C     | j S z&Return the underlying `rotation(So2)`.r0   r6   r$   r$   r%   r=         zSe2.so2c                 C  rF   rG   rH   r6   r$   r$   r%   r      rI   zSe2.rVector2 | Parameterc                 C  rF   z@Return the underlying translation vector of shape :math:`(B,2)`.r1   r6   r$   r$   r%   r      rI   zSe2.tc                 C  rF   rG   rH   r6   r$   r$   r%   r(      rI   zSe2.rotationc                 C  rF   rK   rL   r6   r$   r$   r%   r)      rI   zSe2.translationvc           
      C  s   t |  | d }t|}td| j| jd}|dk}t||jj| |}t|d|jj	 | |}| d }| d }t
|| ||  || ||  fd}	t||	S )a  Convert elements of lie algebra to elements of lie group.

        Args:
            v: vector of shape :math:`(B, 3)`.

        Example:
            >>> v = torch.ones((1, 3))
            >>> s = Se2.exp(v)
            >>> s.r
            Parameter containing:
            tensor([0.5403+0.8415j], requires_grad=True)
            >>> s.t
            Parameter containing:
            tensor([[0.3818, 1.3012]], requires_grad=True)

        .r           devicedtype      ?.r   .r   )r   r   expr   rQ   rR   r   r   imagrealr   r'   )
rM   thetar=   r   theta_nonzerosabxyr   r$   r$   r%   rW      s   
&
zSe2.expc           	      C  s   | j  }d| }| j jjd }t|dk|| j jj  | td|j|jd}t	||fd}t	| |fd}t	||fd}|| j
jd  }t	|d	 |d
 |fdS )zConvert elements of lie group  to elements of lie algebra.

        Example:
            >>> v = torch.ones((1, 3))
            >>> s = Se2.exp(v).log()
            >>> s
            tensor([[1.0000, 1.0000, 1.0000]], grad_fn=<StackBackward0>)

        g      ?r   r   rO   rP   rV   .N).r   r   ).r   r   )r=   logr   rY   r   rX   r   rQ   rR   r   r   data)	r2   rZ   
half_thetadenomr\   row0row1V_invupsilonr$   r$   r%   rb      s   

(zSe2.logc                 C  sJ   t |  t| d | d fd}| d }tt||dfd}t|dS )aQ  Convert elements from vector space to lie algebra. Returns matrix of shape :math:`(B, 3, 3)`.

        Args:
            v: vector of shape:math:`(B, 3)`.

        Example:
            >>> theta = torch.tensor(3.1415/2)
            >>> So2.hat(theta)
            tensor([[0.0000, 1.5707],
                    [1.5707, 0.0000]])

        rT   rU   rV   rN   r`   )r   r   )r   r   r
   r   hat	unsqueezer   )rM   ri   rZ   col0r$   r$   r%   rj      s
   
zSe2.hatomegac                 C  sH   t |  | ddddf }t| dddddf }t||d fdS )a{  Convert elements from lie algebra to vector space.

        Args:
            omega: 3x3-matrix representing lie algebra of shape :math:`(B, 3, 3)`.

        Returns:
            vector of shape :math:`(B, 3)`.

        Example:
            >>> v = torch.ones(3)
            >>> omega_hat = Se2.hat(v)
            >>> Se2.vee(omega_hat)
            tensor([1., 1., 1.])

        .r   Nra   rV   )r   r   veer
   )rm   ri   rZ   r$   r$   r%   rn      s   zSe2.veeN
batch_sizeOptional[int]rQ   Optional[Device]rR   r   c                 C  sN   t ddg||d}|durt|dkdd ||d}| t|||t|S )a  Create a Se2 group representing an identity rotation and zero translation.

        Args:
            batch_size: the batch size of the underlying data.
            device: device to place the result on.
            dtype: dtype of the result.

        Example:
            >>> s = Se2.identity(1)
            >>> s.r
            Parameter containing:
            tensor([1.+0.j], requires_grad=True)
            >>> s.t
            x: tensor([0.])
            y: tensor([0.])

        rO   rP   Nr   batch_size must be positivemsg)r   r   repeatr   identityr   )clsro   rQ   rR   r   r$   r$   r%   rv     s
   zSe2.identityc                 C  s2   t | j | jjd fd}t|d}d|d< |S )a0  Return the matrix representation of shape :math:`(B, 3, 3)`.

        Example:
            >>> s = Se2(So2.identity(1), torch.ones(1, 2))
            >>> s.matrix()
            tensor([[[1., -0., 1.],
                     [0., 1., 1.],
                     [0., 0., 1.]]], grad_fn=<CopySlices>)

        ra   rV   )r   r   r   r   rS   ).rV   rV   )r
   r   matrixr   rc   r   )r2   rtrt_3x3r$   r$   r%   rx   &  s   
z
Se2.matrixrx   c                 C  s8   t |dddddf }|ddddf }| ||S )a  Create an Se2 group from a matrix.

        Args:
            matrix: tensor of shape :math:`(B, 3, 3)`.

        Example:
            >>> s = Se2.from_matrix(torch.eye(3).repeat(2, 1, 1))
            >>> s.r
            Parameter containing:
            tensor([1.+0.j, 1.+0.j], requires_grad=True)
            >>> s.t
            Parameter containing:
            tensor([[0., 0.],
                    [0., 0.]], requires_grad=True)

        .Nr   rV   )r   from_matrix)rw   rx   r   r   r$   r$   r%   r{   6  s   
zSe2.from_matrixc                 C  s4   | j  }d| j }t|trtdt||| S )av  Return the inverse transformation.

        Example:
            >>> s = Se2(So2.identity(1), torch.ones(1,2))
            >>> s_inv = s.inverse()
            >>> s_inv.r
            Parameter containing:
            tensor([1.+0.j], requires_grad=True)
            >>> s_inv.t
            Parameter containing:
            tensor([[-1., -1.]], requires_grad=True)

        rV   z*Unexpected integer from `-1 * translation`)r   inverser   r-   intr.   r'   )r2   r_invr?   r$   r$   r%   r|   M  s
   


zSe2.inversec                 C  sL   t |||}|du rd}nt|dkdd |df}| |tt|||dS )aK  Create a Se2 group representing a random transformation.

        Args:
            batch_size: the batch size of the underlying data.
            device: device to place the result on.
            dtype: dtype of the result.

        Example:
            >>> s = Se2.random()
            >>> s = Se2.random(batch_size=3)

        N)r   r   rr   rs   r   rP   )r   randomr   r   r   )rw   ro   rQ   rR   r   r    r$   r$   r%   r   b  s   z
Se2.randomr^   r_   c                 C  s^   t |j|jk t||g t|jdkr|jd nd}t||j|j}| |t||fdS )zConstruct a translation only Se2 instance.

        Args:
            x: the x-axis translation.
            y: the y-axis translation.

        r   NrV   )	r   r    r   r!   r   rv   rQ   rR   r   )rw   r^   r_   ro   r(   r$   r$   r%   transy  s
   	z	Se2.transc                 C  s   t |}| ||S )z_Construct a x-axis translation.

        Args:
            x: the x-axis translation.

        r   r   )rw   r^   zsr$   r$   r%   trans_x     zSe2.trans_xc                 C  s   t |}| ||S )z_Construct a y-axis translation.

        Args:
            y: the y-axis translation.

        r   )rw   r_   r   r$   r$   r%   trans_y  r   zSe2.trans_yc                 C  s:   |   }t| jjd | jjd  fd|ddddf< |S )a  Return the adjoint matrix of shape :math:`(B, 3, 3)`.

        Example:
            >>> s = Se2.identity()
            >>> s.adjoint()
            tensor([[1., -0., 0.],
                    [0., 1., -0.],
                    [0., 0., 1.]], grad_fn=<CopySlices>)

        rU   rT   rV   .r   r   )rx   r   r   rc   )r2   ry   r$   r$   r%   adjoint  s   .zSe2.adjoint)r(   r   r)   r*   r   r   )r   r5   )r8   r9   r   r'   )r<   r'   r   r'   )r<   r	   r   r	   )r<   rE   r   rE   )r   r   )r   rJ   )rM   r	   r   r'   )r   r	   )rM   r	   r   r	   )rm   r	   r   r	   )NNN)ro   rp   rQ   rq   rR   r   r   r'   )rx   r	   r   r'   )r   r'   )r^   r	   r_   r	   r   r'   )r^   r	   r   r'   )r_   r	   r   r'   ) __name__
__module____qualname____doc__r,   r7   r;   r@   r   rC   propertyr=   r   r   r(   r)   staticmethodrW   rb   rj   rn   classmethodrv   rx   r{   r|   r   r   r   r   r   __classcell__r$   r$   r3   r%   r'   6   sV    
"







r'   N)r   r   r   r	   r   r   ) 
__future__r   typingr   r   kornia.corer   r   r   r   r	   r
   r   r   r   r   r   r   kornia.core.checkr   r   r   kornia.geometry.liegroup._utilsr   r   r   kornia.geometry.liegroup.so2r   kornia.geometry.vectorr   r&   r'   r$   r$   r$   r%   <module>   s   8

