U
    ¦»|e›)  ã                   @   s|   d Z ddlZddlZddlZddlZddlmZm	Z	m
Z
mZ ddlmZ ddlmZ g Zdd„ ZG d	d
„ d
ƒZddd„ZdS )zTrust-region optimization.é    Né   )Ú_check_unknown_optionsÚ_status_messageÚOptimizeResultÚ_prepare_scalar_function)ÚHessianUpdateStrategy)Ú
FD_METHODSc                    s.   dg‰ˆd krˆd fS ‡ ‡‡fdd„}ˆ|fS )Nr   c                    s(   ˆd  d7  < ˆt  | ¡f|ˆ  žŽ S )Nr   r   )ÚnpÚcopy)ÚxÚwrapper_args©ÚargsÚfunctionÚncalls© úX/var/www/website-v5/atlas_env/lib/python3.8/site-packages/scipy/optimize/_trustregion.pyÚfunction_wrapper   s    z(_wrap_function.<locals>.function_wrapperr   )r   r   r   r   r   r   Ú_wrap_function   s
    r   c                   @   sj   e Zd ZdZddd„Zdd„ Zedd„ ƒZed	d
„ ƒZedd„ ƒZ	dd„ Z
edd„ ƒZdd„ Zdd„ ZdS )ÚBaseQuadraticSubproblemaQ  
    Base/abstract class defining the quadratic model for trust-region
    minimization. Child classes must implement the ``solve`` method.

    Values of the objective function, Jacobian and Hessian (if provided) at
    the current iterate ``x`` are evaluated on demand and then stored as
    attributes ``fun``, ``jac``, ``hess``.
    Nc                 C   sF   || _ d | _d | _d | _d | _d | _d | _|| _|| _|| _	|| _
d S ©N)Ú_xÚ_fÚ_gÚ_hÚ_g_magÚ_cauchy_pointÚ_newton_pointÚ_funÚ_jacÚ_hessÚ_hessp)Úselfr   ÚfunÚjacÚhessÚhesspr   r   r   Ú__init__'   s    z BaseQuadraticSubproblem.__init__c                 C   s*   | j t | j|¡ dt ||  |¡¡  S )Ng      à?)r#   r	   Údotr$   r&   ©r"   Úpr   r   r   Ú__call__4   s    z BaseQuadraticSubproblem.__call__c                 C   s   | j dkr|  | j¡| _ | j S )z1Value of objective function at current iteration.N)r   r   r   ©r"   r   r   r   r#   7   s    
zBaseQuadraticSubproblem.func                 C   s   | j dkr|  | j¡| _ | j S )z=Value of Jacobian of objective function at current iteration.N)r   r   r   r,   r   r   r   r$   >   s    
zBaseQuadraticSubproblem.jacc                 C   s   | j dkr|  | j¡| _ | j S )z<Value of Hessian of objective function at current iteration.N)r   r    r   r,   r   r   r   r%   E   s    
zBaseQuadraticSubproblem.hessc                 C   s*   | j d k	r|   | j|¡S t | j|¡S d S r   )r!   r   r	   r(   r%   r)   r   r   r   r&   L   s    
zBaseQuadraticSubproblem.hesspc                 C   s    | j dkrtj | j¡| _ | j S )zAMagnitude of jacobian of objective function at current iteration.N)r   ÚscipyÚlinalgÚnormr$   r,   r   r   r   Újac_magR   s    
zBaseQuadraticSubproblem.jac_magc                 C   s€   t  ||¡}dt  ||¡ }t  ||¡|d  }t || d| |  ¡}|t ||¡ }| d|  }	d| | }
t|	|
gƒS )zÀ
        Solve the scalar quadratic equation ||z + t d|| == trust_radius.
        This is like a line-sphere intersection.
        Return the two values of t, sorted from low to high.
        é   é   éþÿÿÿ)r	   r(   ÚmathÚsqrtÚcopysignÚsorted)r"   ÚzÚdÚtrust_radiusÚaÚbÚcZsqrt_discriminantÚauxÚtaÚtbr   r   r   Úget_boundaries_intersectionsY   s    	z4BaseQuadraticSubproblem.get_boundaries_intersectionsc                 C   s   t dƒ‚d S )Nz9The solve method should be implemented by the child class)ÚNotImplementedError)r"   r:   r   r   r   Úsolvep   s    zBaseQuadraticSubproblem.solve)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r+   Úpropertyr#   r$   r%   r&   r0   rA   rC   r   r   r   r   r      s   	




