B
    0dA                 @   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arangeZzeroscumprod)orderfactorIJM r    J/var/www/html/venv/lib/python3.7/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}xttD ]}| ||
}tt|s>P |||| | |	 }t|| }|dkrnd}n|| }|dk	r|dks|t|  d|  | |krP |
|7 }
|	|7 }	|dks|dk	r|d|  | |k rd}P |}qW ||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$   s0    
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). But if a component of `y`
        is approximately below `atol`, the error only needs to fall within
        the same `atol` threshold, and the number of correct digits is not
        guaranteed. 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?g      ?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>   )r?   r    r!   r@      s    c             S   s   t | |ddS )NT)Zoverwrite_b)r   )r3   rA   r    r    r!   r4      s    )rC   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   rC   r   identityr@   r4   r   arrayZhstackZcumsumr   	MAX_ORDERgammaalphaerror_constemptyr%   r   n_equal_stepsr3   )r?   r.   t0y0t_boundrH   rJ   rK   rT   Zjac_sparsityZ
vectorizedZ
first_stepZ
extraneousr:   r@   r4   r   kappar%   )	__class__)r?   r!   rG      sJ    
& 
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 )Nr	   )njevZ
fun_singler   Zfun_vectorizedrK   rR   )rL   r7   r:   r   )r?   sparsityr    r!   jac_wrapped   s    z&BDF._validate_jac.<locals>.jac_wrappedr	   )rC   c                s"    j d7  _ t | |jdS )Nr	   )rC   )rb   r   rC   )rL   r7   )rT   r?   r^   r    r!   rd     s    c                s$    j d7  _ tj | |jdS )Nr	   )rC   )rb   r   asarrayrC   )rL   r7   )rT   r?   r^   r    r!   rd     s    z8`jac` is expected to have shape {}, but actually has {}.)rL   r7   r   r   r   callablerb   rC   r   re   shaperI   
ValueErrorrB   )r?   rT   rc   r]   groupsrd   r   r    )rT   r?   rc   r^   r!   rS      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 k}d}x|s||k rd| 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}||	|  }xr|s(|d kr| | j||  }t| j|||||| j|| j	\}}}}|s|rP | ||}d }d}qW |sTd}||9 }t	||| d| _d }qdd	t d  d	t |  }||t|  }|| | }t || }|dkrt!t"||d
|d    }||9 }t	||| d| _qd}qW |  jd7  _|| _ || _#|| _|| _|| _|||d   ||d	 < |||d < x2t$t%|d D ]}||  ||d  7  < qDW | j|d k rzd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 Q R X t*|$d }%||%7 }|| _
t+t,|t!|$ }|  j|9  _t	||| d| _d | _dS )Nr   r   Fr	   )r   Tg      ?g?rD   )TNignore)dividerE   )-rL   r%   rH   r   absZ	nextafterrM   infrN   r(   r   r\   rK   rJ   rY   rX   rZ   r   r3   rT   ZTOO_SMALL_STEPr_   sumr#   r$   r@   r   r;   r.   r4   rQ   r+   r   rO   
MIN_FACTORr7   reversedr*   rW   rV   Zerrstater   ZargmaxrP   
MAX_FACTOR)&r?   rL   r%   rH   Zmin_steprN   rK   rJ   r   rY   rX   rZ   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 )Nr	   )BdfDenseOutputt_oldrL   rN   rM   r   r%   r)   )r?   r    r    r!   _dense_output_impl  s    zBDF._dense_output_impl)__name__
__module____qualname____doc__r   rn   rG   rS   rv   ry   __classcell__r    r    )ra   r!   r<   H   s   o95 r<   c                   s$   e Zd Z fddZdd Z  ZS )rw   c                sL   t  || || _| j|t| j  | _|dt| j  | _|| _d S )Nr	   )	rF   rG   r   rL   r   r   t_shiftdenomr%   )r?   rx   rL   rs   r   r%   )ra   r    r!   rG     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$   )r?   rL   xpr7   r    r    r!   
_call_impl  s    
(
zBdfDenseOutput._call_impl)rz   r{   r|   rG   r   r~   r    r    )ra   r!   rw     s   rw   )"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   rW   r+   rp   rr   r"   r(   r;   r<   rw   r    r    r    r!   <module>   s"   (
$  v