o
    èEbˆP  ã                   @   sJ  d Z ddlmZ ddlZddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZ e e¡jZdd	„ Z		d@dd„Zdd„ Zdd„ ZdAdd„ZdBdd„ZdCdd„Zdd„ Zdd„ ZdDdd„ZdDdd „Zd!d"„ Zd#d$„ Z d%d&„ Z!d'd(„ Z"d)d*„ Z#d+d,„ Z$d-d.„ Z%dCd/d0„Z&d1d2„ Z'd3d4„ Z(d5d6„ Z)dEd8d9„Z*dEd:d;„Z+d<d=„ Z,d>d?„ Z-dS )Fz+Functions used by least-squares algorithms.é    )ÚcopysignN)Únorm)Ú
cho_factorÚ	cho_solveÚLinAlgError)Úissparse)ÚLinearOperatorÚaslinearoperatorc           
      C   sš   t  ||¡}|dkrtdƒ‚t  | |¡}t  | | ¡|d  }|dkr&tdƒ‚t  || ||  ¡}|t||ƒ  }|| }|| }	||	k rI||	fS |	|fS )aq  Find the intersection of a line with the boundary of a trust region.

    This function solves the quadratic equation with respect to t
    ||(x + s*t)||**2 = Delta**2.

    Returns
    -------
    t_neg, t_pos : tuple of float
        Negative and positive roots.

    Raises
    ------
    ValueError
        If `s` is zero or `x` is not within the trust region.
    r   z`s` is zero.é   z#`x` is not within the trust region.)ÚnpÚdotÚ
ValueErrorZsqrtr   )
ÚxÚsÚDeltaÚaÚbÚcÚdÚqÚt1Út2© r   ú</usr/lib/python3/dist-packages/scipy/optimize/_lsq/common.pyÚintersect_trust_region   s   r   ç{®Gáz„?é
   c	                 C   sŽ  dd„ }	|| }
|| krt | |d  }|d |k}nd}|r2| || ¡ }t|ƒ|kr2|ddfS t|
ƒ| }|rI|	d|
||ƒ\}}| | }nd}|du sU|sa|dkratd| || d	 ƒ}n|}t|ƒD ]D}||k sq||kr|td| || d	 ƒ}|	||
||ƒ\}}|dk r‹|}|| }t||| ƒ}||| | | 8 }t |¡|| k r« nqg| |
|d
 |  ¡ }||t|ƒ 9 }|||d fS )aÁ  Solve a trust-region problem arising in least-squares minimization.

    This function implements a method described by J. J. More [1]_ and used
    in MINPACK, but it relies on a single SVD of Jacobian instead of series
    of Cholesky decompositions. Before running this function, compute:
    ``U, s, VT = svd(J, full_matrices=False)``.

    Parameters
    ----------
    n : int
        Number of variables.
    m : int
        Number of residuals.
    uf : ndarray
        Computed as U.T.dot(f).
    s : ndarray
        Singular values of J.
    V : ndarray
        Transpose of VT.
    Delta : float
        Radius of a trust region.
    initial_alpha : float, optional
        Initial guess for alpha, which might be available from a previous
        iteration. If None, determined automatically.
    rtol : float, optional
        Stopping tolerance for the root-finding procedure. Namely, the
        solution ``p`` will satisfy ``abs(norm(p) - Delta) < rtol * Delta``.
    max_iter : int, optional
        Maximum allowed number of iterations for the root-finding procedure.

    Returns
    -------
    p : ndarray, shape (n,)
        Found solution of a trust-region problem.
    alpha : float
        Positive value such that (J.T*J + alpha*I)*p = -J.T*f.
        Sometimes called Levenberg-Marquardt parameter.
    n_iter : int
        Number of iterations made by root-finding procedure. Zero means
        that Gauss-Newton step was selected as the solution.

    References
    ----------
    .. [1] More, J. J., "The Levenberg-Marquardt Algorithm: Implementation
           and Theory," Numerical Analysis, ed. G. A. Watson, Lecture Notes
           in Mathematics 630, Springer Verlag, pp. 105-116, 1977.
    c                 S   sD   |d |  }t || ƒ}|| }t |d |d  ¡ | }||fS )z Function of which to find zero.

        It is defined as "norm of regularized (by alpha) least-squares
        solution minus `Delta`". Refer to [1]_.
        r
   é   )r   r   Úsum)ÚalphaÚsufr   r   ZdenomZp_normÚphiÚ	phi_primer   r   r   Úphi_and_derivativej   s
   z2solve_lsq_trust_region.<locals>.phi_and_derivativer   éÿÿÿÿFg        Ngü©ñÒMbP?ç      à?r
   é   )ÚEPSr   r   ÚmaxÚranger   Úabs)ÚnÚmZufr   ÚVr   Zinitial_alphaÚrtolZmax_iterr#   r    Z	thresholdZ	full_rankÚpZalpha_upperr!   r"   Zalpha_lowerr   ÚitÚratior   r   r   Úsolve_lsq_trust_region9   sB   1
