o
    ?Hh]D                     @   s   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 ddlmZmZ d	Zd
ZdZdZdd Zdd Zdd ZG dd deZ G dd deZ!dS )    N)	lu_factorlu_solve)issparse
csc_matrixeye)splu)group_columns   )validate_max_stepvalidate_tolselect_initial_stepnormEPSnum_jacvalidate_first_stepwarn_extraneous)	OdeSolverDenseOutput      g?
   c                 C   s|   t d| d dddf }t d| d }t | d | d f}|d ||  | |ddddf< d|d< t j|ddS )z6Compute the matrix for changing the differences array.r	   Nr   axis)nparangezeroscumprod)orderfactorIJM r"   X/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/scipy/integrate/_ivp/bdf.py	compute_R   s   $r$   c                 C   sH   t ||}t |d}||}t|j| d|d  | d|d < dS )z<Change differences array in-place when step size is changed.r	   N)r$   dotr   T)Dr   r   RURUr"   r"   r#   change_D   s   


*r+   c	                 C   s   d}	|  }
d}d}ttD ]e}| ||
}tt|s nU|||| | |	 }t|| }|du r7d}n|| }|durS|dksQ|t|  d|  | |krS n!|
|7 }
|	|7 }	|dksm|durq|d|  | |k rqd} n|}q||d |
|	fS )z5Solve the algebraic system resulting from BDF method.r   NFr	   T)copyrangeNEWTON_MAXITERr   allisfiniter   )funt_new	y_predictcpsiLUsolve_luscaletoldydy_norm_old	convergedkfdydy_normrater"   r"   r#   solve_bdf_system$   s0   
rC   c                       sJ   e Zd ZdZejddddddf fdd	Zdd	 Zd
d Zdd Z	  Z
S )BDFa  Implicit method based on backward-differentiation formulas.

    This is a variable order method with the order varying automatically from
    1 to 5. The general framework of the BDF algorithm is described in [1]_.
    This class implements a quasi-constant step size as explained in [2]_.
    The error estimation strategy for the constant-step BDF is derived in [3]_.
    An accuracy enhancement using modified formulas (NDF) [2]_ is also implemented.

    Can be applied in the complex domain.

    Parameters
    ----------
    fun : callable
        Right-hand side of the system: the time derivative of the state ``y``
        at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
        scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
        return an array of the same shape as ``y``. See `vectorized` for more
        information.
    t0 : float
        Initial time.
    y0 : array_like, shape (n,)
        Initial state.
    t_bound : float
        Boundary time - the integration won't continue beyond it. It also
        determines the direction of the integration.
    first_step : float or None, optional
        Initial step size. Default is ``None`` which means that the algorithm
        should choose.
    max_step : float, optional
        Maximum allowed step size. Default is np.inf, i.e., the step size is not
        bounded and determined solely by the solver.
    rtol, atol : float and array_like, optional
        Relative and absolute tolerances. The solver keeps the local error
        estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
        relative accuracy (number of correct digits), while `atol` controls
        absolute accuracy (number of correct decimal places). To achieve the
        desired `rtol`, set `atol` to be smaller than the smallest value that
        can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
        allowable error. If `atol` is larger than ``rtol * abs(y)`` the
        number of correct digits is not guaranteed. Conversely, to achieve the
        desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
        than `atol`. If components of y have different scales, it might be
        beneficial to set different `atol` values for different components by
        passing array_like with shape (n,) for `atol`. Default values are
        1e-3 for `rtol` and 1e-6 for `atol`.
    jac : {None, array_like, sparse_matrix, callable}, optional
        Jacobian matrix of the right-hand side of the system with respect to y,
        required by this method. The Jacobian matrix has shape (n, n) and its
        element (i, j) is equal to ``d f_i / d y_j``.
        There are three ways to define the Jacobian:

            * If array_like or sparse_matrix, the Jacobian is assumed to
              be constant.
            * If callable, the Jacobian is assumed to depend on both
              t and y; it will be called as ``jac(t, y)`` as necessary.
              For the 'Radau' and 'BDF' methods, the return value might be a
              sparse matrix.
            * If None (default), the Jacobian will be approximated by
              finite differences.

        It is generally recommended to provide the Jacobian rather than
        relying on a finite-difference approximation.
    jac_sparsity : {None, array_like, sparse matrix}, optional
        Defines a sparsity structure of the Jacobian matrix for a
        finite-difference approximation. Its shape must be (n, n). This argument
        is ignored if `jac` is not `None`. If the Jacobian has only few non-zero
        elements in *each* row, providing the sparsity structure will greatly
        speed up the computations [4]_. A zero entry means that a corresponding
        element in the Jacobian is always zero. If None (default), the Jacobian
        is assumed to be dense.
    vectorized : bool, optional
        Whether `fun` can be called in a vectorized fashion. Default is False.

        If ``vectorized`` is False, `fun` will always be called with ``y`` of
        shape ``(n,)``, where ``n = len(y0)``.

        If ``vectorized`` is True, `fun` may be called with ``y`` of shape
        ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
        such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
        the returned array is the time derivative of the state corresponding
        with a column of ``y``).

        Setting ``vectorized=True`` allows for faster finite difference
        approximation of the Jacobian by this method, but may result in slower
        execution overall in some circumstances (e.g. small ``len(y0)``).

    Attributes
    ----------
    n : int
        Number of equations.
    status : string
        Current status of the solver: 'running', 'finished' or 'failed'.
    t_bound : float
        Boundary time.
    direction : float
        Integration direction: +1 or -1.
    t : float
        Current time.
    y : ndarray
        Current state.
    t_old : float
        Previous time. None if no steps were made yet.
    step_size : float
        Size of the last successful step. None if no steps were made yet.
    nfev : int
        Number of evaluations of the right-hand side.
    njev : int
        Number of evaluations of the Jacobian.
    nlu : int
        Number of LU decompositions.

    References
    ----------
    .. [1] G. D. Byrne, A. C. Hindmarsh, "A Polyalgorithm for the Numerical
           Solution of Ordinary Differential Equations", ACM Transactions on
           Mathematical Software, Vol. 1, No. 1, pp. 71-96, March 1975.
    .. [2] L. F. Shampine, M. W. Reichelt, "THE MATLAB ODE SUITE", SIAM J. SCI.
           COMPUTE., Vol. 18, No. 1, pp. 1-22, January 1997.
    .. [3] E. Hairer, G. Wanner, "Solving Ordinary Differential Equations I:
           Nonstiff Problems", Sec. III.2.
    .. [4] A. Curtis, M. J. D. Powell, and J. Reid, "On the estimation of
           sparse Jacobian matrices", Journal of the Institute of Mathematics
           and its Applications, 13, pp. 117-120, 1974.
    gMbP?gư>NFc                    s  t | t j|||||
