
    xfX                         d dl Zd dlmZ ddlmZmZ ddlm	Z	 d dl
mZ dZ G d d      Z G d	 d
      Z G d d      Z G d de      Zy)    N   )approx_derivativegroup_columns)HessianUpdateStrategy)LinearOperator)z2-pointz3-pointcsc                   D    e Zd ZdZ	 ddZd Zd Zd Zd Zd Z	d	 Z
d
 Zy)ScalarFunctiona  Scalar function and its derivatives.

    This class defines a scalar function F: R^n->R and methods for
    computing or approximating its first and second derivatives.

    Parameters
    ----------
    fun : callable
        evaluates the scalar function. Must be of the form ``fun(x, *args)``,
        where ``x`` is the argument in the form of a 1-D array and ``args`` is
        a tuple of any additional fixed parameters needed to completely specify
        the function. Should return a scalar.
    x0 : array-like
        Provides an initial set of variables for evaluating fun. Array of real
        elements of size (n,), where 'n' is the number of independent
        variables.
    args : tuple, optional
        Any additional fixed parameters needed to completely specify the scalar
        function.
    grad : {callable, '2-point', '3-point', 'cs'}
        Method for computing the gradient vector.
        If it is a callable, it should be a function that returns the gradient
        vector:

            ``grad(x, *args) -> array_like, shape (n,)``

        where ``x`` is an array with shape (n,) and ``args`` is a tuple with
        the fixed parameters.
        Alternatively, the keywords  {'2-point', '3-point', 'cs'} can be used
        to select a finite difference scheme for numerical estimation of the
        gradient with a relative step size. These finite difference schemes
        obey any specified `bounds`.
    hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy}
        Method for computing the Hessian matrix. If it is callable, it should
        return the  Hessian matrix:

            ``hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)``

        where x is a (n,) ndarray and `args` is a tuple with the fixed
        parameters. Alternatively, the keywords {'2-point', '3-point', 'cs'}
        select a finite difference scheme for numerical estimation. Or, objects
        implementing `HessianUpdateStrategy` interface can be used to
        approximate the Hessian.
        Whenever the gradient is estimated via finite-differences, the Hessian
        cannot be estimated with options {'2-point', '3-point', 'cs'} and needs
        to be estimated using one of the quasi-Newton strategies.
    finite_diff_rel_step : None or array_like
        Relative step size to use. The absolute step size is computed as
        ``h = finite_diff_rel_step * sign(x0) * max(1, abs(x0))``, possibly
        adjusted to fit into the bounds. For ``method='3-point'`` the sign
        of `h` is ignored. If None then finite_diff_rel_step is selected
        automatically,
    finite_diff_bounds : tuple of array_like
        Lower and upper bounds on independent variables. Defaults to no bounds,
        (-np.inf, np.inf). Each bound must match the size of `x0` or be a
        scalar, in the latter case the bound will be the same for all
        variables. Use it to limit the range of function evaluation.
    epsilon : None or array_like, optional
        Absolute step size to use, possibly adjusted to fit into the bounds.
        For ``method='3-point'`` the sign of `epsilon` is ignored. By default
        relative steps are used, only if ``epsilon is not None`` are absolute
        steps used.

    Notes
    -----
    This class implements a memoization logic. There are methods `fun`,
    `grad`, hess` and corresponding attributes `f`, `g` and `H`. The following
    things should be considered:

        1. Use only public methods `fun`, `grad` and `hess`.
        2. After one of the methods is called, the corresponding attribute
           will be set. However, a subsequent call with a different argument
           of *any* of the methods may overwrite the attribute.
    Nc	                     t              st        vrt        dt         d      t              s+t        v s#t        t              st        dt         d      t        v rt        v rt        d      t        j                  |      j                  t               _	         j                  j                   _        d _        d _        d _        d _        d _        d _        d  _        t
        j&                   _        i t        v rd<   |d<   |d	<   |d
<   t        v rd<   |d<   |d	<   dd<    fd fd}	|	 _         j-                          t              r fd fd}
nt        v r fd}

 _         j1                          t              r t        j2                  |      g  _        d _         xj                  dz  c_        t7        j8                   j4                        r, fdt7        j:                   j4                         _        n`t         j4                  t<              r fdn> fdt        j>                  t        j@                   j4                               _         fd}nut        v r fd} |        d _        nWt        t              rG _         j4                  jC                   j                  d       d _        d  _"        d  _#         fd} _$        t        t              r fd}| _%        y  fd}| _%        y )Nz)`grad` must be either callable or one of .z@`hess` must be either callable, HessianUpdateStrategy or one of zWhenever the gradient is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   Fmethodrel_stepabs_stepboundsTas_linear_operatorc                 \   xj                   dz  c_          t        j                  |       g }t        j                  |      s$	 t        j                  |      j                         }|j                  k  r| _	        |_        |S # t        t        f$ r}t        d      |d }~ww xY w)Nr   z@The user-provided objective function must return a scalar value.)
