ó
àÆ÷Xc           @` sÏ  d  d l  m Z m Z m Z d  d l Z d  d l Z d  d l m Z d  d l Z y d  d l	 Z
 e Z Wn e k
 r e Z n Xd  d l m Z d  d l Z d  d l m Z d  d l m Z m Z e j e ƒ Z d! Z d e f d „  ƒ  YZ e ƒ  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ e ƒ  Z e d d	 d e ƒ Z e d d
 d e ƒ Z  d e f d „  ƒ  YZ! d e f d „  ƒ  YZ" e d „ Z# d „  Z$ d e f d „  ƒ  YZ% d e f d  „  ƒ  YZ& e% ƒ  Z' d S("   i    (   t   absolute_importt   print_functiont   divisionN(   t   xrange(   t   tensor(   t   as_tensor_variable(   t   Opt   Applyt   generalt	   symmetrict   lower_triangulart   upper_triangulart	   hermitiant   bandedt   diagonalt   toeplitzt   Choleskyc           B` sD   e  Z d  Z d Z e d „ Z d „  Z d „  Z d „  Z d „  Z	 RS(	   s‹   
    Return a triangular matrix square root of positive semi-definite `x`.

    L = cholesky(X, lower=True) implies dot(L, L.T) == X.

    t   lowert   destructivec         C` s   | |  _  t |  _ d  S(   N(   R   t   FalseR   (   t   selfR   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   __init__.   s    	c         C` s   | d g S(   Ni    (    (   R   t   nodet   shapes(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   infer_shape2   s    c         C` sO   t  s t d ƒ ‚ t | ƒ } | j d k s3 t ‚ t |  | g | j ƒ  g ƒ S(   Ns8   Scipy not available. Scipy is needed for the Cholesky opi   (   t   imported_scipyt   AssertionErrorR   t   ndimR   t   type(   R   t   x(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt	   make_node5   s
    		c         C` sC   | d } | d } t  j j | d |  j ƒj | j ƒ | d <d  S(   Ni    R   (   t   scipyt   linalgt   choleskyR   t   astypet   dtype(   R   R   t   inputst   outputsR   t   z(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   perform<   s    

c   	      C` sØ   | d } | d } |  | ƒ } |  j  s> | j } | j } n  d „  } d „  } | | | | j j | ƒ ƒ ƒ } |  j  r§ t j | | j ƒ t j t j | ƒ ƒ g St j | | j ƒ t j t j | ƒ ƒ g Sd S(   s4  
        Cholesky decomposition reverse-mode gradient update.

        Symbolic expression for reverse-mode Cholesky gradient taken from [0]_

        References
        ----------
        .. [0] I. Murray, "Differentiation of the Cholesky decomposition",
           http://arxiv.org/abs/1602.07527

        i    c         S` s'   t  j |  ƒ t  j t  j |  ƒ d ƒ S(   s=   Extracts lower triangle of square matrix and halves diagonal.g       @(   R   t   trilt   diagR   (   t   mtx(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   tril_and_halve_diagonalW   s    c         S` s"   t  |  j t  |  j | j ƒ j ƒ S(   s0   Computes L^{-T} P L^{-1} for lower-triangular L.(   t   solve_upper_triangulart   T(   t   outert   inner(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   conjugate_solve_triangular[   s    N(   R   R-   t   dotR   R(   R)   R   t   triu(	   R   R$   t	   gradientsR   t   dzt   chol_xR+   R0   t   s(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   gradA   s    

					-(   s   lowers   destructive(
   t   __name__t
   __module__t   __doc__t	   __props__t   TrueR   R   R   R'   R7   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   !   s   			t   CholeskyGradc           B` s;   e  Z d  Z d Z e d „ Z d „  Z d „  Z d „  Z RS(   s   
    R   R   c         C` s   | |  _  t |  _ d  S(   N(   R   R   R   (   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   q   s    	c         C` s©   t  | ƒ } t  | ƒ } t  | ƒ } | j d k s9 t ‚ | j d k sN t ‚ | j d k sc t ‚ | j j j |  j k s‡ t d ƒ ‚ t |  | | | g | j ƒ  g ƒ S(   Ni   s<   lower/upper mismatch between Cholesky op and CholeskyGrad op(   R   R   R   t   ownert   opR   R   R   (   R   R   t   lR4   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   u   s    	c      
   C` s÷  | d } | d } | d } | d } | j  d } |  j r•t j | ƒ }	 x™t | d d d ƒ D]*}
 x‘ t |
 d | ƒ D]| } xs t | | ƒ D]b } |	 | |
 f c |	 | | f | | |
 f 8<|	 | |
 f c |	 | | f | | |
 f 8<q” Wq~ Wxi t |
 d | ƒ D]T } |	 | |
 f c | |
 |
 f <|	 |
 |
 f c | | |
 f |	 | |
 f 8<qW|	 |
 |
 f c d | |
 |
 f <qd WnTt j | ƒ }	 xBt | d d d ƒ D]*}
 x‘ t |
 d | ƒ D]| } xs t | | ƒ D]b } |	 |
 | f c |	 | | f | |
 | f 8<|	 |
 | f c |	 | | f | |
 | f 8<qëWqÕWxi t |
 d | ƒ D]T } |	 |
 | f c | |
 |
 f <|	 |
 |
 f c | |
 | f |	 |
 | f 8<qiW|	 |
 |
 f c d | |
 |
 f <q»W|	 | d <d S(   s“  
        Implements the "reverse-mode" gradient [1]_ for the
        Cholesky factorization of a positive-definite matrix.

        References
        ----------
        .. [1] S. P. Smith. "Differentiation of the Cholesky Algorithm".
           Journal of Computational and Graphical Statistics,
           Vol. 4, No. 2 (Jun.,1995), pp. 134-147
           http://www.jstor.org/stable/1390762

        i    i   i   iÿÿÿÿN(   t   shapeR   t   numpyR(   R   R2   (   R   R   R$   R%   R   t   LR4   t   dxt   Nt   Ft   kt   jt   i(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'      s6    



	.6 2+.6 2(c         C` s   | d g S(   Ni    (    (   R   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   «   s    (   s   lowers   destructive(	   R8   R9   R:   R;   R<   R   R   R'   R   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR=   k   s   		*t   Solvec           B` sV   e  Z d  Z d Z d e e e d „ Z d „  Z d „  Z d	 „  Z d
 „  Z	 d „  Z
 RS(   s.   
    Solve a system of linear equations.

    t   A_structureR   t   overwrite_At   overwrite_bR   c         C` sF   | t  k r t d | ƒ ‚ n  | |  _ | |  _ | |  _ | |  _ d  S(   Ns!   Invalid matrix structure argument(   t   MATRIX_STRUCTURESt
   ValueErrorRK   R   RL   RM   (   R   RK   R   RL   RM   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   ·   s    			c         C` s   d t  |  j ƒ  ƒ S(   Ns	   Solve{%s}(   t   strt   _props(   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   __repr__Ã   s    c         C` sÊ   t  s t d ƒ ‚ t | ƒ } t | ƒ } | j d k s? t ‚ | j d k sT t ‚ t j j t j d ƒ j	 | j
 ƒ t j d ƒ j	 | j
 ƒ ƒ j
 } t j d | j d | ƒ } t |  | | g | g ƒ S(   Ns5   Scipy not available. Scipy is needed for the Solve opi   i   t   broadcastableR#   (   i   i   (   R   R   R   R   R   R    t   solveRB   t   eyeR"   R#   R   RS   R   (   R   t   At   bt   o_dtypeR   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   Æ   s    			!			c         C` s   | \ } } |  j  d k r9 t j j | | d t ƒ} nB |  j  d k rf t j j | | d t ƒ} n t j j | | ƒ } | | d d <d  S(   NR
   R   R   i    (   RK   R   R    t   solve_triangularR<   R   RT   (   R   R   R$   t   output_storageRV   RW   t   rval(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'   Ø   s    		c         C` sM   | \ } } | d } t  | ƒ d k r2 | f g S| d } | | f g Sd  S(   Ni   (   t   len(   R   R   R   t   Ashapet   Bshapet   rowst   cols(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   å   s    


c         C` s÷   | \ } } |  | | ƒ } | d } i d d 6d d 6} t  d | j |  j |  j ƒ d |  j ƒ } | | j | ƒ }	 | j d k r˜ t j |	 | ƒ n |	 j | j ƒ }
 |  j d k rÌ t j	 |
 ƒ }
 n! |  j d k rí t j
 |
 ƒ }
 n  |
 |	 g S(   sx  
        Reverse-mode gradient updates for matrix solve operation c = A \ b.

        Symbolic expression for updates taken from [1]_.

        References
        ----------
        ..[1] M. B. Giles, "An extended collection of matrix derivative results
          for forward and reverse mode automatic differentiation",
          http://eprints.maths.ox.ac.uk/1079/

        i    R   R
   RK   R   i   (   RJ   t   getRK   R   R-   R   R   R.   R1   R(   R2   (   R   R$   t   output_gradientsRV   RW   t   ct   c_bart	   trans_mapt   trans_solve_opt   b_bart   A_bar(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR7   î   s     

5(   s   A_structures   lowers   overwrite_As   overwrite_b(   R8   R9   R:   R;   R   R   RR   R   R'   R   R7   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyRJ   ¯   s   					RK   R   t   Eigvalshc           B` sD   e  Z d  Z d Z e d „ Z d „  Z d „  Z d „  Z d „  Z	 RS(   sP   
    Generalized eigenvalues of a Hermitian positive definite eigensystem.

    R   c         C` s%   | t  t g k s t ‚ | |  _ d  S(   N(   R<   R   R   R   (   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   6  s    c         C` s  t  s t d ƒ ‚ | t j j k r… t | ƒ } | j d k sE t ‚ t j j | j	 ƒ } t j j
 d | ƒ } t |  | g | g ƒ St | ƒ } t | ƒ } | j d k s² t ‚ | j d k sÇ t ‚ t j j | j	 | j	 ƒ } t j j
 d | ƒ } t |  | | g | g ƒ Sd  S(   Ns9   Scipy not  available. Scipy is needed for the Eigvalsh opi   R#   (   R   R   t   theanoR   t	   NoneConstR   R   t   scalart   upcastR#   t   vectorR   (   R   t   aRW   t	   out_dtypet   w(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   :  s    		c         C` s~   | \ } t  | ƒ d k rN t j j d | d d | d d |  j ƒ | d <n, t j j d | d d d  d |  j ƒ | d <d  S(   Ni   Ro   i    RW   i   R   (   R\   R   R    t   eigvalshR   t   None(   R   R   R$   R%   Rq   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'   O  s    	3c         C` s.   | \ } } | \ } t  |  j ƒ | | | ƒ S(   N(   t   EigvalshGradR   (   R   R$   t	   g_outputsRo   RW   t   gw(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR7   V  s    	c         C` s   | d d } | f g S(   Ni    (    (   R   R   R   t   n(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   [  s    (   s   lower(
   R8   R9   R:   R;   R<   R   R   R'   R7   R   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyRi   .  s   			Rt   c           B` s;   e  Z d  Z d Z e d „ Z d „  Z d „  Z d „  Z RS(   s`   
    Gradient of generalized eigenvalues of a Hermitian positive definite
    eigensystem.

    R   c         C` s^   | t  t g k s t ‚ | |  _ | rB t j |  _ d „  |  _ n t j |  _ d „  |  _ d  S(   Nc         S` s   t  j |  d ƒ S(   Ni   (   RB   R2   (   Ro   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   <lambda>v  s    c         S` s   t  j |  d ƒ S(   Niÿÿÿÿ(   RB   R(   (   Ro   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyRx   y  s    (	   R<   R   R   R   RB   R(   t   tri0t   tri1R2   (   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   q  s    	c         C` sß   t  s t d ƒ ‚ t | ƒ } t | ƒ } t | ƒ } | j d k sK t ‚ | j d k s` t ‚ | j d k su t ‚ t j j | j | j | j ƒ } t j j	 d | ƒ } t j j	 d | ƒ } t
 |  | | | g | | g ƒ S(   Ns9   Scipy not available. Scipy is needed for the GEigvalsh opi   i   R#   (   R   R   R   R   Rj   Rl   Rm   R#   R   t   matrixR   (   R   Ro   RW   Rv   Rp   t   out1t   out2(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   {  s    		!c         C` s  | \ } } } t  j j | | d |  j ƒ\ } } | j t j | ƒ j | j ƒ ƒ }	 | j t j | | ƒ j | j ƒ ƒ }
 |  j |	 ƒ |  j	 |	 ƒ j } |  j |
 ƒ |  j	 |
 ƒ j } t j
 | d | j d j ƒ| d d <t j
 | d | j d j ƒ| d d <d  S(   NR   R#   i    i   (   R   R    t   eighR   R1   RB   R)   R-   Ry   Rz   t   asarrayR%   R#   (   R   R   R$   R%   Ro   RW   Rv   Rq   t   vt   gAt   gBR|   R}   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'   Š  s    $$)'c         C` s   | d | d g S(   Ni    i   (    (   R   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   –  s    (   s   lower(	   R8   R9   R:   R;   R<   R   R   R'   R   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyRt   `  s   

		c         C` s   t  | ƒ |  | ƒ S(   N(   Ri   (   Ro   RW   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyRr   š  s    c         ` sV  t  j |  ƒ }  t  j | ƒ } |  j | j d k rS t d |  j | j f ƒ ‚ n  t  j |  | ƒ ‰  ˆ  j t  j |  j | j f ƒ |  j | j ƒ ‰  ˆ  j d d d t	 t
 d ˆ  j ƒ ƒ Œ } | j d k ró ˆ  j d d d ƒ } | j ƒ  ‰  n_ | j ˆ  j d ˆ  j d ˆ  j d ˆ  j d f t ‡  f d †  t d ˆ  j ƒ Dƒ ƒ ƒ ‰  ˆ  S(   sa   Kronecker product.

    Same as scipy.linalg.kron(a, b).

    Parameters
    ----------
    a: array_like
    b: array_like

    Returns
    -------
    array_like with a.ndim + b.ndim - 2 dimensions

    Notes
    -----
    numpy.kron(a, b) != scipy.linalg.kron(a, b)!
    They don't have the same shape and order when
    a.ndim != b.ndim != 2.

    i   sD   kron: inputs dimensions must sum to 3 or more. You passed %d and %d.i    i   i   c         3` s   |  ] } ˆ  j  | Vq d  S(   N(   RA   (   t   .0RI   (   t   o(    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pys	   <genexpr>Â  s    i   (   R   R   R   t	   TypeErrorR.   t   reshapet   concatenateRA   t
   dimshufflet   listt   ranget   flattent   tupleR   (   Ro   RW   t   shf(    (   R„   s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   kronž  s     *,t   Expmc           B` s8   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z RS(   s<   
    Compute the matrix exponential of a square array.

    c         C` sa   t  s t d ƒ ‚ t | ƒ } | j d k s3 t ‚ t j j d | j ƒ } t |  | g | g ƒ S(   Ns4   Scipy not available. Scipy is needed for the Expm opi   R#   (	   R   R   R   R   Rj   R   R{   R#   R   (   R   RV   t   expm(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   Î  s    		c         C` s,   | \ } | \ } t  j j | ƒ | d <d  S(   Ni    (   R   R    R   (   R   R   R$   R%   RV   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'   ×  s    		c         C` s%   | \ } | \ } t  ƒ  | | ƒ g S(   N(   t   ExpmGrad(   R   R$   R%   RV   t   g_out(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR7   Ü  s    		c         C` s   | d g S(   Ni    (    (   R   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   á  s    (    (   R8   R9   R:   R;   R   R'   R7   R   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   Æ  s   				R‘   c           B` s/   e  Z d  Z d Z d „  Z d „  Z d „  Z RS(   s@   
    Gradient of the matrix exponential of a square array.

    c         C` sd   t  s t d ƒ ‚ t | ƒ } | j d k s3 t ‚ t j j d | j ƒ } t |  | | g | g ƒ S(   Ns4   Scipy not available. Scipy is needed for the Expm opi   R#   (	   R   R   R   R   Rj   R   R{   R#   R   (   R   RV   Rv   t   out(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   í  s    		c         C` s   | d g S(   Ni    (    (   R   R   R   (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR   õ  s    c         C` s  | \ } } | \ } t  j j | d t ƒ\ } } t  j j | ƒ j }	 t j | ƒ }
 t j j	 |
 |
 ƒ t j j	 | | ƒ } t j
 | |
 ƒ |	 j | j j | ƒ j |	 ƒ | ƒ j | j ƒ } t j ƒ  . t j d t j ƒ | j | j ƒ | d <Wd  QXd  S(   Nt   rightt   ignorei    (   R   R    t   eigR<   t   invR-   RB   t   expt   subtractR.   t   fill_diagonalR1   t   warningst   catch_warningst   simplefiltert   ComplexWarningR"   R#   (   R   R   R$   R%   RV   R   R“   Rq   t   Vt   Ut   exp_wt   Xt   Y(    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR'   ø  s    	(4(    (   R8   R9   R:   R;   R   R   R'   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyR‘   å  s
   		(   s   generalR	   s   lower_triangulars   upper_triangularR   R   s   diagonalR   ((   t
   __future__R    R   R   t   loggingR›   t	   six.movesR   RB   t   scipy.linalgR   R<   R   t   ImportErrorR   Rj   R   t   theano.tensorR   t
   theano.gofR   R   t	   getLoggerR8   t   loggerRN   R   R!   R=   RJ   RT   t   solve_lower_triangularR,   Ri   Rt   Rr   RŽ   R   R‘   R   (    (    (    s5   /tmp/pip-build-X4mzal/theano/theano/tensor/slinalg.pyt   <module>   sH   

       G	Da	2:	(&