r   r   ç      ð?ç     @�@ç333333Ã?ç-Cëâ6?FTc           "         st  t |ƒ |dkrtdƒ‚|dkr0|dkr0tdƒ‚|dkr@tdƒ‚d|	  krTdk s^n tdƒ‚|dkrntdƒ‚|dkr~td	ƒ‚||krŽtd
ƒ‚t |¡ ¡ }t| ||||d�‰ ˆ j} ˆ j}t	|ƒrÊˆ j
}n6t	|ƒrÔn,|tksæt|tƒrød}‡ fdd„}ntdƒ‚t||ƒ\}}|dk�r$t|ƒd }d}|}|}|�r<|g}||| |||ƒ}d}|j|
k�rˆz| |¡\}}W n$ tjjk
�r’   d}Y �qˆY nX ||ƒ}|| }||| |||ƒ}|j|j }|j| }|dk�rÜd}�qˆ|| }|dk �rø|d9 }n|dk�r|�rtd| |ƒ}||	k�r(|}|}|�r>| t |¡¡ |dk	�rV|t |¡ƒ |d7 }|j|
k �rrd}�qˆ||k�rPd}�qˆ�qPtd td ddf} |�r|dk�rºt| | ƒ nt | | td¡ td|j ƒ td| ƒ tdˆ j ƒ tdˆ j ƒ tdˆ j|d   ƒ t||dk||j|j ˆ jˆ jˆ j|d  || | d�
}!|dk	�rb|j
|!d< |�rp||!d< |!S )aÐ  
    Minimization of scalar function of one or more variables using a
    trust-region algorithm.

    Options for the trust-region algorithm are:
        initial_trust_radius : float
            Initial trust radius.
        max_trust_radius : float
            Never propose steps that are longer than this value.
        eta : float
            Trust region related acceptance stringency for proposed steps.
        gtol : float
            Gradient norm must be less than `gtol`
            before successful termination.
        maxiter : int
            Maximum number of iterations to perform.
        disp : bool
            If True, print convergence message.
        inexact : bool
            Accuracy to solve subproblems. If True requires less nonlinear
            iterations, but more vector products. Only effective for method
            trust-krylov.

    This function is called by the `minimize` function.
    It is not supposed to be called directly.
    Nz7Jacobian is currently required for trust-region methodsz_Either the Hessian or the Hessian-vector product is currently required for trust-region methodszBA subproblem solving strategy is required for trust-region methodsr   g      Ð?zinvalid acceptance stringencyz%the max trust radius must be positivez)the initial trust radius must be positivez?the initial trust radius must be less than the max trust radius)r$   r%   r   c                    s   ˆ   | ¡ |¡S r   )r%   r(   )r   r*   r   ©Úsfr   r   r&   ¿   s    z%_minimize_trust_region.<locals>.hesspéÈ   é   r1   g      è?r   ÚsuccessÚmaxiterz:A bad approximation caused failure to predict improvement.z3A linalg error occurred, such as a non-psd Hessian.z#         Current function value: %fz         Iterations: %dz!         Function evaluations: %dz!         Gradient evaluations: %dz          Hessian evaluations: %d)
r   rQ   Ústatusr#   r$   ÚnfevÚnjevÚnhevÚnitÚmessager%   Úallvecs)!r   Ú
ValueErrorÚ	Exceptionr	   ÚasarrayÚflattenr   r#   ÚgradÚcallabler%   r   Ú
isinstancer   r   Úlenr0   rC   r.   ÚLinAlgErrorÚminÚappendr
   r   ÚprintÚwarningsÚwarnÚRuntimeWarningrT   ÚngevrV   r   r$   )"r#   Úx0r   r$   r%   r&   Ú
subproblemZinitial_trust_radiusZmax_trust_radiusÚetaÚgtolrR   ÚdispÚ
return_allÚcallbackÚinexactÚunknown_optionsZnhesspÚwarnflagr:   r   rY   ÚmÚkr*   Úhits_boundaryZpredicted_valueZ
x_proposedZ
m_proposedZactual_reductionZpredicted_reductionÚrhoZstatus_messagesÚresultr   rM   r   Ú_minimize_trust_regionu   sÄ    







ü
    ý

ry   )r   NNNNrI   rJ   rK   rL   NFFNT)rG   r4   rf   Únumpyr	   Úscipy.linalgr-   Ú	_optimizer   r   r   r   Z'scipy.optimize._hessian_update_strategyr   Ú(scipy.optimize._differentiable_functionsr   Ú__all__r   r   ry   r   r   r   r   Ú<module>   s,   X                 ü