ÿr2   c                 C   sv  zt | ƒ\}}t||f|ƒ }t ||¡|d kr|dfW S W n	 ty(   Y nw | d |d  }| d |d  }| d |d  }|d | }	|d | }
t | |	 d|| |
  d| d| | |
  | |	 g¡}t |¡}t |t |¡ ¡}|t 	d| d|d   d|d  d|d   f¡ }d	tj
||  |¡ dd
 t ||¡ }t |¡}|dd…|f }|dfS )az  Solve a general trust-region problem in 2 dimensions.

    The problem is reformulated as a 4th order algebraic equation,
    the solution of which is found by numpy.roots.

    Parameters
    ----------
    B : ndarray, shape (2, 2)
        Symmetric matrix, defines a quadratic term of the function.
    g : ndarray, shape (2,)
        Defines a linear term of the function.
    Delta : float
        Radius of a trust region.

    Returns
    -------
    p : ndarray, shape (2,)
        Found solution.
    newton_step : bool
        Whether the returned solution is the Newton step which lies within
        the trust region.
    r
   T)r   r   )r   r&   )r&   r&   r   r&   é   r%   ©ZaxisNF)r   r   r   r   r   ZarrayÚrootsÚrealZisrealZvstackr   Úargmin)ÚBÚgr   ÚRÚlowerr/   r   r   r   r   ÚfZcoeffsÚtÚvalueÚir   r   r   Úsolve_trust_region_2d«   s0   
ÿÿ6ÿ
6(
r@   c                 C   sh   |dkr	|| }n||  krdkrn nd}nd}|dk r&d| } | |fS |dkr0|r0| d9 } | |fS )zÍUpdate the radius of a trust region based on the cost reduction.

    Returns
    -------
    Delta : float
        New radius.
    ratio : float
        Ratio between actual and predicted reductions.
    r   r&   ç      Ð?g      è?g       @r   )r   Zactual_reductionZpredicted_reductionÚ	step_normZ	bound_hitr1   r   r   r   Úupdate_tr_radiusÞ   s   
ýrC   c           
      C   sÊ   |   |¡}t  ||¡}|dur|t  || |¡7 }|d9 }t  ||¡}|dura|   |¡}|t  ||¡7 }dt  ||¡ t  ||¡ }	|dur\|t  || |¡7 }|	dt  || |¡ 7 }	|||	fS ||fS )a²  Parameterize a multivariate quadratic function along a line.

    The resulting univariate quadratic function is given as follows:
    ::
        f(t) = 0.5 * (s0 + s*t).T * (J.T*J + diag) * (s0 + s*t) +
               g.T * (s0 + s*t)

    Parameters
    ----------
    J : ndarray, sparse matrix or LinearOperator shape (m, n)
        Jacobian matrix, affects the quadratic term.
    g : ndarray, shape (n,)
        Gradient, defines the linear term.
    s : ndarray, shape (n,)
        Direction vector of a line.
    diag : None or ndarray with shape (n,), optional
        Addition diagonal part, affects the quadratic term.
        If None, assumed to be 0.
    s0 : None or ndarray with shape (n,), optional
        Initial point. If None, assumed to be 0.

    Returns
    -------
    a : float
        Coefficient for t**2.
    b : float
        Coefficient for t.
    c : float
        Free term. Returned only if `s0` is provided.
    Nr%   )r   r   )
ÚJr9   r   ÚdiagZs0Úvr   r   Úur   r   r   r   Úbuild_quadratic_1dû   s   


rH   c           	      C   sv   ||g}| dkrd| |  }||  k r|k rn n|  |¡ t |¡}|| | |  | }t |¡}|| || fS )zÛMinimize a 1-D quadratic function subject to bounds.

    The free term `c` is 0 by default. Bounds must be finite.

    Returns
    -------
    t : float
        Minimum point.
    y : float
        Minimum value.
    r   g      à¿)Úappendr   Úasarrayr7   )	r   r   ÚlbÚubr   r=   ZextremumÚyZ	min_indexr   r   r   Úminimize_quadratic_1d.  s   


