o
    8Va-                     @   s   d Z ddl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 ddlmZ eddd	d
  dd Zdd Zd#ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" ZdS )$z^
Solution of equations using dense matrices.

The dense matrix is stored as a list of lists.

    N)isqrt)symbols)augmentcolconjugate_transposeeyerowaddrowmul)SymPyDeprecationWarningZ
densesolvei1  z1.1)ZfeatureZissueZdeprecated_since_versionc                 C   s   t | }t|}t|D ]>}|| | dkr,|| | dkr,t||d|| |  | t|d |D ]}|| | dkrJt||||| |  | q3q|S )a  
    Returns the row echelon form of a matrix with diagonal elements
    reduced to 1.

    Examples
    ========

    >>> from sympy.matrices.densesolve import row_echelon
    >>> from sympy import QQ
    >>> a = [
    ... [QQ(3), QQ(7), QQ(4)],
    ... [QQ(2), QQ(4), QQ(5)],
    ... [QQ(6), QQ(2), QQ(3)]]
    >>> row_echelon(a, QQ)
    [[1, 7/3, 4/3], [0, 1, -7/2], [0, 0, 1]]

    See Also
    ========

    rref
       r   )copydeepcopylenranger	   r   matlistKZresult_matlistnrowij r   ;/usr/lib/python3/dist-packages/sympy/matrices/densesolve.pyrow_echelon   s   
 r   c                 C   sf   t | }t||}t|}t|D ]}|| | dkr0t|D ]}t||||| |  | q q|S )a{  
    Returns the reduced row echelon form of a Matrix.

    Examples
    ========

    >>> from sympy.matrices.densesolve import rref
    >>> from sympy import QQ
    >>> a = [
    ... [QQ(1), QQ(2), QQ(1)],
    ... [QQ(-2), QQ(-3), QQ(1)],
    ... [QQ(3), QQ(5), QQ(0)]]
    >>> rref(a, QQ)
    [[1, 0, -5], [0, 1, 3], [0, 0, 0]]

    See Also
    ========

    row_echelon
    r   )r   r   r   r   r   r   r   r   r   r   rref7   s   

r   c              	   C   s   t | }t||t| }}t|D ]7}t|d |D ]-}|| | dkrI|| | || |  || |< t||||| |  || |  | qq||fS )a  
    It computes the LU decomposition of a matrix and returns L and U
    matrices.

    Examples
    ========

    >>> from sympy.matrices.densesolve import LU
    >>> from sympy import QQ
    >>> a = [
    ... [QQ(1), QQ(2), QQ(3)],
    ... [QQ(2), QQ(-4), QQ(6)],
    ... [QQ(3), QQ(-9), QQ(-3)]]
    >>> LU(a, QQ)
    ([[1, 0, 0], [2, 1, 0], [3, 15/8, 1]], [[1, 2, 3], [0, -8, 0], [0, 0, -12]])

    See Also
    ========

    upper_triangle
    lower_triangle
    r   r   )r   r   r   r   r   r   )r   r   reverser   Znew_matlist1Znew_matlist2r   r   r   r   r   LUV   s    &r   c           	      C   s   t | }t|}t||}t|D ]H}t|d D ]?}|j}t|D ]}||| | || |  7 }q#||krGt|| | | || |< q|| | | || |  || |< qq|t||fS )a  
    Performs the cholesky decomposition of a Hermitian matrix and
    returns L and it's conjugate transpose.

    Examples
    ========

    >>> from sympy.matrices.densesolve import cholesky
    >>> from sympy import QQ
    >>> cholesky([[QQ(25), QQ(15), QQ(-5)], [QQ(15), QQ(18), QQ(0)], [QQ(-5), QQ(0), QQ(11)]], QQ)
    ([[5, 0, 0], [3, 3, 0], [-1, 1, 3]], [[5, 3, -1], [0, 3, 1], [0, 0, 3]])

    See Also
    ========

    cholesky_solve
    r   )r   r   r   r   r   zeror   r   )	r   r   new_matlistr   Lr   r   akr   r   r   choleskyw   s   