nfevnpcopyisscalarasarrayitem	TypeError
ValueError	_lowest_f	_lowest_x)xfxeargsfunselfs      J/usr/lib/python3/dist-packages/scipy/optimize/_differentiable_functions.pyfun_wrappedz,ScalarFunction.__init__.<locals>.fun_wrapped   s    IINI RWWQZ'$'B;;r?B,,.B DNN"!"!#I ":. $6 s   	#B B+B&&B+c                  4      j                         _        y Nr   fr$   r"   s   r#   
update_funz+ScalarFunction.__init__.<locals>.update_fun        (DF    c                     xj                   dz  c_         t        j                   t        j                  |       g       S Nr   )ngevr   
atleast_1dr   )r   r    gradr"   s    r#   grad_wrappedz-ScalarFunction.__init__.<locals>.grad_wrapped   s1    		Q	}}T"''!*%<t%<==r,   c                  4      j                         _        y r&   )r   g)r2   r"   s   r#   update_gradz,ScalarFunction.__init__.<locals>.update_grad       %dff-r,   c                      j                          xj                  dz  c_        t        j                  fdj                  i _        y )Nr   f0)_update_funr/   r   r   r(   r4   finite_diff_optionsr$   r"   s   r#   r5   z,ScalarFunction.__init__.<locals>.update_grad   sF      "		Q	*; B466 B-@Br,   r   c                     xj                   dz  c_         t        j                   t        j                  |       g       S r.   )nhevsps
csr_matrixr   r   r   r    hessr"   s    r#   hess_wrappedz-ScalarFunction.__init__.<locals>.hess_wrapped   s1    IINI>>$rwwqz*AD*ABBr,   c                 f    xj                   dz  c_          t        j                  |       g S r.   )r=   r   r   r@   s    r#   rB   z-ScalarFunction.__init__.<locals>.hess_wrapped   s(    IINI
2T22r,   c           	          xj                   dz  c_         t        j                  t        j                   t        j                  |       g             S r.   )r=   r   
atleast_2dr   r   r@   s    r#   rB   z-ScalarFunction.__init__.<locals>.hess_wrapped   s:    IINI==D4Kd4K)LMMr,   c                  4      j                         _        y r&   )r   HrB   r"   s   r#   update_hessz,ScalarFunction.__init__.<locals>.update_hess   r6   r,   c                      j                          t        j                  fdj                  i _        j                  S Nr8   )_update_gradr   r   r4   rG   )r;   r2   r"   s   r#   rI   z,ScalarFunction.__init__.<locals>.update_hess   sB    !!#*< BDFF B-@Bvvr,   rA   c                       j                           j                  j                   j                   j                  z
   j
                   j                  z
         y r&   )rL   rG   updater   x_prevr4   g_prevr"   s   r#   rI   z,ScalarFunction.__init__.<locals>.update_hess   s;    !!#dfft{{2DFFT[[4HIr,   c                    j                          j                  _        j                  _        t        j                  |       j                  t              _        d_	        d_
        d_        j                          y NF)rL   r   rO   r4   rP   r   r0   astypefloat	f_updated	g_updated	H_updated_update_hessr   r"   s    r#   update_xz)ScalarFunction.__init__.<locals>.update_x   sc    !!#"ff"ff q)007!&!&!&!!#r,   c                     t        j                  |       j                  t              _        d_        d_        d_        y rS   )r   r0   rT   rU   r   rV   rW   rX   rZ   s    r#   r[   z)ScalarFunction.__init__.<locals>.update_x   s5     q)007!&!&!&r,   )&callable
