
    \h(                     D    S r SSKJrJrJrJr  SSKJr  S rS r	S r
S rg)	z%Module for differentiation using CSE.    )cseMatrix
Derivative
MatrixBase)iterablec                   ^	^
 U	U
4S jm
S m	[        U 5      nU  VVs/ s H  u  p4UT
" XB5      4PM     nnnU VVs/ s H+  nUR                  U Vs/ s H  nT
" Xr5      PM     sn5      PM-     nnnXX4$ s  snnf s  snf s  snnf )a  
This function is designed to postprocess the output of a common subexpression
elimination (CSE) operation. Specifically, it removes any CSE replacement
symbols from the arguments of ``Derivative`` terms in the expression. This
is necessary to ensure that the forward Jacobian function correctly handles
derivative terms.

Parameters
==========

replacements : list of (Symbol, expression) pairs
    Replacement symbols and relative common subexpressions that have been
    replaced during a CSE operation.

reduced_expressions : list of SymPy expressions
    The reduced expressions with all the replacements from the
    replacements list above.

Returns
=======

processed_replacements : list of (Symbol, expression) pairs
    Processed replacement list, in the same format of the
    ``replacements`` input list.

processed_reduced : list of SymPy expressions
    Processed reduced list, in the same format of the
    ``reduced_expressions`` input list.
c                    > [        U [        5      (       a  T" X5      $ U R                  (       d  U $ U R                   Vs/ s H  nT" X!5      PM     nnU R                  " U6 $ s  snf N)
isinstancer   argsfunc)node	repl_dictargnew_argsreplace_alltraverses       P/var/www/auris/envauris/lib/python3.13/site-packages/sympy/simplify/_cse_diff.pyr   -_remove_cse_from_derivative.<locals>.traverse&   sY    dJ''t//yyK8<		B	HS,	Byy(## Cs    A#c                     U n UR                   nU Vs0 s H  oDU;   d  M
  XAU   _M     nnU(       d   U$ UR                  U5      nME  s  snf r
   )free_symbolsxreplace)r   r   resultr   ksymbols_dicts         r   r   0_remove_cse_from_derivative.<locals>.replace_all.   sX    !..L5AT\)^OA|O\LT __\2F Ts
   	A		A	)dict	__class__)replacementsreduced_expressionsr   rep_symsub_expprocessed_replacementsred_expexpprocessed_reducedr   r   s            @@r   _remove_cse_from_derivativer'      s    >$ \"I !- ,G 