&r!   c           
      C   s   t | }t|}t||t||}}t|D ]L}t|d D ]C}|j}t|D ]}	||| |	 || |	  ||	 |	  7 }q)||krQ|| | | || |< q || | | || |  || |< q q||t||fS )a  
    Performs the LDL decomposition of a hermitian matrix and returns L, D and
    transpose of L. Only applicable to rational entries.

    Examples
    ========

    >>> from sympy.matrices.densesolve import LDL
    >>> from sympy import QQ

    >>> a = [
    ... [QQ(4), QQ(12), QQ(-16)],
    ... [QQ(12), QQ(37), QQ(-43)],
    ... [QQ(-16), QQ(-43), QQ(98)]]
    >>> LDL(a, QQ)
    ([[1, 0, 0], [3, 1, 0], [-4, 5, 1]], [[4, 0, 0], [0, 1, 0], [0, 0, 9]], [[1, 3, -4], [0, 1, 5], [0, 0, 1]])

    r   )r   r   r   r   r   r   r   )
r   r   r   r   r   Dr   r   r   r    r   r   r   LDL   s   
*&r#   c                 C   s   t | }t||\}}|S )a  
    Transforms a given matrix to an upper triangle matrix by performing
    row operations on it.

    Examples
    ========

    >>> from sympy.matrices.densesolve import upper_triangle
    >>> from sympy import QQ
    >>> a = [
    ... [QQ(4,1), QQ(12,1), QQ(-16,1)],
    ... [QQ(12,1), QQ(37,1), QQ(-43,1)],
    ... [QQ(-16,1), QQ(-43,1), QQ(98,1)]]
    >>> upper_triangle(a, QQ)
    [[4, 12, -16], [0, 1, 5], [0, 0, 9]]

    See Also
    ========

    LU
    r   r   r   r   r   Zcopy_matlistlower_triangleupper_triangler   r   r   r'      s   
r'   c                 C   s    t | }t||dd\}}|S )a  
    Transforms a given matrix to a lower triangle matrix by performing
    row operations on it.

    Examples
    ========

    >>> from sympy.matrices.densesolve import lower_triangle
    >>> from sympy import QQ
    >>> a = [
    ... [QQ(4,1), QQ(12,1), QQ(-16)],
    ... [QQ(12,1), QQ(37,1), QQ(-43,1)],
    ... [QQ(-16,1), QQ(-43,1), QQ(98,1)]]
    >>> lower_triangle(a, QQ)
    [[1, 0, 0], [3, 1, 0], [-4, 5, 1]]

    See Also
    ========

    LU
    r   )r   r$   r%   r   r   r   r&      s   
r&   c                 C   s*   t | }t|||}t||}t|dS )a  
    Solves a system of equations using reduced row echelon form given
    a matrix of coefficients, a vector of variables and a vector of constants.

    Examples
    ========

    >>> from sympy.matrices.densesolve import rref_solve
    >>> from sympy import QQ
    >>> from sympy import Dummy
    >>> x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    >>> coefficients = [
    ... [QQ(25), QQ(15), QQ(-5)],
    ... [QQ(15), QQ(18), QQ(0)],
    ... [QQ(-5), QQ(0), QQ(11)]]
    >>> constants = [
    ... [QQ(2)],
    ... [QQ(3)],
    ... [QQ(1)]]
    >>> variables = [
    ... [x],
    ... [y],
    ... [z]]
    >>> rref_solve(coefficients, variables, constants, QQ)
    [[-1/225], [23/135], [4/45]]

    See Also
    ========

    row_echelon
    augment
    )r   r   r   r   r   )r   variableconstantr   r   Z	augmentedZsolutionr   r   r   
rref_solve   s   
!

r+   c           	      C   V   t | }t|}t||\}}dd td| D }t|||| t|||| |S )a  
    Solves a system of equations using  LU decomposition given a matrix
    of coefficients, a vector of variables and a vector of constants.

    Examples
    ========

    >>> from sympy.matrices.densesolve import LU_solve
    >>> from sympy import QQ
    >>> from sympy import Dummy
    >>> x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    >>> coefficients = [
    ... [QQ(2), QQ(-1), QQ(-2)],
    ... [QQ(-4), QQ(6), QQ(3)],
    ... [QQ(-4), QQ(-2), QQ(8)]]
    >>> variables = [
    ... [x],
    ... [y],
    ... [z]]
    >>> constants = [
    ... [QQ(-1)],
    ... [QQ(13)],
    ... [QQ(-6)]]
    >>> LU_solve(coefficients, variables, constants, QQ)
    [[2], [3], [1]]

    See Also
    ========

    LU
    forward_substitution
    backward_substitution
    c                 S      g | ]}|gqS r   r   .0r   r   r   r   
