
    ge=                         d Z ddlZddlmZ ddlmZ ddlmZ g dZ	 G d d          Z
 G d	 d
e
          Z G d de          Z G d de          ZdS )z@Hessian update strategies for quasi-Newton optimization methods.    N)norm)get_blas_funcs)warn)HessianUpdateStrategyBFGSSR1c                   *    e Zd ZdZd Zd Zd Zd ZdS )r   a]  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                      t          d          )  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.
        z=The method ``initialize(n, approx_type)`` is not implemented.NotImplementedErrorselfnapprox_types      Glib/python3.11/site-packages/scipy/optimize/_hessian_update_strategy.py
initializez HessianUpdateStrategy.initialize$        " #9 : : 	:    c                      t          d          )  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)``.
        z>The method ``update(delta_x, delta_grad)`` is not implemented.r   r   delta_x
delta_grads      r   updatezHessianUpdateStrategy.update6   r   r   c                      t          d          )P  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.
        z)The method ``dot(p)`` is not implemented.r   r   ps     r   dotzHessianUpdateStrategy.dotH   s     " #9 : : 	:r   c                      t          d          )zReturn 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).
        z0The method ``get_matrix(p)`` is not implemented.r   )r   s    r   
get_matrixz HessianUpdateStrategy.get_matrixY   s     " #9 : : 	:r   N)__name__
__module____qualname____doc__r   r   r    r"    r   r   r   r      sZ         0: : :$: : :$: : :": : : : :r   r   c                       e Zd ZdZ edd          Z edd          Z edd          ZddZd	 Z	d
 Z
d Zd Zd Zd ZdS )FullHessianUpdateStrategyzKHessian update strategy with full dimensional internal representation.
    syrddtypesyr2symvautoc                 L    || _         d | _        d | _        d | _        d | _        d S N)
init_scalefirst_iterationr   BH)r   r3   s     r   __init__z"FullHessianUpdateStrategy.__init__o   s-    $  $r   c                     d| _         || _        || _        |dvrt          d          | j        dk    r"t	          j        |t                    | _        dS t	          j        |t                    | _        dS )r   T)hessinv_hessz+`approx_type` must be 'hess' or 'inv_hess'.r9   r,   N)	r4   r   r   
ValueErrornpeyefloatr5   r6   r   s      r   r   z$FullHessianUpdateStrategy.initializex   sx      $&222JKKKv%%VAU+++DFFFVAU+++DFFFr   c                     t          j        ||          }t          j        ||          }t          j        t          j        ||                    }|dk    s|dk    s|dk    rdS | j        dk    r||z  S ||z  S )N        r      r9   )r<   r    absr   )r   r   r   s_norm2y_norm2yss         r   _auto_scalez%FullHessianUpdateStrategy._auto_scale   s     &'**&Z00VBF:w//0099111v%%R<<r   c                      t          d          )Nz9The method ``_update_implementation`` is not implemented.r   r   s      r   _update_implementationz0FullHessianUpdateStrategy._update_implementation   s    ! #9 : : 	:r   c                    t          j        |dk              rdS t          j        |dk              rt          dt                     dS | j        ri| j        dk    r|                     ||          }nt          | j                  }| j        dk    r| xj	        |z  c_	        n| xj
        |z  c_
        d| _        |                     ||           dS )r   r@   Nzdelta_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.r0   r9   F)r<   allr   UserWarningr4   r3   rF   r>   r   r5   r6   rH   )r   r   r   scales       r   r   z FullHessianUpdateStrategy.update   s     6'S.!! 	F6*#$$ 	 # %0	1 1 1
 F 	)&((((*==do..6))%%#(D ##GZ88888r   c                     | j         dk    r|                     d| j        |          S |                     d| j        |          S )r   r9   rA   )r   _symvr5   r6   r   s     r   r    zFullHessianUpdateStrategy.dot   sB     v%%::a+++::a+++r   c                     | j         dk    rt          j        | j                  }nt          j        | j                  }t          j        |d          }|j        |         ||<   |S )zReturn 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).
        r9   )k)r   r<   copyr5   r6   tril_indices_fromT)r   Mlis      r   r"   z$FullHessianUpdateStrategy.get_matrix   s[     v%%AAA!!r***B"r   N)r0   )r#   r$   r%   r&   r   _syr_syr2rN   r7   r   rF   rH   r   r    r"   r'   r   r   r)   r)   g   s         >%s+++DN6---EN6---E   , , ,4     : : :$9 $9 $9L, , ,&    r   r)   c                   :     e Zd ZdZ	 	 d	 fd	Zd Zd Zd Z xZS )
