
    Џkh/                         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 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dZy)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)_call_callback_maybe_halt   )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                 r    | j                         j                         }d|<   j                  | z        S Nr   )ravelcopymatvec)xx_freeJop
active_setds     V/var/www/teggl/fontify/venv/lib/python3.12/site-packages/scipy/optimize/_lsq/dogbox.pyr   zlsmr_operator.<locals>.matvecB   s2    !zzz!a%      c                 :    j                  |       z  }d|<   |S r   )rmatvec)r   rr   r    r!   s     r"   r%   zlsmr_operator.<locals>.rmatvecG   s#    A*r#   )r   r%   dtype)shaper   float)r   r!   r    mnr   r%   s   ```    r"   lsmr_operatorr,   :   s3     99DAq!

 1a&NNr#   c                 2   || 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=   O   s     q&Kq&Kzz+	z2Hzz+y1HXXh,FXXh,F88Hyj)D88Hi(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kD  |z  <   t        j                  |dk  |z  |dkD  |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br2   r3   r4   r7   r8   r9   r:   r;   r<   
bound_hits	to_bounds_cauchy_step	step_diff	step_sizehitstr_hits                         r"   dogleg_steprP   l   s     6G	9b"62Hhd q,Jh1J--%bmmA&6HhOLIq )Aq)<Q??!CKk)I(i)18=OIt&(JqF"#&'JqF"#VVTAX%T(99:FY..
FBBr#   c                    |}|j                         }d}|}d}|4 ||      }dt        j                  |d         z  }t        |||      \  }}ndt        j                  ||      z  }t        ||      }t        |t              xr |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  }$|$ }%||%   }&|j                         }'d||$<   t        |t        j                        }(|(|	k  rd} |d
k(  rt#        |!|||#|"|(       | ||
k(  rn||%   })||%   }*||%   }+||%   },|dk(  r-|d d |%f   }-t%        |-| d      d   }.t'        |-|&|&       \  }/}0nG|dk(  rBt)        |      }1t+        |1||$      }2t-        |2|fi |d   |%    }.|.|,z  }.t'        |1||       \  }/}0d}#|#dk  rB||
k  r<||,z  }3t/        |).|&/0|3|*|+      \  }4}5}6|j1                  d       |4||%<   |dk(  rt3        -|&|4       }7n|dk(  rt3        1||       }7t        j4                  ||z   ||      }8 | |8      }9|dz  }t        ||z  t        j                        }:t        j6                  t        j8                  |9            sd|:z  }| ||9d      };ndt        j                  |9|9      z  };||;z
  }#t;        ||#7|:|6      \  }}<t        |      }"t=        |#||"t        |      |<||      } | n|#dk  r||
k  r<|#dkD  rz5||%<   8}|dk(  }=||=   ||=<   |dk(  }=||=   ||=<   9}|j                         };} ||      }|dz  }| ||      }t        |||      \  }}t        ||      }|rt        ||      \  }}nd}"d}#|!dz  }!|#t?        |||!|      }>;|>d<   tA        ||>      rd} n| d} t?        |||||'|(|||| 
      S )Nr
   g      ?r   jac)ordg      ?r?   r@   d      Texact)rcondr   g      g        g      ?)	cost_only)r   funnitnfevcost)
r   r\   rY   rR   grad
optimalityactive_maskr[   njevstatus)!r   r.   sumr   dotr   
isinstancestrr   r   infrA   rB   r1   
empty_likesizer   r   r   r   r   r,   r   rP   fillr   clipallisfiniter   r   r   r	   )?rY   rR   x0f0J0r3   r4   ftolxtolgtolmax_nfevx_scaleloss_function	tr_solver
tr_optionsverbosecallbackff_truer[   Jra   rhor\   rE   	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_freerD   rF   rG   r   lsmr_opr2   	step_freeon_bound_freerO   predicted_reductionx_newf_newstep_h_normcost_newratiomaskintermediate_results?                                                                  r"   dogboxr      s^   
AVVXFD
AD ARVVCF^#-aC81RVVAq\!QA7C(=W-=I,Q/y"AKyiRVV,Ez}}Rs+H!#HRXXb"!"HRXXb"
A==D77S=II!| 
\A%
;8*aRVV$D=!"a<%it=M&/9 )TX-=8X,X,8_
 q({^F"5a8K &ffvg>DAq& "1%C $C
;G9j9!<XFFK:%K &c1qb1DAq!#x
*I/:VQ9gw0P,I}f IIcN&DNG#'9&&:C(E 'E#f$'9#q$'G&G# GGAHb"-EJEAIDti/RVV<K66"++e,-{* (($?u!55#h+')<VLE5
 T
I!2 $	47E4"O "-Y !#x\ a!.HXAr>DhAdGq=DhAdGAVVXFDAAAID(#A&5aC@1Q"A#4Q	#B yI Q	 "0	#6*2'(- &("[ ^ !
$F64d;MO Or#   )N)__doc__numpyr.   numpy.linalgr   r   scipy.sparse.linalgr   r   r   scipy.optimizer   scipy._lib._utilr	   commonr   r   r   r   r   r   r   r   r   r   r   r   r,   r=   rP   r    r#   r"   <module>r      sS   )T  $ F F ) 67 7 7 7O*::(CX DHBOr#   