dd t| _t|| j\ _ _ 	 j
 j}|d u rAt j	 j
 j||| jd j j
 _nt||| _d  _d  _tdt | td|d  _d  _ ||	\ _ _t jr fdd}d	d
 }t jd jjd}n fdd}dd
 }tj j jjd}| _| _ | _!t"g d}t#dt$dt%dt&d  f _'d|  j'  _(| j' dt%dt&d    _)tj*t&d  jf jjd} j|d< | j  j |d< | _+d _,d _-d  _.d S )NT)support_complexr	   r   gQ?      ?c                    s     j d7  _ t| S Nr	   )nlur   Aselfr"   r#   lu   s   zBDF.__init__.<locals>.luc                 S   s
   |  |S )N)solver6   br"   r"   r#   r7      s   
zBDF.__init__.<locals>.solve_lucsc)formatdtypec                    s     j d7  _ t| ddS )Nr	   T)overwrite_a)rH   r   rI   rK   r"   r#   rM      s   c                 S   s   t | |ddS )NT)overwrite_b)r   rO   r"   r"   r#   r7      s   rS   )r   gGzǿgqqgugsh|?r   r         )/r   super__init__r
   max_stepr   nrtolatolr1   tr;   r   	directionh_absr   	h_abs_olderror_norm_oldmaxr   min
newton_tol
jac_factor_validate_jacjacr    r   r   rS   r   identityrM   r7   r   arrayhstackcumsumr   	MAX_ORDERgammaalphaerror_constemptyr'   r   n_equal_stepsr6   )rL   r1   t0y0t_boundr[   r]   r^   ri   jac_sparsity
vectorized
first_step
extraneousr?   rM   r7   r   kappar'   	__class__rK   r#   rZ      sP   

& 

zBDF.__init__c                    sd  j }j d u r.d urtrtt}|ffdd}||}||fS t r |} jd7  _t|rRt|jd} fdd}ntj	|jd} fdd}|j
jjfkr{tdjjf d|j
 d	||fS t rt jd}ntj	 jd}|j
jjfkrtdjjf d|j
 d	d }||fS )
