U
    ?h                     @   sf   d dl Z d dlZd dlmZ d dlmZ dd Zdd Zdd	 Z	d
d Z
dddZdd Zdd ZdS )    N)assert_allclose)odec                 C   sx   | j \}}d}t| d dD ]}t| | r| } q>qd}t|d ddD ]}t| | rR|} qpqR||fS )z7Returns ml and mu, the lower and upper band sizes of a.r      )shaperangenpdiagany)aZnrowsZncolsmlkmu r   _/var/www/html/venv/lib/python3.8/site-packages/scipy/integrate/tests/test_banded_ode_solvers.py_band_count   s    
r   c                 C   s
   | |S )zLinear system dy/dt = a * y)dottyr   r   r   r   _linear_func   s    r   c                 C   s   |S )zJacobian of a * y is a.r   r   r   r   r   _linear_jac   s    r   c                    sv   t  \}} fddt|ddD }|t  td| d dD ](}|tjt |dg|  f  qH|S )zBanded Jacobian.c                    s(   g | ] }t jd g| t  |f qS )r   )r   r_r	   ).0r   r   r   r   
<listcomp>$   s     z&_linear_banded_jac.<locals>.<listcomp>r   r   r   )r   r   appendr   r	   r   )r   r   r   r   r   Zbjacr   r   r   r   _linear_banded_jac!   s    &r   r   皙?bdfTFc	              	   C   s   |rt | \}	}
nd}	d}
|r:|r.ttt}qBttt}ntt}|dkr^t| rZd}nd}|j||||	|
ddd d}||| |	|  |
|  |g}|g}| r|j|k r||j|  ||j ||j qt|}t|}||fS )a  Use scipy.integrate.ode to solve a linear system of ODEs.

    a : square ndarray
        Matrix of the linear system to be solved.
    y0 : ndarray
        Initial condition
    tend : float
        Stop time.
    dt : float
        Step size of the output.
    solver : str
        If not None, this must be "vode", "lsoda" or "zvode".
    method : str
        Either "bdf" or "adams".
    use_jac : bool
        Determines if the jacobian function is passed to ode().
    with_jacobian : bool
        Passed to ode.set_integrator().
    banded : bool
        Determines whether a banded or full jacobian is used.
        If `banded` is True, `lband` and `uband` are determined by the
        values in `a`.
    Nzvodevodeg&.>g|=)with_jacobianmethodlbandubandZrtolZatolr   )r   r   r   r   r   r   ZiscomplexobjZset_integratorZset_initial_valueZset_f_paramsZset_jac_paramsZ
successfulr   Z	integrater   r   array)r   y0tenddtsolverr#   use_jacr"   bandedr$   r%   rt0r   r   r   r   r   _solve_linear_sys+   sD    
  



r/   c                 C   sH   t j| \}}t j||}|t ||dd  }||j}|S )z
    Analytical solution to the linear differential equations dy/dt = a*y.

    The solution is only valid if `a` is diagonalizable.

    Returns a 2-D array with shape (len(t), len(y0)).
    r   r   )r   ZlinalgZeigZsolveexpZreshaper   T)r   r'   r   ZlamvceZsolr   r   r   _analytical_solutionp   s
    r5   c                     s  t ddd} t dddddgddd	ddgddd
ddgdddddgdddddgg}t |}t |}t |}||||gg D ]6}t d|jd d }t||| }|| |f qfdd}t	t
D ]T}	ddgddgddgddgddgg}
tj|
 D ]"\}}}}}||	||||| qq|d|  }t t |}||g g  D ]<}t d|jd d d }t||| }|| |f qZ fdd}t	t
 D ]N}	ddgddgddgddgg}
tj|
 D ] \}}}}||	d|||| qܐqd S )Nr   g      ?   g333333r   g        g?g      g?gٿg333333?ggg333333ӿgffffffr   c                    s\    |  }|  \}}}	t |||d |d |d  |||||d	\}
}t|
| t||	 d S Nr   r   r   )r(   r)   r*   r#   r+   r"   r,   r/   r   idxr*   methr+   with_jacr,   r   r'   t_exacty_exactr   r   )real_matricesreal_solutionsr   r   
check_real   s    

z+test_banded_ode_solvers.<locals>.check_realr!   Zlsodar   ZadamsFTy              ?y              ?c                    s\    |  }|  \}}}	t |||d |d |d  |||||d	\}
}t|
| t||	 d S r7   r8   r9   )complex_matricescomplex_solutionsr   r   check_complex   s    

z.test_banded_ode_solvers.<locals>.check_complexr    )r   Zlinspacer&   ZtriuZtrilZaranger   r5   r   r   len	itertoolsproductr	   )r=   Za_realZa_real_upperZa_real_lowerZa_real_diagr   r'   r>   rA   r:   pr*   r;   r+   r<   r,   Z	a_complexZa_complex_diagrD   r   )rB   rC   r?   r@   r   test_banded_ode_solvers   sV    


rI   )r   r   Nr   TFF)rF   numpyr   Znumpy.testingr   Zscipy.integrater   r   r   r   r   r/   r5   rI   r   r   r   r   <module>   s    
         
E