�
�F�V�+ � @ s� d Z d d l Z d d l j Z d d l j Z d d l Z d d l
Z
d d � Z d d � Z d d d d
� Z
d d d d d � Z d d
d d � Z d d d � Z d d d � Z d d d � Z d S)z!A package for computing Pfaffians� Nc C s� | j d d k s t � t j | d d � | d d � � } | d k rl t j | j d � d | d f St j | d d | � } | j � } | d d k r� | d | 8<|
} n | d | 7<| } | t j j | � } | d | f Sd S)z�(v, tau, alpha) = householder_real(x)
Compute a Householder transformation such that
(1-tau v v^T) x = alpha e_1
where x and v a real vectors, tau is 0 or 2, and
alpha a real number (e_1 is the first unit vector)
r � N� )
�shape�AssertionError�np�dot�zeros�math�sqrt�copy�linalg�norm)�x�sigma�norm_x�v�alpha� r �../code/pfaffian.py�householder_real s &!
r c C s
| j d d k s t � t j t j | d d � � | d d � � } | d k ru t j | j d � d | d f St j | d j � | d | � } | j � } t j
d t j | d j
| d j � � } | d | | 7<| t j j | � } | d | | f S)z�(v, tau, alpha) = householder_real(x)
Compute a Householder transformation such that
(1-tau v v^T) x = alpha e_1
where x and v a complex vectors, tau is 0 or 2, and
alpha a complex number (e_1 is the first unit vector)
r r Ny �?r )r r r r �conjr �cmathr
� conjugater �expr �atan2�imag�realr r
)r r r r �phaser r r �householder_complex* s /!%-r FTc C s� | j d | j d k o% d k n s0 t � t | | j j � � d k sU t � | j d } t j | � } t j | j t j � r� t
} n- t j | j t j � s� t d � � n t
} | s� | j � } n | r� t j | j d d | j �} n x�t | j d d � D]y} | | | d d � | f � \ } } } | | | d | f <| | | | d f <d | | d d � | f <d | | | d d � f <| t j | | d d � | d d � f | j � � }
| | d d � | d d � f t j | |
� t j |
| � 7<| r| t j | d d � | d d � f | � } | d d � | d d � f t j | | j � � 8<qqW| r�t j | � t j | � f St j | � Sd S)a T, Q = skew_tridiagonalize(A, overwrite_a, calc_q=True)
or
T = skew_tridiagonalize(A, overwrite_a, calc_q=False)
Bring a real or complex skew-symmetric matrix (A=-A^T) into
tridiagonal form T (with zero diagonal) with a orthogonal
(real case) or unitary (complex case) matrix U such that
A = Q T Q^T
(Note that Q^T and *not* Q^dagger also in the complex case)
A is overwritten if overwrite_a=True (default: False), and
Q only calculated if calc_q=True (default: True)
r r g�+����=z)pfaffian() can only work on numeric input�dtyper N)r r �abs�T�maxr �asarray�
issubdtyper �complexfloatingr �number� TypeErrorr r �eye�ranger r �outer�asmatrix)�A�overwrite_a�calc_q�n�householder�Q�ir �taur �w�yr r r �skew_tridiagonalizeE s6 0%
"):D0=r6 c
C s| | j d | j d k o% d k n s0 t � t | | j j � � d k sU t � | j d } t j | � } | s� | j � } n | r� t j | d | j �} n | r� t j
| � } n xt | d � D]�} | d t j | | d d � | f � j � } | | d k r�| | d | d � f j � } | | | d � f | | d | d � f <| | | | d � f <| | d � | d f j � } | | d � | f | | d � | d f <| | | d � | f <| rP| | d d | d � f j � } | | d | d � f | | d d | d � f <| | | d | d � f <n | r�| | d } | | | | d <| | | <q�n | | d | f d k r� | | d d � | f j � }
|
| | d | f }
d | | d d � | f <d | | | d d � f <| | d d � | d d � f t j
|
| | d d � | d f � 7<| | d d � | d d � f t j
| | d d � | d f |
� 8<| r�|
| | d d � | d f <q�q� q� W| rt j t j | � t j
| � | f f � } n | rR| r3t j | � t j | � | f St j | � t j | � f Sn&