ó
î&]\c           @` sÉ   d  Z  d d l m Z m Z m Z d d l Z d d l m Z d d l	 m
 Z
 d d l m Z d d d	 g Z d e f d
 „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d	 e f d „  ƒ  YZ d S(   s@   Hessian update strategies for quasi-Newton optimization methods.i    (   t   divisiont   print_functiont   absolute_importN(   t   norm(   t   get_blas_funcs(   t   warnt   HessianUpdateStrategyt   BFGSt   SR1c           B` s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s]  Interface for implementing Hessian update strategies.

    Many optimization methods make use of Hessian (or inverse Hessian)
    approximations, such as the quasi-Newton methods BFGS, SR1, L-BFGS.
    Some of these  approximations, however, do not actually need to store
    the entire matrix or can compute the internal matrix product with a
    given vector in a very efficiently manner. This class serves as an
    abstract interface between the optimization algorithm and the
    quasi-Newton update strategies, giving freedom of implementation
    to store and update the internal matrix as efficiently as possible.
    Different choices of initialization and update procedure will result
    in different quasi-Newton strategies.

    Four methods should be implemented in derived classes: ``initialize``,
    ``update``, ``dot`` and ``get_matrix``.

    Notes
    -----
    Any instance of a class that implements this interface,
    can be accepted by the method ``minimize`` and used by
    the compatible solvers to approximate the Hessian (or
    inverse Hessian) used by the optimization algorithms.
    c         C` s   t  d ƒ ‚ d S(   sÏ  Initialize internal matrix.

        Allocate internal memory for storing and updating
        the Hessian or its inverse.

        Parameters
        ----------
        n : int
            Problem dimension.
        approx_type : {'hess', 'inv_hess'}
            Selects either the Hessian or the inverse Hessian.
            When set to 'hess' the Hessian will be stored and updated.
            When set to 'inv_hess' its inverse will be used instead.
        s=   The method ``initialize(n, approx_type)`` is not implemented.N(   t   NotImplementedError(   t   selft   nt   approx_type(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt
   initialize%   s    c         C` s   t  d ƒ ‚ d S(   sö  Update internal matrix.

        Update Hessian matrix or its inverse (depending on how 'approx_type'
        is defined) using information about the last evaluated points.

        Parameters
        ----------
        delta_x : ndarray
            The difference between two points the gradient
            function have been evaluated at: ``delta_x = x2 - x1``.
        delta_grad : ndarray
            The difference between the gradients:
            ``delta_grad = grad(x2) - grad(x1)``.
        s>   The method ``update(delta_x, delta_grad)`` is not implemented.N(   R	   (   R
   t   delta_xt
   delta_grad(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   update7   s    c         C` s   t  d ƒ ‚ d S(   sQ  Compute the product of the internal matrix with the given vector.

        Parameters
        ----------
        p : array_like
            1-d array representing a vector.

        Returns
        -------
        Hp : array
            1-d  represents the result of multiplying the approximation matrix
            by vector p.
        s)   The method ``dot(p)`` is not implemented.N(   R	   (   R
   t   p(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   dotI   s    c         C` s   t  d ƒ ‚ d S(   sö   Return current internal matrix.

        Returns
        -------
        H : ndarray, shape (n, n)
            Dense matrix containing either the Hessian
            or its inverse (depending on how 'approx_type'
            is defined).
        s0   The method ``get_matrix(p)`` is not implemented.N(   R	   (   R
   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt
   get_matrixZ   s    
(   t   __name__t
   __module__t   __doc__R   R   R   R   (    (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR      s
   			t   FullHessianUpdateStrategyc           B` s†   e  Z d  Z e d d d ƒZ e d d d ƒZ e d d d ƒZ d d „ Z d „  Z d	 „  Z	 d
 „  Z
 d „  Z d „  Z d „  Z RS(   sK   Hessian update strategy with full dimensional internal representation.
    t   syrt   dtypet   dt   syr2t   symvt   autoc         C` s1   | |  _  d  |  _ d  |  _ d  |  _ d  |  _ d  S(   N(   t
   init_scalet   Nonet   first_iterationR   t   Bt   H(   R
   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   __init__p   s
    				c         C` s|   t  |  _ | |  _ | |  _ | d k r6 t d ƒ ‚ n  |  j d k r` t j | d t ƒ|  _ n t j | d t ƒ|  _	 d S(   sÏ  Initialize internal matrix.

        Allocate internal memory for storing and updating
        the Hessian or its inverse.

        Parameters
        ----------
        n : int
            Problem dimension.
        approx_type : {'hess', 'inv_hess'}
            Selects either the Hessian or the inverse Hessian.
            When set to 'hess' the Hessian will be stored and updated.
            When set to 'inv_hess' its inverse will be used instead.
        t   hesst   inv_hesss+   `approx_type` must be 'hess' or 'inv_hess'.R   N(   R$   R%   (
   t   TrueR    R   R   t
   ValueErrort   npt   eyet   floatR!   R"   (   R
   R   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   y   s    			c         C` sŠ   t  j | | ƒ } t  j | | ƒ } t  j t  j | | ƒ ƒ } | d k sc | d k sc | d k rg d S|  j d k r~ | | S| | Sd  S(   Ng        i    i   R$   (   R(   R   t   absR   (   R
   R   R   t   s_norm2t   y_norm2t   ys(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   _auto_scale“   s    $c         C` s   t  d ƒ ‚ d  S(   Ns9   The method ``_update_implementation`` is not implemented.(   R	   (   R
   R   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   _update_implementation¡   s    c         C` sË   t  j | d k ƒ r d St  j | d k ƒ r? t d t ƒ d S|  j r· |  j d k rl |  j | | ƒ } n t |  j ƒ } |  j d k rœ |  j	 | 9_	 n |  j
 | 9_
 t |  _ n  |  j | | ƒ d S(   sö  Update internal matrix.

        Update Hessian matrix or its inverse (depending on how 'approx_type'
        is defined) using information about the last evaluated points.

        Parameters
        ----------
        delta_x : ndarray
            The difference between two points the gradient
            function have been evaluated at: ``delta_x = x2 - x1``.
        delta_grad : ndarray
            The difference between the gradients:
            ``delta_grad = grad(x2) - grad(x1)``.
        g        NsÇ   delta_grad == 0.0. Check if the approximated function is linear. If the function is linear better results can be obtained by defining the Hessian as zero instead of using quasi-Newton approximations.R   R$   (   R(   t   allR   t   UserWarningR    R   R/   R*   R   R!   R"   t   FalseR0   (   R
   R   R   t   scale(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   ¥   s    	c         C` s?   |  j  d k r% |  j d |  j | ƒ S|  j d |  j | ƒ Sd S(   sQ  Compute the product of the internal matrix with the given vector.

        Parameters
        ----------
        p : array_like
            1-d array representing a vector.

        Returns
        -------
        Hp : array
            1-d  represents the result of multiplying the approximation matrix
            by vector p.
        R$   i   N(   R   t   _symvR!   R"   (   R
   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   Ë   s    c         C` s`   |  j  d k r$ t j |  j ƒ } n t j |  j ƒ } t j | d d ƒ} | j | | | <| S(   sï   Return the current internal matrix.

        Returns
        -------
        M : ndarray, shape (n, n)
            Dense matrix containing either the Hessian or its inverse
            (depending on how `approx_type` was defined).
        R$   t   kiÿÿÿÿ(   R   R(   t   copyR!   R"   t   tril_indices_fromt   T(   R
   t   Mt   li(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   Þ   s    	(   R   R   R   R   t   _syrt   _syr2R5   R#   R   R/   R0   R   R   R   (    (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   h   s   					&	c           B` s;   e  Z d  Z d d d d „ Z d „  Z d „  Z d „  Z RS(   sÒ  Broyden-Fletcher-Goldfarb-Shanno (BFGS) Hessian update strategy.

    Parameters
    ----------
    exception_strategy : {'skip_update', 'damp_update'}, optional
        Define how to proceed when the curvature condition is violated.
        Set it to 'skip_update' to just skip the update. Or, alternatively,
        set it to 'damp_update' to interpolate between the actual BFGS
        result and the unmodified matrix. Both exceptions strategies
        are explained  in [1]_, p.536-537.
    min_curvature : float
        This number, scaled by a normalization factor, defines the
        minimum curvature ``dot(delta_grad, delta_x)`` allowed to go
        unaffected by the exception strategy. By default is equal to
        1e-8 when ``exception_strategy = 'skip_update'`` and equal
        to 0.2 when ``exception_strategy = 'damp_update'``.
    init_scale : {float, 'auto'}
        Matrix scale at first iteration. At the first
        iteration the Hessian matrix or its inverse will be initialized
        with ``init_scale*np.eye(n)``, where ``n`` is the problem dimension.
        Set it to 'auto' in order to use an automatic heuristic for choosing
        the initial scale. The heuristic is described in [1]_, p.143.
        By default uses 'auto'.

    Notes
    -----
    The update is based on the description in [1]_, p.140.

    References
    ----------
    .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
           Second Edition (2006).
    t   skip_updateR   c         C` s   | d k r0 | d  k	 r$ | |  _ ql d |  _ n< | d k r` | d  k	 rT | |  _ ql d |  _ n t d ƒ ‚ t t |  ƒ j | ƒ | |  _ d  S(   NR>   g:Œ0âŽyE>t   damp_updategš™™™™™É?s<   `exception_strategy` must be 'skip_update' or 'damp_update'.(   R   t   min_curvatureR'   t   superR   R#   t   exception_strategy(   R
   RB   R@   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR#     s    c         C` sS   |  j  d | | | d |  j ƒ|  _ |  j | | | d | d |  j ƒ|  _ d S(   s  Update the inverse Hessian matrix.

        BFGS update using the formula:

            ``H <- H + ((H*y).T*y + s.T*y)/(s.T*y)^2 * (s*s.T)
                     - 1/(s.T*y) * ((H*y)*s.T + s*(H*y).T)``

        where ``s = delta_x`` and ``y = delta_grad``. This formula is
        equivalent to (6.17) in [1]_ written in a more efficient way
        for implementation.

        References
        ----------
        .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
               Second Edition (2006).
        g      ð¿t   ai   N(   R=   R"   R<   (   R
   R.   t   Hyt   yHyt   s(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   _update_inverse_hessian&  s    %c         C` sH   |  j  d | | d |  j ƒ|  _ |  j  d | | d |  j ƒ|  _ d S(   sœ  Update the Hessian matrix.

        BFGS update using the formula:

            ``B <- B - (B*s)*(B*s).T/s.T*(B*s) + y*y^T/s.T*y``

        where ``s`` is short for ``delta_x`` and ``y`` is short
        for ``delta_grad``. Formula (6.19) in [1]_.

        References
        ----------
        .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
               Second Edition (2006).
        g      ð?RC   g      ð¿N(   R<   R!   (   R
   R.   t   Bst   sBst   y(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   _update_hessian:  s    "c   
      C` s§  |  j  d k r | } | } n | } | } t j | | ƒ } |  j | ƒ } | j | ƒ } | d k ré |  j | | ƒ } |  j  d k r© | t j |  j d t ƒ|  _ n | t j |  j d t ƒ|  _ |  j | ƒ } | j | ƒ } n  | |  j	 | k re|  j
 d k rd  S|  j
 d k red |  j	 d | | }	 |	 | d |	 | } t j | | ƒ } qen  |  j  d k r|  j | | | | ƒ n |  j | | | | ƒ d  S(   NR$   g        R   R>   R?   i   (   R   R(   R   R/   R)   R   R*   R!   R"   R@   RB   RK   RG   (
   R
   R   R   t   wt   zt   wzt   Mwt   wMwR4   t   update_factor(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR0   L  s2    	"N(   R   R   R   R   R#   RG   RK   R0   (    (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   ð   s   !		c           B` s&   e  Z d  Z d d d „ Z d „  Z RS(   sÏ  Symmetric-rank-1 Hessian update strategy.

    Parameters
    ----------
    min_denominator : float
        This number, scaled by a normalization factor,
        defines the minimum denominator magnitude allowed
        in the update. When the condition is violated we skip
        the update. By default uses ``1e-8``.
    init_scale : {float, 'auto'}, optional
        Matrix scale at first iteration. At the first
        iteration the Hessian matrix or its inverse will be initialized
        with ``init_scale*np.eye(n)``, where ``n`` is the problem dimension.
        Set it to 'auto' in order to use an automatic heuristic for choosing
        the initial scale. The heuristic is described in [1]_, p.143.
        By default uses 'auto'.

    Notes
    -----
    The update is based on the description in [1]_, p.144-146.

    References
    ----------
    .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
           Second Edition (2006).
    g:Œ0âŽyE>R   c         C` s#   | |  _  t t |  ƒ j | ƒ d  S(   N(   t   min_denominatorRA   R   R#   (   R
   RR   R   (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR#   –  s    	c         C` sß   |  j  d k r | } | } n | } | } |  j | ƒ } | | } t j | | ƒ } t j | ƒ |  j t | ƒ t | ƒ k r… d  S|  j  d k r¹ |  j d | | d |  j ƒ|  _ n" |  j d | | d |  j ƒ|  _ d  S(   NR$   i   RC   (	   R   R   R(   R+   RR   R   R<   R!   R"   (   R
   R   R   RL   RM   RO   t
   z_minus_Mwt   denominator(    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR0   š  s    	
,%(   R   R   R   R#   R0   (    (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyR   z  s   (   R   t
   __future__R    R   R   t   numpyR(   t   numpy.linalgR   t   scipy.linalgR   t   warningsR   t   __all__t   objectR   R   R   R   (    (    (    sF   lib/python2.7/site-packages/scipy/optimize/_hessian_update_strategy.pyt   <module>   s   \ˆŠ