§
    µ³Ùg¢-  ã                   ó’   — 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 )z¬Compute 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     €€€úP/granary/edev/quantum/lib/python3.11/site-packages/scipy/optimize/_lsq/dogbox.pyr   zlsmr_operator.<locals>.matvec@   s:   ø€ Ø—’‘”—’Ñ!Ô!ˆØˆˆzÑØ�zŠz˜!˜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   øøø€ ð Œ9�D€A€qð!ð !ð !ð !ð !ð !ð !ð
ð ð ð ð ð ð õ
 ˜1˜a˜&¨¸ÍÐ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Ô2€HÝŒz˜+ yÑ1Ô1€HåŒX�h Ñ,Ô,€FÝŒX�h Ñ,Ô,€FåŒ8�H˜y˜jÑ)Ô)€DÝŒ8�H˜iÑ(Ô(€Dà�X˜v v¨t°TÐ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Ø	ˆ9�b˜"ñ6ô 6Ñ2€Hˆh˜ ¨¨dõ ”˜q­Ð,Ñ,Ô,€Jå�˜h¨Ñ1Ô1ð .Ø˜J¨Ð-Ð-å%¥b¤m°AÑ&6Ô&6¸¸¸HÀhÑOÔO�L€Iˆqõ )¨¨A¨q°)Ñ<Ô<¸QÔ?Ð?À!ÑC€Kà˜kÑ)€IÝ(¨°iØ)1°8ñ=ô =�O€Iˆtà&(€J��q’˜FÑ"Ñ#Ø&'€J��q’˜FÑ"Ñ#ÝŒV�T˜A’X Ñ%¨°ª°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Ø�VŠV‰XŒX€FØ€Dà
€AØ€DàÐ Øˆm˜AÑÔˆØ•R”V˜C œF‘^”^Ñ#ˆÝ-¨a°°CÑ8Ô8‰ˆˆ1ˆ1à•R”V˜A˜q‘\”\Ñ!ˆå�Q˜ÑÔ€Aå˜7¥CÑ(Ô(Ð=¨W¸Ò-=€IØð 0Ý,¨QÑ/Ô/Ñˆˆyˆyà" A¨¡Kˆyˆå��i‘¥R¤VÐ,Ñ,Ô,€EØ�‚z€zØˆåŒ}˜R¥sÐ+Ñ+Ô+€HØ!#€H�RŒX�b˜"ÑÔÑØ!"€H�RŒX�b˜"ÑÔÑà
€AÝŒ=˜ÑÔ€DàÐØ”7˜S‘=ˆàÐØ€IØ€IØÐà�!‚|€|ÝÑ Ô Ð ðAØ ‘\ AÒ%ˆ
Ø�;ˆà�8”ˆØ—’‘”ˆØˆˆ*‰å�a�RœVÐ$Ñ$Ô$ˆØ�DŠ=ˆ=Ø!"Ðà�aŠ<ˆ<Ý% i°°tÐ=MØ&/°ñ9ô 9ð 9ð Ð)¨T°XÒ-=Ð-=Ùà�8”ˆØ�X”,ˆØ�X”,ˆØ˜8”_ˆ
ð ˜ÒÐØ�q�q�q˜(�{”^ˆFÝ ¨¨°"Ð5Ñ5Ô5°aÔ8ˆKõ & f¨f°v°gÑ>Ô>‰DˆAˆqˆqØ˜&Ò Ð Ý" 1Ñ%Ô%ˆCõ $ C¨°
Ñ;Ô;ˆGÝ ¨Ð9Ð9¨jÐ9Ð9¸!Ô<¸XÔFÐFˆKØ˜:Ñ%ˆKõ & c¨1¨q¨bÑ1Ô1‰DˆAˆqàÐØ !Ò#Ñ#¨¨xª©Ø 
Ñ*ˆIå/:Ø˜ V¨Q°°9¸gÀwñ0Pô 0PÑ,ˆI�} fð �IŠI�c‰NŒNˆNØ&ˆD�‰Nà˜GÒ#Ð#Ý'9¸&À&Ø:Cñ(Eô (Eð 'EÐ#Ð#à˜fÒ$Ð$Ý'9¸#¸qÀ$Ñ'GÔ'GÐ&GÐ#õ ”G˜A ™H b¨"Ñ-Ô-ˆEà�C˜‘J”JˆEØ�A‰IˆDå˜t iÑ/µR´VÐ<Ñ<Ô<ˆKå”6�"œ+ eÑ,Ô,Ñ-Ô-ð Ø˜{Ñ*�Øð Ð(Ø(˜=¨¸$Ð?Ñ?Ô?��à¥¤¨¨uÑ!5Ô!5Ñ5�Ø# h™Ðå+ØÐ'Ð)<Ø˜Vñô ‰LˆE�5õ
 ˜T™
œ
ˆIÝ!2Ø  $¨	µ4¸±7´7¸EÀ4Èñ"Oô "OÐð "Ð-ØðY  !Ò#Ð#¨¨xª©ð\ ˜aÒÐØ!.ˆH�XÑàˆAà˜r’>ˆDØ˜”hˆAˆd‰GØ˜q’=ˆDØ˜”hˆAˆd‰GàˆAØ—V’V‘X”XˆFàˆDà��A�q‘	”	ˆAØ�A‰IˆDàÐ(Ø#�m AÑ&Ô&�Ý5°a¸¸CÑ@Ô@‘��1å˜Q Ñ"Ô"ˆAàð CÝ#4°Q¸	Ñ#BÔ#BÑ ��yøàˆIØ Ðà�Q‰ˆ	ñCAðF Ð!ØÐåØ
�$˜F¨°À6Ø 4¨dÐ;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"   