FD_METHODSr   
isinstancer   r   r0   rT   rU   r   sizenr   r/   r=   rV   rW   rX   r   infr   _update_fun_implr9   _update_grad_implrL   r   rG   r>   issparser?   r   rE   r   
initializerO   rP   _update_hess_impl_update_x_impl)r"   r!   x0r    r1   rA   finite_diff_rel_stepfinite_diff_boundsepsilonr*   r5   rI   r[   r;   r$   r2   rB   s   `` ```       @@@@r#   __init__zScalarFunction.__init__V   s   ~$j"8;J<qI  $*"4d$9:(\, 
 :$*"4 8 9 9 r"))%0			 :,0).B
+.5
+,>):,0).B
+.5
+8< 45	,	) !+ D>>. ZB "- D>"''"+--DF!DNIINI||DFF#C /DFFN33
N rzz$&&'9:. Z M!DN34DFFFdfff-!DNDKDKJ "-d12
$& '' 'r,   c                 L    | j                   s| j                          d| _         y y NTrV   rc   rQ   s    r#   r9   zScalarFunction._update_fun   !    ~~!!#!DN r,   c                 L    | j                   s| j                          d| _         y y ro   )rW   rd   rQ   s    r#   rL   zScalarFunction._update_grad   !    ~~""$!DN r,   c                 L    | j                   s| j                          d| _         y y ro   rX   rg   rQ   s    r#   rY   zScalarFunction._update_hess  rs   r,   c                     t        j                  || j                        s| j                  |       | j	                          | j
                  S r&   )r   array_equalr   rh   r9   r(   r"   r   s     r#   r!   zScalarFunction.fun  s7    ~~a("vvr,   c                     t        j                  || j                        s| j                  |       | j	                          | j
                  S r&   )r   rw   r   rh   rL   r4   rx   s     r#   r1   zScalarFunction.grad  7    ~~a("vvr,   c                     t        j                  || j                        s| j                  |       | j	                          | j
                  S r&   )r   rw   r   rh   rY   rG   rx   s     r#   rA   zScalarFunction.hess  rz   r,   c                     t        j                  || j                        s| j                  |       | j	                          | j                          | j                  | j                  fS r&   )r   rw   r   rh   r9   rL   r(   r4   rx   s     r#   fun_and_gradzScalarFunction.fun_and_grad  sL    ~~a("vvtvv~r,   r&   )__name__
__module____qualname____doc__rm   r9   rL   rY   r!   r1   rA   r}    r,   r#   r
   r
      s8    IV .2a'F"