rN   c                 C   s–   |j dkr|  |¡}t ||¡}|dur|t || |¡7 }n |  |j¡}tj|d dd}|dur?|tj||d  dd7 }t ||¡}d| | S )aì  Compute values of a quadratic function arising in least squares.

    The function is 0.5 * s.T * (J.T * J + diag) * s + g.T * s.

    Parameters
    ----------
    J : ndarray, sparse matrix or LinearOperator, shape (m, n)
        Jacobian matrix, affects the quadratic term.
    g : ndarray, shape (n,)
        Gradient, defines the linear term.
    s : ndarray, shape (k, n) or (n,)
        Array containing steps as rows.
    diag : ndarray, shape (n,), optional
        Addition diagonal part, affects the quadratic term.
        If None, assumed to be 0.

    Returns
    -------
    values : ndarray with shape (k,) or float
        Values of the function. If `s` was 2-D, then ndarray is
        returned, otherwise, float is returned.
    r&   Nr
   r   r4   r%   )Úndimr   r   ÚTr   )rD   r9   r   rE   ZJsr   Úlr   r   r   Úevaluate_quadraticE  s   

€rR   c                 C   s   t  | |k| |k@ ¡S )z$Check if a point lies within bounds.)r   Úall)r   rK   rL   r   r   r   Ú	in_boundso  s   rT   c                 C   s¦   t  |¡}|| }t  | ¡}| t j¡ t jdd t  ||  | | ||  | | ¡||< W d  ƒ n1 s9w   Y  t  |¡}|t  ||¡t  	|¡ 
t¡ fS )að  Compute a min_step size required to reach a bound.

    The function computes a positive scalar t, such that x + s * t is on
    the bound.

    Returns
    -------
    step : float
        Computed step. Non-negative value.
    hits : ndarray of int with shape of x
        Each element indicates whether a corresponding variable reaches the
        bound:

             *  0 - the bound was not hit.
             * -1 - the lower bound was hit.
             *  1 - the upper bound was hit.
    Úignore)ZoverN)r   ZnonzeroZ
empty_likeÚfillÚinfZerrstateÚmaximumÚminÚequalÚsignZastypeÚint)r   r   rK   rL   Znon_zeroZ
s_non_zeroZstepsZmin_stepr   r   r   Ústep_size_to_boundt  s   


ÿÿ
 r]   ç»½×Ùß|Û=c                 C   s¶   t j| td}|dkrd|| |k< d|| |k< |S | | }||  }|t  dt  |¡¡ }|t  dt  |¡¡ }t  |¡|t  ||¡k@ }	d||	< t  |¡|t  ||¡k@ }
d||
< |S )a·  Determine which constraints are active in a given point.

    The threshold is computed using `rtol` and the absolute value of the
    closest bound.

    Returns
    -------
    active : ndarray of int with shape of x
        Each component shows whether the corresponding constraint is active:

             *  0 - a constraint is not active.
             * -1 - a lower bound is active.
             *  1 - a upper bound is active.
    ©Zdtyper   r$   r&   )r   Ú
zeros_liker\   rX   r*   ÚisfiniteÚminimum)r   rK   rL   r.   ÚactiveZ
lower_distZ
upper_distZlower_thresholdZupper_thresholdZlower_activeZupper_activer   r   r   Úfind_active_constraints‘  s$   ÿÿrd   c           	   	   C   sà   |   ¡ }t| |||ƒ}t |d¡}t |d¡}|dkr4t || || ¡||< t || || ¡||< n&|| |t dt || ¡¡  ||< || |t dt || ¡¡  ||< ||k ||kB }d|| ||   ||< |S )zÔShift a point to the interior of a feasible region.

    Each element of the returned vector is at least at a relative distance
    `rstep` from the closest bound. If ``rstep=0`` then `np.nextafter` is used.
    r$   r&   r   r%   )Úcopyrd   r   rZ   Z	nextafterrX   r*   )	r   rK   rL   ZrstepZx_newrc   Z
