o
    Ö­j]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"   úU/var/www/html/CropPilot/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.
    gü©ñÒMbP?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   g®Gáz®Ç¿gÇqÇq¼¿gýöuàœµ¿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ˆ ƒr‹tˆ ˆjd�}ntj	ˆ ˆjd�}|j
ˆjˆjfkr¬t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 �rµd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&    (
$   