
    ^Mh-                         d Z ddlZddlmZmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZmZmZmZmZmZmZmZmZmZmZ d Zd	 Zd
 Zd ZdS )a	  
Dogleg algorithm with rectangular trust regions for least-squares minimization.

The description of the algorithm can be found in [Voglis]_. The algorithm does
trust-region iterations, but the shape of trust regions is rectangular as
opposed to conventional elliptical. The intersection of a trust region and
an initial feasible region is again some rectangle. Thus, on each iteration a
bound-constrained quadratic optimization problem is solved.

A quadratic problem is solved by well-known dogleg approach, where the
function is minimized along piecewise-linear "dogleg" path [NumOpt]_,
Chapter 4. If Jacobian is not rank-deficient then the function is decreasing
along this path, and optimization amounts to simply following along this
path as long as a point stays within the bounds. A constrained Cauchy step
(along the anti-gradient) is considered for safety in rank deficient cases,
in this situations the convergence might be slow.

If during iterations some variable hit the initial bound and the component
of anti-gradient points outside the feasible region, then a next dogleg step
won't make any progress. At this state such variables satisfy first-order
optimality conditions and they are excluded before computing a next dogleg
step.

Gauss-Newton step can be computed exactly by `numpy.linalg.lstsq` (for dense
Jacobian matrices) or by iterative procedure `scipy.sparse.linalg.lsmr` (for
dense and sparse matrices, or Jacobian being LinearOperator). The second
option allows to solve very large problems (up to couple of millions of
residuals on a regular PC), provided the Jacobian matrix is sufficiently
sparse. But note that dogbox is not very good for solving problems with
large number of constraints, because of variables exclusion-inclusion on each
iteration (a required number of function evaluations might be high or accuracy
of a solution will be poor), thus its large-scale usage is probably limited
to unconstrained problems.

References
----------
.. [Voglis] C. Voglis and I. E. Lagaris, "A Rectangular Trust Region Dogleg
            Approach for Unconstrained and Bound Constrained Nonlinear
            Optimization", WSEAS International Conference on Applied
            Mathematics, Corfu, Greece, 2004.
.. [NumOpt] J. Nocedal and S. J. Wright, "Numerical optimization, 2nd edition".
    N)lstsqnorm)LinearOperatoraslinearoperatorlsmr)OptimizeResult   )step_size_to_bound	in_boundsupdate_tr_radiusevaluate_quadraticbuild_quadratic_1dminimize_quadratic_1dcompute_gradcompute_jac_scalecheck_terminationscale_for_robust_loss_functionprint_header_nonlinearprint_iteration_nonlinearc                 l      j         \  }} fd} fd}t          ||f||t                    S )zCompute LinearOperator to use in LSMR by dogbox algorithm.

    `active_set` mask is used to excluded active variables from computations
    of matrix-vector products.
    c                     |                                                                  }d|<                       | z            S Nr   )ravelcopymatvec)xx_freeJop
active_setds     Z/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/scipy/optimize/_lsq/dogbox.pyr   zlsmr_operator.<locals>.matvec@   s:    !!zzz!a%       c                 B                         |           z  }d|<   |S r   )rmatvec)r   rr   r   r    s     r!   r$   zlsmr_operator.<locals>.rmatvecE   s%    A*r"   )r   r$   dtype)shaper   float)r   r    r   mnr   r$   s   ```    r!   lsmr_operatorr+   8   su     9DAq! ! ! ! ! ! !
      
 1a&NNNNr"   c                 &   || z
  }|| z
  }t          j        ||           }t          j        ||          }t          j        ||          }t          j        ||          }	t          j        ||           }
t          j        ||          }||||	|
|fS )a  Find intersection of trust-region bounds and initial bounds.

    Returns
    -------
    lb_total, ub_total : ndarray with shape of x
        Lower and upper bounds of the intersection region.
    orig_l, orig_u : ndarray of bool with shape of x
        True means that an original bound is taken as a corresponding bound
        in the intersection region.
    tr_l, tr_u : ndarray of bool with shape of x
        True means that a trust-region bound is taken as a corresponding bound
        in the intersection region.
    )npmaximumminimumequal)r   	tr_boundslbublb_centeredub_centeredlb_totalub_totalorig_lorig_utr_ltr_us               r!   find_intersectionr<   M   s     q&Kq&Kz+	z22Hz+y11HXh,,FXh,,F8Hyj))D8Hi((DXvvtT99r"   c                    t          | |||          \  }}	}
}}}t          j        | t                    }t	          |||	          r||dfS t          t          j        |           | ||	          \  }}t          ||d|          d          |z  }||z
  }t          ||||	          \  }}d||dk     |
z  <   d||dk    |z  <   t          j        |dk     |z  |dk    |z  z            }|||z  z   ||fS )a  Find dogleg step in a rectangular region.

    Returns
    -------
    step : ndarray, shape (n,)
        Computed dogleg step.
    bound_hits : ndarray of int, shape (n,)
        Each component shows whether a corresponding variable hits the
        initial bound after the step is taken:
            *  0 - a variable doesn't hit the bound.
            * -1 - lower bound is hit.
            *  1 - upper bound is hit.
    tr_hit : bool
        Whether the step hit the boundary of the trust-region.
    r&   Fr   r	   )r<   r-   