Nc                    s>     j d7  _  | |}t j| || j j\} _|S rG   )njev
fun_singler   fun_vectorizedr^   rg   )r_   r;   r?   r    )rL   sparsityr"   r#   jac_wrapped  s   
z&BDF._validate_jac.<locals>.jac_wrappedr	   rV   c                    s"    j d7  _ t | |jdS Nr	   rV   )r~   r   rS   r_   r;   ri   rL   ru   r"   r#   r     s   c                    s$    j d7  _ tj | |jdS r   )r~   r   asarrayrS   r   r   r"   r#   r      s   z `jac` is expected to have shape z, but actually has .)r_   r;   r   r   r   callabler~   rS   r   r   shaper\   
ValueError)rL   ri   r   rt   groupsr   r    r"   )ri   rL   r   ru   r#   rh     sB   



zBDF._validate_jacc           &   
   C   s  | j }| j}| j}dtt|| jtj |  }| j|kr/|}t	|| j
|| j  d| _n| j|k rD|}t	|| j
|| j  d| _n| j}| j}| j}| j
}| j}	| j}
| j}| j}| j}| jd u }d}|sk||k rrd| jfS || j }|| }| j|| j  dkr| j}t	||t|| |  d| _d }|| }t|}tj|d |d  dd}||t|  }t|d|d  j|
d|d  |	|  }d}||	|  }|s|d u r| | j||  }t| j|||||| j|| j	\}}}}|s|rn| ||}d }d}|r|s$d}||9 }t	||| d| _d }qfdd	t d  d	t |  }||t|  }|| | }t || }|dkrgt!t"||d
|d    }||9 }t	||| d| _nd}|ri|  jd7  _|| _ || _#|| _|| _|| _|||d   ||d	 < |||d < t$t%|d D ]}||  ||d  7  < q| j|d k rdS |dkr||d  ||  }t || } ntj} |t&k r||d  ||d	   }!t |!| }"ntj}"t'| ||"g}#tj(dd |#d
t)||d   }$W d    n	1 sw   Y  t*|$d }%||%7 }|| _
t+t,|t!|$ }|  j|9  _t	||| d| _d | _dS )Nr   r   Fr	   r   TrF   g?rW   )TNignore)dividerX   )-r_   r'   r[   r   abs	nextafterr`   infra   r+   r   rs   r^   r]   rp   ro   rq   r    r6   ri   TOO_SMALL_STEPrv   sumr%   r&   rM   r   rC   r1   r7   rf   r.   r   rd   
MIN_FACTORr;   reversedr-   rn   rk   errstater   argmaxre   
MAX_FACTOR)&rL   r_   r'   r[   min_stepra   r^   r]   r   rp   ro   rq   r    r6   current_jacstep_acceptedhr2   r3   r8   r5   r=   r4   n_itery_newr:   r   safetyerror
error_normierror_merror_m_normerror_perror_p_normerror_normsfactorsdelta_orderr"   r"   r#   
_step_impl4  s   "





.
@

zBDF._step_implc              	   C   s2   t | j| j| j| j | j| jd | jd   S rG   )BdfDenseOutputt_oldr_   ra   r`   r   r'   r,   rK   r"   r"   r#   _dense_output_impl  s   zBDF._dense_output_impl)__name__
__module____qualname____doc__r   r   rZ   rh   r   r   __classcell__r"   r"   r|   r#   rD   H   s    |<3 rD   c                       s$   e Zd Z fddZdd Z  ZS )r   c                    sL   t  || || _| j|t| j  | _|dt| j  | _|| _d S rG   )	rY   rZ   r   r_   r   r   t_shiftdenomr'   )rL   r   r_   r   r   r'   r|   r"   r#   rZ     s
   
zBdfDenseOutput.__init__c                 C   s   |j dkr|| j | j }t|}n|| jd d d f  | jd d d f  }tj|dd}t| jdd  j|}|j dkrH|| jd 7 }|S || jdd d d f 7 }|S )Nr   r   r	   )ndimr   r   r   r   r%   r'   r&   )rL   r_   xpr;   r"   r"   r#   
_call_impl  s   
(
zBdfDenseOutput._call_impl)r   r   r   rZ   r   r   r"   r"   r|   r#   r     s    r   )"numpyr   scipy.linalgr   r   scipy.sparser   r   r   scipy.sparse.linalgr   scipy.optimize._numdiffr   commonr
   r   r   r   r   r   r   r   baser   r   rn   r.   r   r   r$   r+   rC   rD   r   r"   r"   r"   r#   <module>   s&    (
$   