(7./ ,   +*G 	wGw8C3wGH*  
 "44
 Hs   A3A>A9"A>9A>c                    [        US   [        5      (       d  [        S5      eUS   R                  S   S:X  d!  US   R                  S   S:X  d  [        S5      e[	        U5      (       d  [        S5      e[        U[        5      (       d  [        U5      nUR                  S   S:X  d  UR                  S   S:X  d  [        S5      e[        X5      u  pU (       a  [        [
        [        U 6 5      u  p4O[        / 5      [        / 5      pC[        U5      [        U5      [        US   5      pvnUS   R                  R                  Xv[        US   5       VV	V
Vs0 s H7  u  p[        U5        H"  u  pU	R                  U5      =nS:w  d  M  X4U_M$     M9     snn
n	n5      nU (       d  / U// 4$ [
        R                  " Xu[        US    V	s/ s H  oU	R                  4PM     sn	5       VV	VV
Vs0 s HA  u  nu  p[        U5        H)  u  pX;   d  M  U	R                  U5      =nS:w  d  M%  X4U_M+     MC     snn
nn	n5      n[        U5      nU Vs/ s H  oR                  U-  PM     nn[
        R                  " SU[        U5       V
Vs0 s H&  u  pUS   R                  U5      =nS:w  d  M!  SU
4U_M(     snn
5      n[!        SU5       GH*  n[
        R                  " SU[!        US-   5       V
s0 s H2  n
X:   UU   ;   d  M  XH   R                  X:   5      =nS:w  d  M-  SU
4U_M4     sn
5      n[
        R                  " SU[        U5       V
Vs0 s H%  u  pXH   R                  U5      =nS:w  d  M   SU
4U_M'     snn
5      nUR"                  R%                  5       (       a:  UR'                  U5      R)                  U5      n[
        R*                  " UU5      nGM  [
        R*                  " UU5      nGM-     UR'                  U5      R)                  U5      nUS   R                  U5      /nU UU4$ s  snn
n	nf s  sn	f s  snn
nn	nf s  snf s  snn
f s  sn
f s  snn
f )a  
Core function to compute the Jacobian of an input Matrix of expressions
through forward accumulation. Takes directly the output of a CSE operation
(replacements and reduced_expr), and an iterable of variables (wrt) with
respect to which to differentiate the reduced expression and returns the
reduced Jacobian matrix and the ``replacements`` list.

The function also returns a list of precomputed free symbols for each
subexpression, which are useful in the substitution process.

Parameters
==========

replacements : list of (Symbol, expression) pairs
    Replacement symbols and relative common subexpressions that have been
    replaced during a CSE operation.

reduced_expr : list of SymPy expressions
    The reduced expressions with all the replacements from the
    replacements list above.

wrt : iterable
    Iterable of expressions with respect to which to compute the
    Jacobian matrix.

Returns
=======

replacements : list of (Symbol, expression) pairs
    Replacement symbols and relative common subexpressions that have been
    replaced during a CSE operation. Compared to the input replacement list,
    the output one doesn't contain replacement symbols inside
    ``Derivative``'s arguments.

jacobian : list of SymPy expressions
    The list only contains one element, which is the Jacobian matrix with
    elements in reduced form (replacement symbols are present).

precomputed_fs: list
    List of sets, which store the free symbols present in each sub-expression.
    Useful in the substitution process.
r   z``expr`` must be of matrix type   z)``expr`` must be a row or a column matrixz(``wrt`` must be an iterable of variablesz(``wrt`` must be a row or a column matrix)r   r   	TypeErrorshaper   r   r'   mapziplenr   from_dok	enumeratediffr   setrange_repnnzmultiplyaddvstack)r   reduced_exprwrtr!   sub_exprl_subl_wrtl_redirjw
diff_valuef1fssf2rep_sym_setprecomputed_fsc_matrix	bi_matrix	ai_matrix	ci_matrixjacobians                           r   _forward_jacobian_cserO   E   s3   X l1oz229::O!!!$)\!_-B-B1-E-JCDDC==BCCZ((SkIIaLA1!2BCC!<\!XL\(:;"2Jr
h-S3|A3G%E	a	"	"	+	+E ",q/2	
2!#ffQi'
A- QFJ& 2	

B B4|	 (lSTo(VoQ^^)<o(VW	
W
7A!'*w  +,&&)3J9 QFJ* W	

B g,K<DFHqnn{2HNFq%?H~  M~tq2:1+2B2B12E$EJ!#K !3A
 2~  MNH 1e_OOAqAFq1u %\A(/
nQ6G(G &88@8H8H8T*T*YZ)Z &8aVZ%7 %\]	
 OOAuDMcN %RNDA7?{7G7G7J)Jq(P &8aVZ%7N %RS	 >>!**8488CI}}Xy9H}}Xy9H " {{8$((,HQ))(34H>11_	
 )W	
 G M%\
%RsT   .P4
P4
P<.QQ*QQ

 Q.	Q1QQ!	QQ4	Qc                 B    [        U 5      u  p#[        X#U5      u  p$nX$U4$ )a	  
Function to compute the Jacobian of an input Matrix of expressions through
forward accumulation. Takes a sympy Matrix of expressions (expr) as input
and an iterable of variables (wrt) with respect to which to compute the
Jacobian matrix. The matrix is returned in reduced form (containing
replacement symbols) along with the ``replacements`` list.

The function also returns a list of precomputed free symbols for each
subexpression, which are useful in the substitution process.

Parameters
==========

expr : Matrix
    The vector to be differentiated.

wrt : iterable
    The vector with respect to which to perform the differentiation.
    Can be a matrix or an iterable of variables.

Returns
=======

replacements : list of (Symbol, expression) pairs
    Replacement symbols and relative common subexpressions that have been
    replaced during a CSE operation. The output replacement list doesn't
    contain replacement symbols inside ``Derivative``'s arguments.

jacobian : list of SymPy expressions
    The list only contains one element, which is the Jacobian matrix with
    elements in reduced form (replacement symbols are present).

precomputed_fs: list
    List of sets, which store the free symbols present in each
    sub-expression. Useful in the substitution process.
)r   rO   )exprr:   r   r9   rN   rI   s         r   !_forward_jacobian_norm_in_cse_outrR      s.    L "%TL-B<_b-c*LN>11    c                 v   [        U 5      u  p#U(       a  [        [        [        U6 5      u  pEO[        / 5      n[	        X#U5      u  p&nU(       d  US   $ [        U5      n[        U5       H4  u  pU
 Vs0 s H  oX   _M	     nnXU	      R                  U5      XU	   '   M6     US   R                  U5      $ s  snf )a  
Function to compute the Jacobian of an input Matrix of expressions through
forward accumulation. Takes a sympy Matrix of expressions (expr) as input
and an iterable of variables (wrt) with respect to which to compute the
Jacobian matrix.

Explanation
===========

Expressions often contain repeated subexpressions. Using a tree structure,
these subexpressions are duplicated and differentiated multiple times,
leading to inefficiency.

Instead, if a data structure called a directed acyclic graph (DAG) is used
then each of these repeated subexpressions will only exist a single time.
This function uses a combination of representing the expression as a DAG and
a forward accumulation algorithm (repeated application of the chain rule
symbolically) to more efficiently calculate the Jacobian matrix of a target
expression ``expr`` with respect to an expression or set of expressions
``wrt``.

Note that this function is intended to improve performance when
differentiating large expressions that contain many common subexpressions.
For small and simple expressions it is likely less performant than using
SymPy's standard differentiation functions and methods.

Parameters
==========

expr : Matrix
    The vector to be differentiated.

wrt : iterable
    The vector with respect to which to do the differentiation.
    Can be a matrix or an iterable of variables.

See Also
========

Direct Acyclic Graph : https://en.wikipedia.org/wiki/Directed_acyclic_graph
r   )r   r,   r   r-   rO   r   r0   r   )rQ   r:   r   r9   r!   _rN   rI   sub_repr?   ikrA   sub_dicts                r   _forward_jacobianrY      s    V "%TLl!34
*-B<_b-c*LN+< G>*+-.2awzM2.%aj1::8D
 + A;(( /s   3B6N)__doc__sympyr   r   r   r   sympy.utilities.iterablesr   r'   rO   rR   rY    rS   r   <module>r^      s)    + 5 5 .;5|t2n)2X;)rS   