a
    BCCfrD                     @   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   Zaxis)nparangeZzeroscumprod)orderfactorIJM r    T/var/www/html/django/DPS/env/lib/python3.9/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UZRUr    r    r!   change_D   s    


r(   c	                 C   s   d}	|  }
d}d}ttD ]}| ||
}tt|s> q|||| | |	 }t|| }|du rnd}n|| }|dur|dks|t|  d|  | |kr q|
|7 }
|	|7 }	|dks|dur|d|  | |k rd} q|}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scaleZtoldyZdy_norm_old	convergedkfZdyZdy_normZrater    r    r!   solve_bdf_system$   s8    
r;   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 r~t 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)Z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)Zsolver3   br    r    r!   r4      s    zBDF.__init__.<locals>.solve_luZcsc)formatdtypec                    s     j d7  _ t| ddS )Nr	   T)Zoverwrite_a)r?   r   r@   rB   r    r!   rD      s    c                 S   s   t | |ddS )NT)Zoverwrite_b)r   rE   r    r    r!   r4      s    rH   )r   gGzǿgqqgugsh|?r   r         )/r   super__init__r
   max_stepr   nrtolatolr.   tr7   r   	directionh_absr   Z	h_abs_oldZerror_norm_oldmaxr   min
newton_tol
jac_factor_validate_jacjacr   r   r   rH   r   identityrD   r4   r   arrayZhstackZcumsumr   	MAX_ORDERgammaalphaerror_constemptyr%   r   n_equal_stepsr3   )rC   r.   t0y0t_boundrN   rP   rQ   rZ   Zjac_sparsityZ
vectorizedZ
first_stepZ
extraneousr:   rD   r4   r   kappar%   	__class__rB   r!   rM      sN    
& 
zBDF.__init__c                    sP  j }j d u rVd ur<tr,tt}|ffdd}||}nt r |} jd7  _t|rt|jd} fdd}n tj	|jd} fdd}|j
jjfkrtdjjf|j
n\t rt jd}ntj	 jd}|j
jjfkrDtdjjf|j
d }||fS )Nc                    s>     j d7  _  | |}t j| || j j\} _|S r>   )njevZ
fun_singler   Zfun_vectorizedrQ   rX   )rR   r7   r:   r   )rC   sparsityr    r!   jac_wrapped  s    
z&BDF._validate_jac.<locals>.jac_wrappedr	   rI   c                    s"    j d7  _ t | |jdS Nr	   rI   )ri   r   rH   rR   r7   rZ   rC   rd   r    r!   rk     s    c                    s$    j d7  _ tj | |jdS rl   )ri   r   asarrayrH   rm   rn   r    r!   rk     s    z8`jac` is expected to have shape {}, but actually has {}.)rR   r7   r   r   r   callableri   rH   r   ro   shaperO   
ValueErrorrG   )rC   rZ   rj   rc   groupsrk   r   r    )rZ   rC   rj   rd   r!   rY      s>    

zBDF._validate_jacc           &   
   C   s  | j }| j}| j}dtt|| jtj |  }| j|kr^|}t	|| j
|| j  d| _n0| j|k r|}t	|| j
|| j  d| _n| j}| j}| j}| j
}| j}	| j}
| j}| j}| j}| jd u }d}|s||k rd| jfS || j }|| }| j|| j  dkr6| 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q$| ||}d }d}q|sNd}||9 }t	||| d| _d }qdd	t d  d	t |  }||t|  }|| | }t || }|dkrt!t"||d
|d    }||9 }t	||| d| _qd}q|  jd7  _|| _ || _#|| _|| _|| _|||d   ||d	 < |||d < t$t%|d D ]}||  ||d  7  < q:| j|d k rnd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"0    Y  t*|$d }%||%7 }|| _
t+t,|t!|$ }|  j|9  _t	||| d| _d | _dS )Nr   r   Fr	   r   Tr=   g?rJ   )TNignore)dividerK   )-rR   r%   rN   r   abs	nextafterrS   infrT   r(   r   rb   rQ   rP   r_   r^   r`   r   r3   rZ   ZTOO_SMALL_STEPre   sumr#   r$   rD   r   r;   r.   r4   rW   r+   r   rU   
MIN_FACTORr7   reversedr*   r]   r\   Zerrstater   ZargmaxrV   
MAX_FACTOR)&rC   rR   r%   rN   Zmin_steprT   rQ   rP   r   r_   r^   r`   r   r3   Zcurrent_jacZstep_acceptedhr/   r0   r5   r2   r8   r1   Zn_iterZy_newr6   r   ZsafetyerrorZ
error_normiZerror_mZerror_m_normZerror_pZerror_p_normZerror_normsZfactorsZdelta_orderr    r    r!   
_step_impl5  s    "





.



8zBDF._step_implc              	   C   s2   t | j| j| j| j | j| jd | jd   S r>   )BdfDenseOutputt_oldrR   rT   rS   r   r%   r)   rB   r    r    r!   _dense_output_impl  s    zBDF._dense_output_impl)__name__
__module____qualname____doc__r   ry   rM   rY   r   r   __classcell__r    r    rg   r!   r<   H   s   |;5 r<   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 r>   )	rL   rM   r   rR   r   r   t_shiftdenomr%   )rC   r   rR   r~   r   r%   rg   r    r!   rM     s
    zBdfDenseOutput.__init__c                 C   s   |j dkr&|| j | j }t|}n6|| jd d d f  | jd d d f  }tj|dd}t| jdd  j|}|j dkr|| jd 7 }n|| jdd d d f 7 }|S )Nr   r   r	   )ndimr   r   r   r   r#   r%   r$   )rC   rR   xpr7   r    r    r!   
_call_impl  s    
(
zBdfDenseOutput._call_impl)r   r   r   rM   r   r   r    r    rg   r!   r     s   r   )"numpyr   Zscipy.linalgr   r   Zscipy.sparser   r   r   Zscipy.sparse.linalgr   Zscipy.optimize._numdiffr   commonr
   r   r   r   r   r   r   r   baser   r   r]   r+   r{   r}   r"   r(   r;   r<   r   r    r    r    r!   <module>   s$   (
$   