"
"
r,   r
   c                   F    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)VectorFunctiona  Vector function and its derivatives.

    This class defines a vector function F: R^n->R^m and methods for
    computing or approximating its first and second derivatives.

    Notes
    -----
    This class implements a memoization logic. There are methods `fun`,
    `jac`, hess` and corresponding attributes `f`, `J` and `H`. The following
    things should be considered:

        1. Use only public methods `fun`, `jac` and `hess`.
        2. After one of the methods is called, the corresponding attribute
           will be set. However, a subsequent call with a different argument
           of *any* of the methods may overwrite the attribute.
    c	                     t              s&t        vrt        dj                  t                    t              s6t        v s.t	        t
              st        dj                  t                    t        v rt        v rt        d      t        j                  |      j                  t               _
         j                  j                   _        d _        d _        d _        d _        d _        d _        i t        v rGd<   |d<   |t'        |      }	||	fd<   |d	<   t        j(                   j                         _        t        v r3d<   |d<   d
d<   t        j(                   j                         _        t        v rt        v rt        d       fd fd}
|
 _         |
        t        j.                   j0                         _         j2                  j                   _        t              r  j                         _        d
 _         xj                  dz  c_        |s!|Qt9        j:                   j6                        r2 fdt9        j<                   j6                         _        d
 _        n}t9        j:                   j6                        r- fd j6                  jA                          _        d _        n1 fdt        jB                   j6                         _        d _         fd}nt        v rtE         j                  fd j0                  i _        d
 _        |s!|Rt9        j:                   j6                        r3 fd}t9        j<                   j6                         _        d
 _        nt9        j:                   j6                        r. fd} j6                  jA                          _        d _        n2 fd}t        jB                   j6                         _        d _         _#        t              r  j                   j2                         _$        d
 _         xj                  dz  c_        t9        j:                   jH                        r+ fdt9        j<                   jH                         _$        n^t	         jH                  tJ              r fdn= fdt        jB                  t        jL                   jH                               _$         fd}nzt        v rfd fd} |        d
 _        nWt	        t
              rG _$         jH                  jO                   j                  d       d
 _        d  _(        d  _)         fd} _*        t	        t
              r fd}| _+        y  fd }| _+        y )!Nz+`jac` must be either callable or one of {}.zB`hess` must be either callable,HessianUpdateStrategy or one of {}.zWhenever the Jacobian is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   Fr   r   sparsityr   Tr   c                 d    xj                   dz  c_         t        j                   |             S r.   )r   r   r0   )r   r!   r"   s    r#   r$   z,VectorFunction.__init__.<locals>.fun_wrappede  s#    IINI==Q((r,   c                  4      j                         _        y r&   r'   r)   s   r#   r*   z+VectorFunction.__init__.<locals>.update_funi  r+   r,   r   c                 d    xj                   dz  c_         t        j                   |             S r.   )njevr>   r?   r   jacr"   s    r#   jac_wrappedz,VectorFunction.__init__.<locals>.jac_wrappedz  s#    IINI>>#a&11r,   c                 Z    xj                   dz  c_          |       j                         S r.   )r   toarrayr   s    r#   r   z,VectorFunction.__init__.<locals>.jac_wrapped  s!    IINIq6>>++r,   c                 d    xj                   dz  c_         t        j                   |             S r.   )r   r   rE   r   s    r#   r   z,VectorFunction.__init__.<locals>.jac_wrapped  s#    IINI==Q00r,   c                  4      j                         _        y r&   )r   J)r   r"   s   r#   
update_jacz+VectorFunction.__init__.<locals>.update_jac  s    $TVV,r,   r8   c                      j                          t        j                  t        j                  fdj
                  i       _        y rK   )r9   r>   r?   r   r   r(   r   r:   s   r#   r   z+VectorFunction.__init__.<locals>.update_jac  sF    $$& ^^)+tvv A$&& A,?ABDFr,   c                      j                          t        j                  fdj                  i j	                         _        y rK   )r9   r   r   r(   r   r   r:   s   r#   r   z+VectorFunction.__init__.<locals>.update_jac  sC    $$&.{DFF Ftvv F1DFFMgi Fr,   c                      j                          t        j                  t        j                  fdj
                  i       _        y rK   )r9   r   rE   r   r   r(   r   r:   s   r#   r   z+VectorFunction.__init__.<locals>.update_jac  sF    $$&]])+tvv A$&& A,?ABDFr,   c                 f    xj                   dz  c_         t        j                   | |            S r.   )r=   r>   r?   r   vrA   r"   s     r#   rB   z-VectorFunction.__init__.<locals>.hess_wrapped  s%    IINI>>$q!*55r,   c                 @    xj                   dz  c_          | |      S r.   )r=   r   s     r#   rB   z-VectorFunction.__init__.<locals>.hess_wrapped  s    IINI1:%r,   c                     xj                   dz  c_         t        j                  t        j                   | |                  S r.   )r=   r   rE   r   r   s     r#   rB   z-VectorFunction.__init__.<locals>.hess_wrapped  s.    IINI==DAJ)?@@r,   c                  J      j                   j                        _        y r&   )r   r   rG   rH   s   r#   rI   z,VectorFunction.__init__.<locals>.update_hess  s    %dffdff5r,   c                 F     |       j                   j                  |      S r&   )Tdot)r   r   r   s     r#   	jac_dot_vz*VectorFunction.__init__.<locals>.jac_dot_v  s    "1~''++A..r,   c                      j                          t        j                  fj                  j                  j                  j                        j                  fd _        y )N)r8   r    )_update_jacr   r   r   r   r   r   rG   )r;   r   r"   s   r#   rI   z,VectorFunction.__init__.<locals>.update_hess  sW      "*9dff B.2ffhhll466.B15	B .ABr,   rA   c                     j                          j                  j                  j                  j                  z
  } j                  j
                  j                  j                        j                  j
                  j                  j                        z
  }j                  j                  | |       y y y r&   )
r   rO   J_prevr   r   r   r   r   rG   rN   )delta_xdelta_gr"   s     r#   rI   z,VectorFunction.__init__.<locals>.update_hess  s      " ;;*t{{/F"fft{{2G"ffhhll4662T[[]]5F5Ftvv5NNGFFMM'73 0G*r,   c                    j                          j                  _        j                  _        t        j                  |       j                  t              _        d_	        d_
        d_        j                          y rS   )r   r   rO   r   r   r   r0   rT   rU   rV   	J_updatedrX   rY   rZ   s    r#   r[   z)VectorFunction.__init__.<locals>.update_x  sa      ""ff"ffq)007!&!&!&!!#r,   c                     t        j                  |       j                  t              _        d_        d_        d_        y rS   )r   r0   rT   rU   r   rV   r   rX   rZ   s    r#   r[   z)VectorFunction.__init__.<locals>.update_x  s3    q)007!&!&!&r,   ),r]   r^   r   formatr_   r   r   r0   rT   rU   r   r`   ra   r   r   r=   rV   r   rX   r   r   x_diffrc   