lower_maskZ
upper_maskZtight_boundsr   r   r   Úmake_strictly_feasible¸  s    ÿÿrf   c                 C   sx   t  | ¡}t  | ¡}|dk t  |¡@ }|| | |  ||< d||< |dkt  |¡@ }| | ||  ||< d||< ||fS )a9  Compute Coleman-Li scaling vector and its derivatives.

    Components of a vector v are defined as follows:
    ::
               | ub[i] - x[i], if g[i] < 0 and ub[i] < np.inf
        v[i] = | x[i] - lb[i], if g[i] > 0 and lb[i] > -np.inf
               | 1,           otherwise

    According to this definition v[i] >= 0 for all i. It differs from the
    definition in paper [1]_ (eq. (2.2)), where the absolute value of v is
    used. Both definitions are equivalent down the line.
    Derivatives of v with respect to x take value 1, -1 or 0 depending on a
    case.

    Returns
    -------
    v : ndarray with shape of x
        Scaling vector.
    dv : ndarray with shape of x
        Derivatives of v[i] with respect to x[i], diagonal elements of v's
        Jacobian.

    References
    ----------
    .. [1] M.A. Branch, T.F. Coleman, and Y. Li, "A Subspace, Interior,
           and Conjugate Gradient Method for Large-Scale Bound-Constrained
           Minimization Problems," SIAM Journal on Scientific Computing,
           Vol. 21, Number 1, pp 1-23, 1999.
    r   r$   r&   )r   Ú	ones_liker`   ra   )r   r9   rK   rL   rF   ZdvÚmaskr   r   r   ÚCL_scaling_vectorÓ  s   

ri   c                 C   sF  t | ||ƒr| t | ¡fS t |¡}t |¡}|  ¡ }tj| td}|| @ }t | | d||  | |  ¡||< | | || k ||< | |@ }t | | d||  | |  ¡||< | | || k||< ||@ }|| }t 	| | ||  d||  ¡}	|| t |	d||  |	 ¡ ||< |	|| k||< t | ¡}
d|
|< ||
fS )z3Compute reflective transformation and its gradient.r_   r
   r$   )
rT   r   rg   ra   re   r`   ÚboolrX   rb   Z	remainder)rM   rK   rL   Z	lb_finiteZ	ub_finiter   Z
g_negativerh   r   r=   r9   r   r   r   Úreflective_transformationÿ  s(   


$
$ $
rk   c                	   C   s   t d dddddd¡ƒ d S )Nz*{0:^15}{1:^15}{2:^15}{3:^15}{4:^15}{5:^15}Ú	Iterationz
Total nfevÚCostúCost reductionú	Step normÚ
Optimality©ÚprintÚformatr   r   r   r   Úprint_header_nonlinear!  s
   
ÿÿrt   c              	   C   sL   |d u rd}nd  |¡}|d u rd}nd  |¡}td  | |||||¡ƒ d S )Nú               ú
{0:^15.2e}z({0:^15}{1:^15}{2:^15.4e}{3}{4}{5:^15.2e}©rs   rr   )Ú	iterationZnfevÚcostÚcost_reductionrB   Ú
optimalityr   r   r   Úprint_iteration_nonlinear'  s   


ÿÿr|   c                   C   s   t d ddddd¡ƒ d S )Nz#{0:^15}{1:^15}{2:^15}{3:^15}{4:^15}rl   rm   rn   ro   rp   rq   r   r   r   r   Úprint_header_linear8  s
   
ÿÿr}   c                 C   sJ   |d u rd}nd  |¡}|d u rd}nd  |¡}td  | ||||¡ƒ d S )Nru   rv   z!{0:^15}{1:^15.4e}{2}{3}{4:^15.2e}rw   )rx   ry   rz   rB   r{   r   r   r   Úprint_iteration_linear>  s   



ÿr~   c                 C   s    t | tƒr
|  |¡S | j |¡S )z4Compute gradient of the least-squares cost function.)Ú
isinstancer   ÚrmatvecrP   r   )rD   r<   r   r   r   Úcompute_gradQ  s   

r   c                 C   sn   t | ƒrt |  d¡jdd¡ ¡ d }ntj| d ddd }|du r+d||dk< nt ||¡}d| |fS )z5Compute variables scale based on the Jacobian matrix.r
   r   r4   r%   Nr&   )r   r   rJ   Zpowerr   ÚravelrX   )rD   Zscale_inv_oldZ	scale_invr   r   r   Úcompute_jac_scaleY  s   "rƒ   c                    óD   t ˆ ƒ‰ ‡ ‡fdd„}‡ ‡fdd„}‡ ‡fdd„}tˆ j|||dS )z#Return diag(d) J as LinearOperator.c                    ó   ˆˆ   | ¡ S ©N)Úmatvec©r   ©rD   r   r   r   r‡   l  ó   z(left_multiplied_operator.<locals>.matvecc                    s   ˆd d …t jf ˆ  | ¡ S r†   )r   ÚnewaxisÚmatmat©ÚXr‰   r   r   rŒ   o  ó   z(left_multiplied_operator.<locals>.matmatc                    s   ˆ   |  ¡ ˆ ¡S r†   )r€   r‚   rˆ   r‰   r   r   r€   r  s   z)left_multiplied_operator.<locals>.rmatvec©r‡   rŒ   r€   ©r	   r   Úshape©rD   r   r‡   rŒ   r€   r   r‰   r   Úleft_multiplied_operatorh  ó   
