U
    -e	C                     @   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    Y/var/www/html/Darija-Ai-Train/env/lib/python3.8/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krnd}n|| }|dk	r|dks|t|  d|  | |kr q|
|7 }
|	|7 }	|dks|dk	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 calling signature is ``fun(t, y)``.
        Here ``t`` is a scalar, and there are two options for the ndarray ``y``:
        It can either have shape (n,); then ``fun`` must return array_like with
        shape (n,). Alternatively it can have shape (n, k); then ``fun``
        must return an array_like with shape (n, k), i.e. each column
        corresponds to a single column in ``y``. The choice between the two
        options is determined by `vectorized` argument (see below). The
        vectorized implementation allows a faster approximation of the Jacobian
        by finite differences (required for this solver).
    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` is implemented in a vectorized fashion. Default is False.

    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 k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"ddddddg}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   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      sR    
  & 
zBDF.__init__c                    sP  j }j d krVd k	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      sB    

 

 zBDF._validate_jacc           &   
   C   sp  | 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 k}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 k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 5 Q R X 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   absZ	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_impl,  s    "





.
       


"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   rx   rM   rY   r   r   __classcell__r    r    rg   r!   r<   H   s   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+   rz   r|   r"   r(   r;   r<   r   r    r    r    r!   <module>   s"   (
$  z