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   ©Úaxis)ÚnpÚarangeÚzerosÚcumprod)ÚorderÚfactorÚIÚJÚM© r"   úU/var/www/website-v5/atlas_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 râd} 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ÚscaleÚtolÚdÚyZdy_norm_oldÚ	convergedÚkÚfÚdyZdy_normÚ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.
    gü©ñÒMbP?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)Úsolve©r5   Úbr"   r"   r#   r6   ×   s    zBDF.__init__.<locals>.solve_luÚcsc)ÚformatÚdtypec                    s   ˆ  j d7  _ t| dd�S )Nr	   T)Úoverwrite_a)rD   r   rE   rG   r"   r#   rI   Ü   s    c                 S   s   t | |dd�S )NT)Úoverwrite_b)r   rK   r"   r"   r#   r6   à   s    ©rO   r   g®Gáz®Ç¿gÇqÇq¼¿gýöuàœµ¿gsh‘í|?¥¿é   é   )/r   ÚsuperÚ__init__r
   Úmax_stepr   ÚnÚrtolÚatolr0   Útr:   r   Ú	directionÚh_absr   Z	h_abs_oldZerror_norm_oldÚmaxr   ÚminÚ
newton_tolÚ
jac_factorÚ_validate_jacÚjacr    r   r   rO   r   ÚidentityrI   r6   r   ÚarrayÚhstackÚcumsumr   Ú	MAX_ORDERÚgammaÚalphaÚerror_constÚemptyr'   r   Ún_equal_stepsr5   )rH   r0   Út0Úy0Út_boundrW   rY   rZ   rc   Újac_sparsityÚ
vectorizedÚ
first_stepZ
extraneousr=   rI   r6   r   Úkappar'   ©Ú	__class__rG   r#   rV   ¼   sR    ÿ
  þ& 
zBDF.__init__c                    sP  ˆj }ˆj‰ˆ d krVˆd k	r<tˆƒr,tˆƒ‰tˆƒ}ˆ|f‰‡‡fdd„}||ˆƒ}nòtˆ ƒrìˆ |ˆƒ}ˆ jd7  _t|ƒržt|ˆjd�}‡ ‡‡fdd„}n tj	|ˆjd�}‡ ‡‡fdd„}|j
ˆjˆjfkrêt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 rC   )ÚnjevZ
fun_singler   Zfun_vectorizedrZ   ra   )r[   r:   r=   r    )rH   Úsparsityr"   r#   Újac_wrapped  s     þ
z&BDF._validate_jac.<locals>.jac_wrappedr	   rR   c                    s"   ˆ j d7  _ tˆ | |ƒˆjd�S ©Nr	   rR   )rw   r   rO   ©r[   r:   ©rc   rH   ro   r"   r#   ry     s    c                    s$   ˆ j d7  _ tjˆ | |ƒˆjd�S rz   )rw   r   ÚasarrayrO   r{   r|   r"   r#   ry     s    z8`jac` is expected to have shape {}, but actually has {}.)r[   r:   r   r   r   Úcallablerw   rO   r   r}   ÚshaperX   Ú
ValueErrorrN   )rH   rc   rx   rn   Úgroupsry   r    r"   )rc   rH   rx   ro   r#   rb   ÷   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 räd| 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 }qÌdd	t d  d	t |  }||t |¡  }|| | }t || ƒ}|dk�rÔt!t"||d
|d    ƒ}||9 }t	|||ƒ d| _qÌd}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   TrB   gÍÌÌÌÌÌì?rS   éÿÿÿÿ)TNÚignore)ÚdividerT   )-r[   r'   rW   r   ÚabsÚ	nextafterr\   Úinfr]   r*   r   rm   rZ   rY   rj   ri   rk   r    r5   rc   ZTOO_SMALL_STEPrp   Úsumr%   r&   rI   r   r@   r0   r6   r`   r-   r   r^   Ú
MIN_FACTORr:   Úreversedr,   rh   re   Úerrstater   Úargmaxr_   Ú
MAX_FACTOR)&rH   r[   r'   rW   Úmin_stepr]   rZ   rY   r   rj   ri   rk   r    r5   Zcurrent_jacZstep_acceptedÚhr1   r2   r7   r4   r;   r3   Ún_iterÚy_newr9   r   Ú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 rC   )ÚBdfDenseOutputÚt_oldr[   r]   r\   r   r'   r+   rG   r"   r"   r#   Ú_dense_output_impl»  s     ÿzBDF._dense_output_impl)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r‡   rV   rb   r•   r˜   Ú__classcell__r"   r"   ru   r#   rA   H   s   s    þ;5 rA   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 rC   )	rU   rV   r   r[   r   r   Út_shiftÚdenomr'   )rH   r—   r[   r�   r   r'   ru   r"   r#   rV   Á  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&   )rH   r[   ÚxÚpr:   r"   r"   r#   Ú
_call_implÈ  s    
(
zBdfDenseOutput._call_impl)r™   rš   r›   rV   r£   r�   r"   r"   ru   r#   r–   À  s   r–   )"Únumpyr   Úscipy.linalgr   r   Úscipy.sparser   r   r   Úscipy.sparse.linalgr   Zscipy.optimize._numdiffr   Úcommonr
   r   r   r   r   r   r   r   Úbaser   r   rh   r-   r‰   r�   r$   r*   r@   rA   r–   r"   r"   r"   r#   Ú<module>   s"   (
$  z