<listcomp><      zLU_solve.<locals>.<listcomp>y:%i)r   r   r   r   r   forward_substitutionbackward_substitution)	r   r)   r*   r   r   r   r   Uyr   r   r   LU_solve     
"r7   c           	      C   r,   )a}  
    Solves a system of equations using Cholesky decomposition given
    a matrix of coefficients, a vector of variables and a vector of constants.

    Examples
    ========

    >>> from sympy.matrices.densesolve import cholesky_solve
    >>> from sympy import QQ
    >>> from sympy import Dummy
    >>> x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    >>> coefficients = [
    ... [QQ(25), QQ(15), QQ(-5)],
    ... [QQ(15), QQ(18), QQ(0)],
    ... [QQ(-5), QQ(0), QQ(11)]]
    >>> variables = [
    ... [x],
    ... [y],
    ... [z]]
    >>> coefficients = [
    ... [QQ(2)],
    ... [QQ(3)],
    ... [QQ(1)]]
    >>> cholesky_solve([[QQ(25), QQ(15), QQ(-5)], [QQ(15), QQ(18), QQ(0)], [QQ(-5), QQ(0), QQ(11)]], [[x], [y], [z]], [[QQ(2)], [QQ(3)], [QQ(1)]], QQ)
    [[-1/225], [23/135], [4/45]]

    See Also
    ========

    cholesky
    forward_substitution
    backward_substitution
    c                 S   r-   r   r   r.   r   r   r   r0   g  r1   z"cholesky_solve.<locals>.<listcomp>r2   )r   r   r   r!   r   r3   r4   )	r   r)   r*   r   r   r   r   ZLstarr6   r   r   r   cholesky_solveB  r8   r9   c           	      C   sx   t | }t|}t|D ],}|j}t|D ]}||| | || d  7 }q|| d | || |  || d< q|S )a  
    Performs forward substitution given a lower triangular matrix, a
    vector of variables and a vector of constants.

    Examples
    ========

    >>> from sympy.matrices.densesolve import forward_substitution
    >>> from sympy import QQ
    >>> from sympy import Dummy
    >>> x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    >>> a = [
    ... [QQ(1), QQ(0), QQ(0)],
    ... [QQ(-2), QQ(1), QQ(0)],
    ... [QQ(-2), QQ(-1), QQ(1)]]
    >>> variables = [
    ... [x],
    ... [y],
    ... [z]]
    >>> constants = [
    ... [QQ(-1)],
    ... [QQ(13)],
    ... [QQ(-6)]]
    >>> forward_substitution(a, variables, constants, QQ)
    [[-1], [11], [3]]

    See Also
    ========

    LU_solve
    cholesky_solve
    r   )r   r   r   r   r   )	r&   r)   r*   r   Zcopy_lower_triangler   r   r   r   r   r   r   r3   m  s   
!&r3   c           	      C   s   t | }t|}tt|D ]1}|j}tt|d |D ]}||| | || d  7 }q|| d | || |  || d< q|S )a  
    Performs forward substitution given a lower triangular matrix,
    a vector of variables and a vector constants.

    Examples
    ========

    >>> from sympy.matrices.densesolve import backward_substitution
    >>> from sympy import QQ
    >>> from sympy import Dummy
    >>> x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    >>> a = [
    ... [QQ(2), QQ(-1), QQ(-2)],
    ... [QQ(0), QQ(4), QQ(-1)],
    ... [QQ(0), QQ(0), QQ(3)]]
    >>> variables = [
    ... [x],
    ... [y],
    ... [z]]
    >>> constants = [
    ... [QQ(-1)],
    ... [QQ(11)],
    ... [QQ(3)]]
    >>> backward_substitution(a, variables, constants, QQ)
    [[2], [3], [1]]

    See Also
    ========

    LU_solve
    cholesky_solve
    r   r   )r   r   r   reversedr   r   )	r'   r)   r*   r   Zcopy_upper_triangler   r   r   r   r   r   r   r4     s   
!&r4   )r   )__doc__r   Zsympy.core.powerr   Zsympy.core.symbolr   Zsympy.matrices.densetoolsr   r   r   r   r   r	   Zsympy.utilities.exceptionsr
   warnr   r   r   r!   r#   r'   r&   r+   r7   r9   r3   r4   r   r   r   r   <module>   s0     !
!!"'+++