zeros_liker(   r   mr   r>   re   r?   sparse_jacobianr   rE   r   _update_jac_implrG   r   r   rf   rO   r   rg   rh   )r"   r!   ri   r   rA   rj   finite_diff_jac_sparsityrk   r   sparsity_groupsr*   r   rI   r[   r;   r$   rB   r   r   s   `` ``         @@@@@r#   rm   zVectorFunction.__init__3  s    }J!6J$fZ02 2 $*"4d$9: C$fZ02 2 *!3 + , ,
 r"))%0			 *,/).B
+'3"/0H"I3K3B3D#J/,>)''$&&/DK:,0).B
+8< 45''$&&/DK*!3 + , ,	)	) !+tvv& C=[DF!DNIINI#+TVV0D2 /'+$dff%, )',$1 tvv.',$- J&{DFF >tvv >)<>DF!DN#+TVV0DB
 /'+$dff%P )',$B
 tvv.',$ * D>$&&$&&)DF!DNIINI||DFF#6 /DFFN3&
A rzz$&&'9:6Z/B M!DN34DFFFdfff-!DNDKDK4 "-d12$  '' 'r,   c                 b    t        j                  || j                        s|| _        d| _        y y rS   )r   rw   r   rX   )r"   r   s     r#   	_update_vzVectorFunction._update_v  s'    ~~a(DF"DN )r,   c                 h    t        j                  || j                        s| j                  |       y y r&   )r   rw   r   rh   rx   s     r#   	_update_xzVectorFunction._update_x  s'    ~~a(" )r,   c                 L    | j                   s| j                          d| _         y y ro   rp   rQ   s    r#   r9   zVectorFunction._update_fun  rq   r,   c                 L    | j                   s| j                          d| _         y y ro   )r   r   rQ   s    r#   r   zVectorFunction._update_jac  rq   r,   c                 L    | j                   s| j                          d| _         y y ro   ru   rQ   s    r#   rY   zVectorFunction._update_hess  rs   r,   c                 \    | j                  |       | j                          | j                  S r&   )r   r9   r(   rx   s     r#   r!   zVectorFunction.fun  #    qvvr,   c                 \    | j                  |       | j                          | j                  S r&   )r   r   r   rx   s     r#   r   zVectorFunction.jac  r   r,   c                 ~    | j                  |       | j                  |       | j                          | j                  S r&   )r   r   rY   rG   r"   r   r   s      r#   rA   zVectorFunction.hess  s/    qqvvr,   N)r~   r   r   r   rm   r   r   r9   r   rY   r!   r   rA   r   r,   r#   r   r   "  s6     H'T#
#"
"
"