r   a  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).
    skip_updateNr0   c                     |dk    r||| _         n/d| _         n'|dk    r||| _         nd| _         nt          d          t                                          |           || _        d S )NrZ   :0yE>damp_updateg?z<`exception_strategy` must be 'skip_update' or 'damp_update'.)min_curvaturer;   superr7   exception_strategy)r   r`   r^   r3   	__class__s       r   r7   zBFGS.__init__  s    ..(%2""%)""=00(%2""%("" 1 2 2 2 	$$$"4r   c                     |                      d|z  ||| j                  | _        |                     ||z   |dz  z  || j                  | _        dS )a  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).
              a   N)rX   r6   rW   )r   rE   HyyHyss        r   _update_inverse_hessianzBFGS._update_inverse_hessian%  sP    " D2Iq"77BsFBE>177r   c                     |                      d|z  || j                  | _        |                      d|z  || j                  | _        dS )a  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      ?rd   rc   N)rW   r5   )r   rE   BssBsys        r   _update_hessianzBFGS._update_hessian9  sF     38Q$&114#:rTV44r   c                 "   | j         dk    r|}|}n|}|}t          j        ||          }|                     |          }|                    |          }|dk    r|                     ||          }| j         dk    r)|t          j        | j        t                    z  | _        n(|t          j        | j        t                    z  | _        |                     |          }|                    |          }|| j	        |z  k    rN| j
        dk    rd S | j
        dk    r6d| j	        z
  d||z  z
  z  }	|	|z  d|	z
  |z  z   }t          j        ||          }| j         dk    r|                     ||||           d S |                     ||||           d S )Nr9   r@   r,   rZ   r]   rA   )r   r<   r    rF   r=   r   r>   r5   r6   r^   r`   ro   rj   )
r   r   r   wzwzMwwMwrL   update_factors
             r   rH   zBFGS._update_implementationK  s   v%%AAAAAVAq\\XXa[[ffQii #::$$Wj99E6))e!<!<!<<e!<!<!<<!B&&))C#c))) &-77 (M99!"4#5!5!bf* E!!Oq&::VAq\\v%%  Ra00000((Ra88888r   )rZ   Nr0   )	r#   r$   r%   r&   r7   rj   ro   rH   __classcell__ra   s   @r   r   r      s           D HL"5 5 5 5 5 5&8 8 8(5 5 5$+9 +9 +9 +9 +9 +9 +9r   r   c                   *     e Zd ZdZd fd	Zd Z xZS )r   a  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).
    r\   r0   c                 X    || _         t                                          |           d S r2   )min_denominatorr_   r7   )r   r{   r3   ra   s      r   r7   zSR1.__init__  s)    .$$$$$r   c                    | j         dk    r|}|}n|}|}|                     |          }||z
  }t          j        ||          }t          j        |          | j        t          |          z  t          |          z  k    rd S | j         dk    r'|                     d|z  || j                  | _        d S |                     d|z  || j                  | _        d S )Nr9   rA   rd   )	r   r    r<   rB   r{   r   rW   r5   r6   )r   r   r   rq   rr   rt   
z_minus_Mwdenominators           r   rH   zSR1._update_implementation  s    v%%AAAAAXXa[[V
fQ
++ 6+$"6tAww">tJ?O?O"OOOFv%%YYq}jDFYCCDFFFYYq}jDFYCCDFFFr   )r\   r0   )r#   r$   r%   r&   r7   rH   rw   rx   s   @r   r   r   y  s]         6% % % % % %D D D D D D Dr   r   )r&   numpyr<   numpy.linalgr   scipy.linalgr   warningsr   __all__r   r)   r   r   r'   r   r   <module>r      s2   F F           ' ' ' ' ' '       3
2
2Y: Y: Y: Y: Y: Y: Y: Y:xE E E E E 5 E E EPG9 G9 G9 G9 G9$ G9 G9 G9T4D 4D 4D 4D 4D
# 4D 4D 4D 4D 4Dr   