zeros_likeintr   r
   r   any)r   newton_stepgabr1   r2   r3   r6   r7   r8   r9   r:   r;   
bound_hits	to_bounds_cauchy_step	step_diff	step_sizehitstr_hits                         r!   dogleg_steprO   j   s/     6G	9b"6 62Hhd q,,,Jh11 .J--%bmA&6&6HhOOLIq )Aq)<<Q??!CKk)I(i)18= =OIt&(JqF"#&'JqF"#VTAX%T(99::FY..
FBBr"   c                 	   |}|                                 }d}|}d}|= ||          }dt          j        |d                   z  }t          |||          \  }}ndt          j        ||          z  }t          ||          }t          |t                    o|dk    }|rt          |          \  }}n|d|z  }}t          ||z  t          j
                  }|dk    rd}t          j        |t                    }d|t          j        ||          <   d|t          j        ||          <   |}t          j        |          }|

|j        d	z  }
d }d} d }!d }"|d
k    rt!                       	 ||z  dk     }#|# }$||$         }%|                                 }&d||#<   t          |t          j
                  }'|'|	k     rd}|d
k    rt#          | |||"|!|'           |||
k    rn||$         }(||$         })||$         }*||$         }+|dk    r;|d d |$f         },t%          |,| d          d         }-t'          |,|%|%           \  }.}/n[|dk    rUt)          |          }0t+          |0||#          }1t-          |1|fi |d         |$          }-|-|+z  }-t'          |0||           \  }.}/d}"|"dk    rh||
k     ra||+z  }2t/          |(|-|%|.|/|2|)|*          \  }3}4}5|                    d           |3||$<   |dk    rt3          |,|%|3           }6n|dk    rt3          |0||           }6t          j        ||z   ||          }7 | |7          }8|dz  }t          ||z  t          j
                  }9t          j        t          j        |8                    sd|9z  }| ||8d          }:ndt          j        |8|8          z  }:||:z
  }"t;          ||"|6|9|5          \  }};t          |          }!t=          |"||!t          |          |;||          }|n|"dk    r||
k     a|"dk    r|4||$<   |7}|dk    }<||<         ||<<   |dk    }<||<         ||<<   |8}|                                 }|:} |||          }|dz  }| ||          }t          |||          \  }}t          ||          }|rt          ||          \  }}nd}!d}"| dz  } K|d}t?          |||||&|'||||
  
        S )Nr	   g      ?r   jac)ordg      ?r>   r?   d      Texact)rcondr   g      g        g      ?)	cost_only)
r   costfunrQ   grad
optimalityactive_masknfevnjevstatus) r   r-   sumr   dotr   
isinstancestrr   r   infr@   rA   r0   
empty_likesizer   r   r   r   r   r+   r   rO   fillr   clipallisfiniter   r   r   )=rY   rQ   x0f0J0r2   r3   ftolxtolgtolmax_nfevx_scaleloss_function	tr_solver
tr_optionsverboseff_truer]   Jr^   rhorX   rD   	jac_scalescale	scale_invDeltaon_boundr   steptermination_status	iteration	step_normactual_reductionr   free_setg_freeg_fullg_normr   lb_freeub_free
scale_freeJ_freerC   rE   rF   r   lsmr_opr1   	step_freeon_bound_freerN   predicted_reductionx_newf_newstep_h_normcost_newratiomasks=                                                                r!   dogboxr      s   
AVVXXFD
AD mARVCF^^#-aC8811RVAq\\!QA7C((=W-=I 0,Q//yy"AKyiRV,,,Ezz}Rs+++H!#HRXb"!"HRXb"
A=D7S=II!||   A\A%
;8*aRV$$$D==!"a<<%it=M&/9 9 9 )TX-=-=8X,X,8_
 qqq({^F"555a8K &ffvg>>DAqq&  "1%%C $C
;;G99j99!<XFFK:%K &c1qb11DAq!##x
*I/:VQ9gw0P 0P,I}f IIcNNN&DNG##'9&&:C(E (E 'E##f$$'9#q$'G'G&G# GAHb"--ECJJEAIDti/RV<<<K6"+e,,-- {* ((=$???u!5!55#h+')<V LE5
 T

I!2 $	477E4"O "O "-Y !##x\ a!.HXAr>DhAdGq=DhAdGAVVXXFDAq		AAID(#mA&&5aC@@1Q""A C#4Q	#B#B yI Q	CAF !
$F64d;MO O O Or"   )__doc__numpyr-   numpy.linalgr   r   scipy.sparse.linalgr   r   r   scipy.optimizer   commonr
   r   r   r   r   r   r   r   r   r   r   r   r+   r<   rO   r    r"   r!   <module>r      sI  ) )T     $ $ $ $ $ $ $ $ F F F F F F F F F F ) ) ) ) ) )7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7O O O*: : ::(C (C (CVvO vO vO vO vOr"   