r,   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)LinearVectorFunctionzLinear vector function and its derivatives.

    Defines a linear function F = A x, where x is N-D vector and
    A is m-by-n matrix. The Jacobian is constant and equals to A. The Hessian
    is identically zero and it is returned as a csr matrix.
    c                    |s|7t        j                  |      r"t        j                  |      | _        d| _        nft        j                  |      r|j                         | _        d| _        n4t        j                  t        j                  |            | _        d| _        | j                  j                  \  | _
        | _        t        j                  |      j                  t              | _        | j                  j!                  | j                        | _        d| _        t        j&                  | j                  t              | _        t        j                  | j                  | j                  f      | _        y )NTF)dtype)r>   re   r?   r   r   r   r   rE   r   shaper   ra   r0   rT   rU   r   r   r(   rV   zerosr   rG   )r"   Ari   r   s       r#   rm   zLinearVectorFunction.__init__.  s    o5#,,q/^^A&DF#'D \\!_YY[DF#(D  ]]2::a=1DF#(D r"))%0DFF#$&&. 01r,   c                     t        j                  || j                        s5t        j                  |      j	                  t
              | _        d| _        y y rS   )r   rw   r   r0   rT   rU   rV   rx   s     r#   r   zLinearVectorFunction._update_xC  s;    ~~a(]]1%,,U3DF"DN )r,   c                     | j                  |       | j                  s'| j                  j                  |      | _        d| _        | j                  S ro   )r   rV   r   r   r(   rx   s     r#   r!   zLinearVectorFunction.funH  s8    q~~VVZZ]DF!DNvvr,   c                 <    | j                  |       | j                  S r&   )r   r   rx   s     r#   r   zLinearVectorFunction.jacO  s    qvvr,   c                 J    | j                  |       || _        | j                  S r&   )r   r   rG   r   s      r#   rA   zLinearVectorFunction.hessS  s    qvvr,   N)	r~   r   r   r   rm   r   r!   r   rA   r   r,   r#   r   r   '  s     2*#
r,   r   c                   "     e Zd ZdZ fdZ xZS )IdentityVectorFunctionzIdentity vector function and its derivatives.

    The Jacobian is the identity matrix, returned as a dense array when
    `sparse_jacobian=False` and as a csr matrix otherwise. The Hessian is
    identically zero and it is returned as a csr matrix.
    c                     t        |      }|s|t        j                  |d      }d}nt        j                  |      }d}t        |   |||       y )Ncsr)r   TF)lenr>   eyer   superrm   )r"   ri   r   ra   r   	__class__s        r#   rm   zIdentityVectorFunction.__init__`  sL    Go5%(A"Oq	A#OB0r,   )r~   r   r   r   rm   __classcell__)r   s   @r#   r   r   Y  s    1 1r,   r   )numpyr   scipy.sparsesparser>   _numdiffr   r   _hessian_update_strategyr   scipy.sparse.linalgr   r^   r
   r   r   r   r   r,   r#   <module>r      sM      6 ; . *
T TnB BJ/ /d11 1r,   