ÿr”   c                    r„   )z#Return J diag(d) as LinearOperator.c                    s   ˆ   t | ¡ˆ ¡S r†   )r‡   r   r‚   rˆ   r‰   r   r   r‡   }  s   z)right_multiplied_operator.<locals>.matvecc                    s   ˆ   | ˆd d …tjf  ¡S r†   )rŒ   r   r‹   r   r‰   r   r   rŒ   €  r   z)right_multiplied_operator.<locals>.matmatc                    r…   r†   ©r€   rˆ   r‰   r   r   r€   ƒ  rŠ   z*right_multiplied_operator.<locals>.rmatvecr   r‘   r“   r   r‰   r   Úright_multiplied_operatory  r•   r—   c                    sF   t ˆ ƒ‰ ˆ j\‰}‡ ‡fdd„}‡ ‡‡fdd„}tˆ| |f||dS )zµReturn a matrix arising in regularized least squares as LinearOperator.

    The matrix is
        [ J ]
        [ D ]
    where D is diagonal matrix with elements from `diag`.
    c                    s   t  ˆ  | ¡ˆ|  f¡S r†   )r   Zhstackr‡   rˆ   )rD   rE   r   r   r‡   •  s   z(regularized_lsq_operator.<locals>.matvecc                    s*   | d ˆ… }| ˆd … }ˆ   |¡ˆ|  S r†   r–   )r   Zx1Zx2©rD   rE   r,   r   r   r€   ˜  s   z)regularized_lsq_operator.<locals>.rmatvec)r‡   r€   )r	   r’   r   )rD   rE   r+   r‡   r€   r   r˜   r   Úregularized_lsq_operatorŠ  s
   
r™   Tc                 C   s`   |rt | tƒs|  ¡ } t| ƒr|  j|j| jdd9  _| S t | tƒr*t| |ƒ} | S | |9 } | S )zhCompute J diag(d).

    If `copy` is False, `J` is modified in place (unless being LinearOperator).
    Zclip)Úmode)r   r   re   r   ÚdataZtakeÚindicesr—   ©rD   r   re   r   r   r   Úright_multiply   s   
û
þrž   c                 C   sr   |rt | tƒs|  ¡ } t| ƒr |  jt |t | j¡¡9  _| S t | tƒr,t	| |ƒ} | S | |dd…tj
f 9 } | S )zhCompute diag(d) J.

    If `copy` is False, `J` is modified in place (unless being LinearOperator).
    N)r   r   re   r   r›   r   ÚrepeatZdiffZindptrr”   r‹   r   r   r   r   Úleft_multiply²  s   
û
þr    c           	      C   sD   | || k o	|dk}||||  k }|r|rdS |rdS |r dS dS )z8Check termination condition for nonlinear least squares.rA   é   r
   r   Nr   )	ZdFÚFZdx_normZx_normr1   ZftolZxtolZftol_satisfiedZxtol_satisfiedr   r   r   Úcheck_terminationÄ  s   r£   c                 C   sR   |d d|d  |d   }t ||t k < |dC }||d | 9 }t| |dd|fS )z`Scale Jacobian and residuals for a robust loss function.

    Arrays are modified in place.
    r&   r
   r%   F)re   )r'   r    )rD   r<   ZrhoZJ_scaler   r   r   Úscale_for_robust_loss_functionÓ  s
   r¤   )Nr   r   )NN)r   r†   )r^   )T).Ú__doc__Zmathr   Znumpyr   Znumpy.linalgr   Zscipy.linalgr   r   r   Zscipy.sparser   Zscipy.sparse.linalgr   r	   ZfinfoÚfloatZepsr'   r   r2   r@   rC   rH   rN   rR   rT   r]   rd   rf   ri   rk   rt   r|   r}   r~   r   rƒ   r”   r—   r™   rž   r    r£   r¤   r   r   r   r   Ú<module>   sH    '
ÿr3

3
*

',"


