U
    »mœd›)  ã                   @   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)ÚxZwrapper_args©ÚargsÚfunctionZncalls© úT/home/sam/Atlas/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_magZ_cauchy_pointZ_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ÚlinalgZ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_discriminantZ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   r5   r   r   r   Úsolvep   s    zBaseQuadraticSubproblem.solve)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r'   Úpropertyr   r    r!   r"   r+   r;   r=   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   ©Zsfr   r   r"   ¿   s    z%_minimize_trust_region.<locals>.hesspéÈ   é   r,   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   rJ   Ústatusr   r    ÚnfevZnjevÚnhevÚnitÚmessager!   Úallvecs)!r   Ú
ValueErrorÚ	Exceptionr	   ZasarrayÚflattenr   r   ZgradÚcallabler!   r   Ú
isinstancer   r   Úlenr+   r=   r*   ZLinAlgErrorÚminÚappendr
   r   ÚprintÚwarningsÚwarnÚRuntimeWarningrM   ZngevrN   r   r    )"r   Zx0r   r    r!   r"   Z
subproblemZinitial_trust_radiusZmax_trust_radiusÚetaZgtolrK   ZdispZ
return_allÚcallbackZinexactZunknown_optionsZnhesspZwarnflagr5   r   rQ   ÚmÚkr&   Zhits_boundaryZpredicted_valueZ
x_proposedZ
m_proposedZactual_reductionZpredicted_reductionÚrhoZstatus_messagesÚresultr   rG   r   Ú_minimize_trust_regionu   sÄ    







ü
    ý

rd   )r   NNNNrC   rD   rE   rF   NFFNT)rA   r/   r[   Únumpyr	   Zscipy.linalgr)   Ú	_optimizer   r   r   r   Z'scipy.optimize._hessian_update_strategyr   Z(scipy.optimize._differentiable_functionsr   Ú__all__r   r   rd   r   r   r   r   Ú<module>   s,   X                 ü