
    \h?             
          S r SSKrSSKrSSKJr  SSKJr  SSKJ	r	J
r
JrJrJrJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJrJrJr  SSKJ r J!r!J"r"J#r#J$r$  SSK%J&r&  / SQr' " S S5      r( " S S5      r)\)" SSSSSS5      \)" SSSSSS5      \)" SSSSSS5      S.r*Sr+SGS  jr, " S! S"5      r- " S# S$\-5      r. " S% S&\.5      r/ " S' S(5      r0 " S) S*\.\05      r1 " S+ S,\.\05      r2 " S- S.\-\05      r3 " S/ S05      r4 " S1 S2\55      r6 " S3 S4\55      r7S5r8 " S6 S7\45      r9 " S8 S9\95      r: " S: S;\95      r; " S< S=\45      r< " S> S?\45      r= " S@ SA\45      r> " SB SC\45      r?SHSD jr@   SISE jrA  SJSF jrBg)Ka%  
module for generating C, C++, Fortran77, Fortran90, Julia, Rust
and Octave/Matlab routines that evaluate SymPy expressions.
This module is work in progress.
Only the milestones with a '+' character in the list below have been completed.

--- How is sympy.utilities.codegen different from sympy.printing.ccode? ---

We considered the idea to extend the printing routines for SymPy functions in
such a way that it prints complete compilable code, but this leads to a few
unsurmountable issues that can only be tackled with dedicated code generator:

- For C, one needs both a code and a header file, while the printing routines
  generate just one string. This code generator can be extended to support
  .pyf files for f2py.

- SymPy functions are not concerned with programming-technical issues, such
  as input, output and input-output arguments. Other examples are contiguous
  or non-contiguous arrays, including headers of other libraries such as gsl
  or others.

- It is highly interesting to evaluate several SymPy functions in one C
  routine, eventually sharing common intermediate results with the help
  of the cse routine. This is more than just printing.

- From the programming perspective, expressions with constants should be
  evaluated in the code generator as much as possible. This is different
  for printing.

--- Basic assumptions ---

* A generic Routine data structure describes the routine that must be
  translated into C/Fortran/... code. This data structure covers all
  features present in one or more of the supported languages.

* Descendants from the CodeGen class transform multiple Routine instances
  into compilable code. Each derived class translates into a specific
  language.

* In many cases, one wants a simple workflow. The friendly functions in the
  last part are a simple api on top of the Routine/CodeGen stuff. They are
  easier to use, but are less powerful.

--- Milestones ---

+ First working version with scalar input arguments, generating C code,
  tests
+ Friendly functions that are easier to use than the rigorous
  Routine/CodeGen workflow.
+ Integer and Real numbers as input and output
+ Output arguments
+ InputOutput arguments
+ Sort input/output arguments properly
+ Contiguous array arguments (numpy matrices)
+ Also generate .pyf code for f2py (in autowrap module)
+ Isolate constants and evaluate them beforehand in double precision
+ Fortran 90
+ Octave/Matlab

- Common Subexpression Elimination
- User defined comments in the generated code
- Optional extra include lines for libraries/objects that can eval special
  functions
- Test other C compilers and libraries: gcc, tcc, libtcc, gcc+gsl, ...
- Contiguous array arguments (SymPy matrices)
- Non-contiguous array arguments (SymPy matrices)
- ccode must raise an error when it encounters something that cannot be
  translated into c. ccode(integrate(sin(x)/x, x)) does not make sense.
- Complex numbers as input and output
- A default complex datatype
- Include extra information in the header: date, user, hostname, sha1
  hash, ...
- Fortran 77
- C++
- Python
- Julia
- Rust
- ...

    N)StringIO)__version__)SymbolSTupleEqualityFunctionBasic)c_code_printers)AssignmentError)FCodePrinter)JuliaCodePrinter)OctaveCodePrinter)RustCodePrinter)IdxIndexedIndexedBase)MatrixSymbolImmutableMatrix
MatrixBase
MatrixExprMatrixSlice)is_sequence)RoutineDataTypedefault_datatypesget_default_datatypeArgumentInputArgumentOutputArgumentResultCodeGenCCodeGenFCodeGenJuliaCodeGenOctaveCodeGenRustCodeGencodegenmake_routinec                   H    \ rS rSrSrS rS r\r\S 5       r	\S 5       r
Srg)	r   u   a  Generic description of evaluation routine for set of expressions.

A CodeGen class can translate instances of this class into code in a
particular language.  The routine specification covers all the features
present in these languages.  The CodeGen part must raise an exception
when certain features are not present in the target language.  For
example, multiple return values are possible in Python, but not in C or
Fortran.  Another example: Fortran and Python support complex numbers,
while C does not.

c                    [        5       n[        5       nU GH  n[        U[        5      (       aG  UR                  UR                  R
                  UR                  R                  [        5      -
  5        M`  [        U[        5      (       a  UR                  UR                  5        M  [        U[        5      (       ac  UR                  UR                  5        UR                  UR                  R
                  UR                  R                  [        5      -
  5        GM
  [        SU-  5      e   U Hk  n	[        U	[        5      (       d  [        SU	-  5      eUR                  U	R                  R
                  U	R                  R                  [        5      -
  5        Mm     [        5       n
U H  n	[        U	[        5      (       ab  UR                  U	R                  R
                  U	R                  R                  [        5      -
  5        U
R                  U	R                  5        Mz  U
R                  U	5        M     U Vs1 s H&  n[        U[        5      (       a  UR                  OUiM(     nnUR!                  UR#                  U
5      R#                  U5      5      nU[        5       :w  a7  [        SSR%                  U Vs/ s H  n['        U5      PM     sn5      -   5      eXl
        X l        X0l        X@l        XPl        gs  snf s  snf )aY  Initialize a Routine instance.

Parameters
==========

name : string
    Name of the routine.

arguments : list of Arguments
    These are things that appear in arguments of a routine, often
    appearing on the right-hand side of a function call.  These are
    commonly InputArguments but in some languages, they can also be
    OutputArguments or InOutArguments (e.g., pass-by-reference in C
    code).

results : list of Results
    These are the return values of the routine, often appearing on
    the left-hand side of a function call.  The difference between
    Results and OutputArguments and when you should use each is
    language-specific.

local_vars : list of Results
    These are variables that will be defined at the beginning of the
    function.

global_vars : list of Symbols
    Variables which will not be passed into the function.

zUnknown Routine argument: %szUnknown Routine result: %sz+Symbols needed for output are not in input , N)set
isinstancer    updateexprfree_symbolsatomsr   r   addnameInOutArgument
ValueErrorr!   r   label
differenceunionjoinstr	argumentsresults
local_varsglobal_vars)selfr5   r=   r>   r?   r@   input_symbolssymbolsargrlocal_symbolss
notcoveredxs                 O/var/www/auris/envauris/lib/python3.13/site-packages/sympy/utilities/codegen.py__init__Routine.__init__   sE   @ %C#~..sxx44sxx~~g7NNOC//!!#((+C//!!#((+sxx44sxx~~g7NNO !?#!EFF  Aa(( !=!ABBNN166..g1FFG 
 A!V$$qvv22QVV\\'5JJK!!!&&)!!!$  BIIAjC00177a7I
 ''.44[AC
J!YY
'C
1A
'CDE F F 	"$& J (Ds   -LLc                 h    U R                   R                  SR                  " S0 U R                  D6-   $ )Nz?({name!r}, {arguments}, {results}, {local_vars}, {global_vars}) )	__class____name__format__dict__rA   s    rJ   __str__Routine.__str__   sA    ~~&&)j)q)q  *Ctx  uB  uB  *C  C  	C    c                     [        U R                  5      nUR                  S U R                   5       5        UR                  S U R                   5       5        U$ )zReturns a set of all variables possibly used in the routine.

For routines with unnamed return values, the dummies that may or
may not be used will be included in the set.

c              3   8   #    U  H  oR                   v   M     g 7fNr5   ).0rD   s     rJ   	<genexpr>$Routine.variables.<locals>.<genexpr>   s     4^c^   c              3   8   #    U  H  oR                   v   M     g 7frY   )
result_var)r[   ress     rJ   r\   r]      s     8<C<r^   )r.   r?   r0   r=   r>   )rA   vs     rJ   	variablesRoutine.variables   sC      	4T^^44	84<<88rV   c                     U R                    Vs/ s H"  n[        U[        [        45      (       d  M   UPM$     nnUR	                  U R
                  5        U$ s  snf )z|Returns a list of OutputArgument, InOutArgument and Result.

If return values are present, they are at the end of the list.
)r=   r/   r    r6   extendr>   )rA   rD   argss      rJ   result_variablesRoutine.result_variables   sK      $~~ 3~.-022~ 3DLL!3s
   AA)r=   r@   r?   r5   r>   N)rP   
__module____qualname____firstlineno____doc__rK   rT   __repr__propertyrc   rh   __static_attributes__rN   rV   rJ   r   r   u   sA    
I'VC H
 
  rV   r   c                       \ rS rSrSrS rSrg)r      z<Holds strings for a certain datatype in different languages.c                 L    Xl         X l        X0l        X@l        XPl        X`l        g rY   )cnamefnamepynamejlnameoctnamersname)rA   rt   ru   rv   rw   rx   ry   s          rJ   rK   DataType.__init__   s     

rV   )rt   ru   rw   rx   rv   ry   N)rP   rj   rk   rl   rm   rK   rp   rN   rV   rJ   r   r      s
    FrV   r   intz	INTEGER*4 i32doublezREAL*8floatf64z
COMPLEX*16complex)r{   r   r   Fc                 r   Uc  [         nU(       a  SnOSnU R                  (       a	  [        S   $ U R                  (       a	  [        S   $ [	        U [
        5      (       aQ  SnU  H@  nUS:X  a  UR                  (       d  SnUS:X  d  M$  UR                  (       a  M7  [        U   s  $    [        U   $ [        U   $ )z8Derives an appropriate datatype based on the expression.r   r   r{   )COMPLEX_ALLOWED
is_integerr   is_realr/   r   )r1   complex_allowedfinal_dtypedtelements        rJ   r   r     s    ) ''	 ))	D*	%	%GU{7#5#5W}W___(55	 
 !$$ --rV   c                   B    \ rS rSrSrS	S jrS r\r\S 5       r	S r
Srg)
Variablei  zRepresents a typed variable.Nc                    [        U[        [        45      (       d  [        S5      eUc  [	        U5      nO [        U[
        5      (       d  [        S5      eU(       a&  [        U[        [        45      (       d  [        S5      eXl        UR                  UR                  UR                  UR                  UR                  UR                  S.U l        X0l        X@l        g)a  Return a new variable.

Parameters
==========

name : Symbol or MatrixSymbol

datatype : optional
    When not given, the data type will be guessed based on the
    assumptions on the symbol argument.

dimensions : sequence containing tuples, optional
    If present, the argument is interpreted as an array, where this
    sequence of tuples specifies (lower, upper) bounds for each
    index of the array.

precision : int, optional
    Controls the precision of floating point constants.

z*The first argument must be a SymPy symbol.NzMThe (optional) `datatype' argument must be an instance of the DataType class.z4The dimensions argument must be a sequence of tuples)CFORTRANJULIAOCTAVEPYTHONRUST)r/   r   r   	TypeErrorr   r   tuplelist_namert   ru   rw   rx   rv   ry   	_datatype
dimensions	precision)rA   r5   datatyper   r   s        rJ   rK   Variable.__init__  s    * $ 677HII+D1HHh// > ? ?jeT]CCFH H 
~~__&&ooOO
 %"rV   c                 R    U R                   R                  < SU R                  < S3$ )N())rO   rP   r5   rS   s    rJ   rT   Variable.__str__J  s    >>22DII>>rV   c                     U R                   $ rY   )r   rS   s    rJ   r5   Variable.nameO  s    zzrV   c                      U R                   UR                  5          $ ! [         a(    [        SSR	                  U R                   5      -  5      ef = f)a  Returns the datatype string for the requested language.

Examples
========

>>> from sympy import Symbol
>>> from sympy.utilities.codegen import Variable
>>> x = Variable(Symbol('x'))
>>> x.get_datatype('c')
'double'
>>> x.get_datatype('fortran')
'REAL*8'

zHas datatypes for languages: %sr-   )r   upperKeyErrorCodeGenErrorr;   )rA   languages     rJ   get_datatypeVariable.get_datatypeS  sQ    	/>>(.."233 	/@IIdnn- . / /	/s	    2A)r   r   r   r   NNN)rP   rj   rk   rl   rm   rK   rT   rn   ro   r5   r   rp   rN   rV   rJ   r   r     s.    &*#X? H /rV   r   c                       \ rS rSrSrSrg)r   ii  zsAn abstract Argument data structure: a name and a data type.

This structure is refined in the descendants below.

rN   N)rP   rj   rk   rl   rm   rp   rN   rV   rJ   r   r   i  s    
 	rV   r   c                       \ rS rSrSrg)r   ir  rN   NrP   rj   rk   rl   rp   rN   rV   rJ   r   r   r      rV   r   c                   (    \ rS rSrSrS rS r\rSrg)
ResultBaseiv  zBase class for all "outgoing" information from a routine.

Objects of this class stores a SymPy expression, and a SymPy object
representing a result variable that will be used in the generated code
only if necessary.

c                     Xl         X l        g rY   r1   r`   )rA   r1   r`   s      rJ   rK   ResultBase.__init__~  s    	$rV   c                 n    U R                   R                  < SU R                  < SU R                  < S3$ Nr   r-   r   )rO   rP   r1   r`   rS   s    rJ   rT   ResultBase.__str__  s&    #~~66		OO 	rV   r   N	rP   rj   rk   rl   rm   rK   rT   rn   rp   rN   rV   rJ   r   r   v  s    % HrV   r   c                   ,    \ rS rSrSrSS jrS r\rSrg)r    i  z5OutputArgument are always initialized in the routine.Nc                 ^    [         R                  XXEU5        [        R                  XU5        g)a  Return a new variable.

Parameters
==========

name : Symbol, MatrixSymbol
    The name of this variable.  When used for code generation, this
    might appear, for example, in the prototype of function in the
    argument list.

result_var : Symbol, Indexed
    Something that can be used to assign a value to this variable.
    Typically the same as `name` but for Indexed this should be e.g.,
    "y[i]" whereas `name` should be the Symbol "y".

expr : object
    The expression that should be output, typically a SymPy
    expression.

datatype : optional
    When not given, the data type will be guessed based on the
    assumptions on the symbol argument.

dimensions : sequence containing tuples, optional
    If present, the argument is interpreted as an array, where this
    sequence of tuples specifies (lower, upper) bounds for each
    index of the array.

precision : int, optional
    Controls the precision of floating point constants.

N)r   rK   r   rA   r5   r`   r1   r   r   r   s          rJ   rK   OutputArgument.__init__  s'    D 	$hIFD
3rV   c                     U R                   R                  < SU R                  < SU R                  < SU R                  < S3$ r   )rO   rP   r5   r`   r1   rS   s    rJ   rT   OutputArgument.__str__  s*    #'>>#:#:DIItX\XaXabbrV   rN   r   r   rN   rV   rJ   r    r      s    ?#4Jc HrV   r    c                   b    \ rS rSrSrSS jr\R
                  R                  \l        S r\rSr	g)r6   i  z3InOutArgument are never initialized in the routine.Nc                     U(       d  [        U5      n[        R                  XXEU5        [        R                  XU5        g rY   )r   r   rK   r   r   s          rJ   rK   InOutArgument.__init__  s1    +D1H$hIFD
3rV   c                     U R                   R                  < SU R                  < SU R                  < SU R                  < S3$ r   )rO   rP   r5   r1   r`   rS   s    rJ   rT   InOutArgument.__str__  ,    #'>>#:#:DIItyyOO 	rV   rN   r   )
rP   rj   rk   rl   rm   rK   r    rT   rn   rp   rN   rV   rJ   r6   r6     s,    =4
 &..66H HrV   r6   c                   0    \ rS rSrSr  SS jrS r\rSrg)r!   i  a%  An expression for a return value.

The name result is used to avoid conflicts with the reserved word
"return" in the Python language.  It is also shorter than ReturnValue.

These may or may not need a name in the destination (e.g., "return(x*y)"
might return a value without ever naming it).

Nc                    [        U[        [        45      (       d  [        S5      eUc  S[	        [        U5      5      -  nUc  [        U5      n[        U[        5      (       a=  [        U[        [        45      (       a  [        U/UR                  Q76 nO[        U5      nUc  Un[        R                  XUXVS9  [        R                  XU5        g)a  Initialize a return value.

Parameters
==========

expr : SymPy expression

name : Symbol, MatrixSymbol, optional
    The name of this return variable.  When used for code generation,
    this might appear, for example, in the prototype of function in a
    list of return values.  A dummy name is generated if omitted.

result_var : Symbol, Indexed, optional
    Something that can be used to assign a value to this variable.
    Typically the same as `name` but for Indexed this should be e.g.,
    "y[i]" whereas `name` should be the Symbol "y".  Defaults to
    `name` if omitted.

datatype : optional
    When not given, the data type will be guessed based on the
    assumptions on the expr argument.

dimensions : sequence containing tuples, optional
    If present, this variable is interpreted as an array,
    where this sequence of tuples specifies (lower, upper)
    bounds for each index of the array.

precision : int, optional
    Controls the precision of floating point constants.

z.The first argument must be a SymPy expression.Nz	result_%d)r   r   r   )r/   r
   r   r   abshashr   r<   r   r   shaper   r   rK   r   )rA   r1   r5   r`   r   r   r   s          rJ   rK   Result.__init__  s    D $
 344LMM<T$Z0D+D1HdC  $Z 899#D64::6d|J$x%/ 	 	FD
3rV   c                     U R                   R                  < SU R                  < SU R                  < SU R                  < S3$ r   )rO   rP   r1   r5   r`   rS   s    rJ   rT   Result.__str__  r   rV   rN   )NNNNNr   rN   rV   rJ   r!   r!     s#     CG,074r HrV   r!   c                   Z    \ rS rSrSrSrS rSS jrS rSS jr	SS jr
SS	 jrSS
 jrSrg)r"   i  z'Abstract class for the code generators.Nc                 8    U R                   R                  U5      $ rY   )printerindent_coderA   	codeliness     rJ   _indent_codeCodeGen._indent_code  s    ||''	22rV   c                 t   U=(       d    0 nU Vs0 s H  oUU R                   R                  U   _M     nnUR                  5        H  u  pWXpR                   R                  U'   M     [        U R                   U5      " U0 UD6nUR                  5        H  u  pWXpR                   R                  U'   M     U$ s  snf rY   )r   	_settingsitemsgetattr)	rA   methodsettingsrg   kwargskorirb   results	            rJ   _printer_method_with_settings%CodeGen._printer_method_with_settings   s    >r5=>X$,,((++X>NN$DA()LL""1% %v.??IIKDA()LL""1%   ?s   #B5c                 :   U R                   R                  S   (       a+  U R                   R                  U5      nUR                  5       $ U R                   R                  U5      u  p4nU(       d  U(       a  [        S[	        U5      -  5      eUR                  5       $ )z&Returns the symbol as fcode prints it.humanzFailed to print %s)r   r   doprintr7   r<   strip)rA   rG   expr_str	constantsnot_supporteds        rJ   _get_symbolCodeGen._get_symbol*  sy    <<!!'*||++A.H
 ~~ 261E1Ea1H.IhM !5A!>??~~rV   c                     Xl         X l        g)zgInitialize a code generator.

Derived classes will offer more options that affect the generated
code.

Nprojectcse)rA   r   r   s      rJ   rK   CodeGen.__init__4  s     rV   c           
      @   U R                   (       Gar  SSKJ n  [        U5      (       a  [        U[        [
        45      (       d  U(       d  [        S5      eU H.  nUR                  (       a  M  [        SR                  U5      5      e   U Vs/ s H  ofR                  PM     nnU" U5      u  p[        X)5       VVs/ s H  u  pg[        UR                  U5      PM     nnnOO[        U[        5      (       a.  U" UR                  5      u  p[        UR                  U	S   5      nOU" U5      u  pU	nU V
Vs/ s H  u  p[        X5      PM     nn
nU V
Vs1 s H  u  pU
iM	     nn
n[        U VVs/ s H  u  pUPM	     snn6 nO
[        5       n[        U5      (       a6  [        U[        [
        45      (       d  U(       d  [        S5      e[        U6 nO[        U5      nU R                   (       aH  UR!                  ["        5       Vs1 s H  nUR$                  iM     sn['        5       :w  a  [        S5      eO1UR!                  ["        5       Vs1 s H  nUR$                  iM     nnUnUc
  ['        5       O
['        U5      nUR(                  UR(                  -  W-
  U-
  n['        5       nUR+                  U5        U Hy  n[        U["        5      (       a9  UR-                  U5        UR+                  UR.                  S   R(                  5        [        U[0        5      (       d  Mh  UR-                  U5        M{     Un/ n/ nU GH.  n[        U[        5      (       Ga]  UR                  nUR                  n[        U[0        5      (       aP  [3        UR4                   Vs/ s H  n[6        R8                  US-
  4PM     sn5      nUR:                  R$                  nOv[        U[<        5      (       a  / nUnO\[        U[>        5      (       a<  [3        UR4                   Vs/ s H  n[6        R8                  US-
  4PM     sn5      nUnO[        S5      eURA                  U5      (       a  URC                  [E        UUUUS95        OURC                  [G        UUUUS95        UW;  a  UR-                  U5        GMt  GMw  [        U[H        [J        45      (       a  [?        S	[M        [O        U5      5      -  /UR4                  Q76 n[3        UR4                   Vs/ s H  n[6        R8                  US-
  4PM     sn5      nURC                  [G        UUUUS95        GM  URC                  [        U5      5        GM1     / nS
 n0 nUR!                  [0        5      UR!                  [0        5      -   H  nUUUR:                  R$                  '   M     UR!                  [>        5      UR!                  [>        5      -   H  nUUU'   M
     [Q        U[R        S9 H6  nUU;   a  UU   nSU" U5      0nO0 nURC                  [U        U40 UD65        M8     URW                  S S9  URY                  U5        UGb  / nU HF  n [        U [Z        5      (       a  URC                  U R$                  5        M5  URC                  U 5        MH     UnU V!s/ s H  n!U!R\                  U;  d  M  U!PM     n"n!U"(       aR  Sn#U#R                  SR_                  U" V$s/ s H  n$[S        U$R\                  5      PM     sn$5      5      n#[a        U#U"5      eU V!s0 s H  n!U!R\                  U!_M     n%n!/ n&U H  n U&RC                  U%U   5        M     U&n[e        UUUWU5      $ s  snf s  snnf s  snn
f s  snn
f s  snnf s  snf s  snf s  snf s  snf s  snf s  sn!f s  sn$f s  sn!f ! [b         aG    [        U[Z        [>        45      (       a  SU" U5      0nO0 nU&RC                  [U        U40 UD65         M  f = f)a)  Creates an Routine object that is appropriate for this language.

This implementation is appropriate for at least C/Fortran.  Subclasses
can override this if necessary.

Here, we assume at most one return value (the l-value) which must be
scalar.  Additional outputs are OutputArguments (e.g., pointers on
right-hand-side or pass-by-reference).  Matrices are always returned
via OutputArguments.  If ``argument_sequence`` is None, arguments will
be ordered alphabetically, but with all InputArguments first, and then
OutputArgument and InOutArguments.

r   )r   No expression givenz7Lists of expressions must all be Equalities. {} is not.z9CSE and Indexed expressions do not play well together yet   BOnly Indexed, Symbol, or MatrixSymbol can define output arguments.r   zout_%sc                 l    U R                    Vs/ s H  n[        R                  US-
  4PM     sn$ s  snf Nr   )r   r   Zero)rG   dims     rJ   r   #CodeGen.routine.<locals>.dimensions  s+    129#QVVS1W%999s   1keyr   c                 ,    [        U R                  5      $ rY   r<   r5   rI   s    rJ   <lambda>!CodeGen.routine.<locals>.<lambda>      s166{rV   "Argument list didn't specify: {0} r-   )3r   sympy.simplify.cse_mainr   r/   r   r   r7   is_Equalityr   rQ   rhszipr   lhsr!   r   r3   r   r8   r.   r2   r0   removerg   r   r   r   r   r   baser   r   hasappendr6   r    r   r   r   r   sortedr<   r   sortrf   r   r5   r;   CodeGenArgumentListErrorr   r   )'rA   r5   r1   argument_sequencer@   r   er  common
simplifiedabr?   _rF   local_expressionsexpressionsirC   new_symbolssymbol
return_valoutput_argsout_argr   dimsarg_listr   array_symbolsarraymetadatanew_sequencerD   rI   missingmsgmname_arg_dictnew_argss'                                          rJ   routineCodeGen.routine>  s    88834  D:z:R)S)S$%:;;A===*+d+k+klm+noo 
 '++duud+%(X" <?t;PQ;P,;PQdH--),TXX&F#DHHjm<D),T&F%D178#!&+J8*01&31Q&M1 %V'<VcaV'< = %tZz:6N%O%O !677,K+K88!,!2!23!78!7A!78CEA"#^__ B ,7+<+<S+AB+Aa!''+AJB&M  +2ceK8H ++.?.L.LLP]]`kke7#F&#&&""6*""6;;q>#>#>?&'**""6*   
D$))((xxgw// !NAFFC!G#4!NOD$\\//F00D$F66 !NAFFC!G#4!NOD$F& (F G G 88F##&&%fgtMO  &&&vwNP +NN6* , D?K"@AA&x#d4j/'AODJJO7==I=CqvvsQw/=IJ"""7GTdKM !!&,/G  J 
	:  &&w/2C2I2I'2RRE.3M%****+ S &&|47H7N7N|7\\E#(M%  ] W#.F&%f-(*U*;<OOM&=H=> / 	23$(L(c;// ''		2 '',	 )
 !-"*N(Qaff<M.Mq(GN:jj+IACK+I!JK.sG<< 1991QVVQYM9H+GOOM&$9: ,  HtXz:{KKe , R 91'< 9 C6 "O "O( JT O ,J :
   G!&;*EFF$0*V2D#E#%OOM&$EH$EFGsg   ^="^7^^1^
^$^)^.
^3
^8
 ^=^=_=__A``c           
      |   U(       aF  U R                    H5  nU< SUR                  < 3n[        US5       nU" XXXE5        SSS5        M7     g/ n	U R                    HJ  nU< SUR                  < 3n[        5       n
U" XXXE5        U	R	                  XzR                  5       45        ML     U	$ ! , (       d  f       M  = f)a  Writes all the source code files for the given routines.

The generated source is returned as a list of (filename, contents)
tuples, or is written to files (see below).  Each filename consists
of the given prefix, appended with an appropriate extension.

Parameters
==========

routines : list
    A list of Routine instances to be written

prefix : string
    The prefix for the output files

to_files : bool, optional
    When True, the output is written to files.  Otherwise, a list
    of (filename, contents) tuples is returned.  [default: False]

header : bool, optional
    When True, a header comment is included on top of each source
    file. [default: True]

empty : bool, optional
    When True, empty lines are included to structure the source
    files. [default: True]

.wN)dump_fns	extensionopenr   r  getvalue)rA   routinesprefixto_filesheaderemptydump_fnfilenamefr   contentss              rJ   writeCodeGen.write  s    : ==&,g.?.?@(C(ADAvE )( )
 F==&,g.?.?@#:&Hx):):)<=>	 )
 M )(s   B,,
B;	c                    U R                  U5      nU GH  nU(       a  UR                  S5        UR                  U R                  U5      5        UR                  U R	                  U5      5        UR                  U R                  U5      5        UR                  U R                  U5      5        U(       a  UR                  S5        UR                  U R                  U5      5        U(       a  UR                  S5        UR                  U R                  U5      5        GM     U R                  SR                  U5      5      nU(       a#  SR                  U R                  5       U/-   5      nU(       a  UR                  U5        gg)a  Write the code by calling language specific methods.

The generated file contains all the definitions of the routines in
low-level code and refers to the header file if appropriate.

Parameters
==========

routines : list
    A list of Routine instances.

f : file-like
    Where to write the file.

prefix : string
    The filename prefix, used to refer to the proper header file.
    Only the basename of the prefix is used.

header : bool, optional
    When True, a header comment is included on top of each source
    file.  [default : True]

empty : bool, optional
    When True, empty lines are included to structure the source
    files.  [default : True]


r|   N)_preprocessor_statementsr  rf   _get_routine_opening_declare_arguments_declare_globals_declare_locals_call_printer_get_routine_endingr   r;   _get_headerr8  )rA   r/  r6  r0  r2  r3  
code_linesr&  s           rJ   	dump_codeCodeGen.dump_code  s7   : 226:
G!!$'d77@Ad55g>?d33G<=d227;<!!$'d009:!!$'d66w?@   &&rwwz':;
!1!1!3zl!BCJGGJ rV   )r   r   rY   )r   F)NN)FTTTT)rP   rj   rk   rl   rm   r   r   r   r   rK   r&  r8  rE  rp   rN   rV   rJ   r"   r"     s1    1G3 lL\)V3 rV   r"   c                       \ rS rSrSrg)r   iM  rN   Nr   rN   rV   rJ   r   r   M  r   rV   r   c                   $    \ rS rSr\S 5       rSrg)r  iQ  c                      U R                   S   $ r   )rg   rS   s    rJ   missing_args%CodeGenArgumentListError.missing_argsR  s    yy|rV   rN   N)rP   rj   rk   rl   ro   rK  rp   rN   rV   rJ   r  r  Q  s     rV   r  z{Code generated with SymPy %(version)s

See http://www.sympy.org/ for more information.

This file is part of '%(project)s'
c                      ^  \ rS rSrSrSrSrSr  SU 4S jjrS r	S r
S	 rS
 rS rS rS rS rS rSS jr\\l        \R*                  R                  \l        SS jr\\l        \\/rSrU =r$ )r#   i_  zGenerator for C code.

The .write() method inherited from CodeGen will output a code file and
an interface file, <prefix>.c and <prefix>.h respectively.

chc99c                    > [         TU ]  XS9  U=(       d&    [        U R                  R	                  5          " 5       U l        X0l        Uc	  S/U l        g g )Nr   z#include <math.h>)superrK   r   standardlowerr   preprocessor_statements)rA   r   r   rU  r   rO   s        rJ   rK   CCodeGen.__init__k  sP    2J/$--2E2E2G"H"J'>$"*,?+@D( +rV   c                     / nUR                  S5        [        [        U R                  S.-  nUR	                  5        H&  nUR                  SUR                  S5      -  5        M(     UR                  S5        U$ )/Writes a common header for the generated files.zP/******************************************************************************
versionr   z *%s*
L   zQ ******************************************************************************/
r  header_commentsympy_versionr   
splitlinescenterrA   rD  tmplines       rJ   rC  CCodeGen._get_headert  so    
-.=+/<< 9 9NN$Di$++b/9: %./rV   c                    [        UR                  5      S:  a  [        S5      e[        UR                  5      S:X  a  UR                  S   R                  S5      nOSn/ nUR                   H  nU R
                  R                  UR                  5      nUR                  (       d  [        U[        5      (       a'  UR                  UR                  S5      SU-  45        Mu  UR                  UR                  S5      U45        M     SR                  U Vs/ s H  nSU-  PM
     sn5      nU< S	UR                  < S
U< S3$ s  snf )Returns a string for the function prototype of the routine.

If the routine has multiple result objects, an CodeGenError is
raised.

See: https://en.wikipedia.org/wiki/Function_prototype

r   z,C only supports a single or no return value.r   r   void*%sr-   z%s %s r   r   )lenr>   r   r   r=   r   r   r5   r   r/   r   r  r;   )rA   r&  ctype	type_argsrD   r5   tr=   s           rJ   get_prototypeCCodeGen.get_prototype  s
    w!#MNN!Q&OOA&33C8EE	$$C<<''1D~~C!<!<  #"2"23"7!FG  #"2"23"7!>? % IIY?Y!Y?@	#W\\9== @s   Ec                    / nUR                  SR                  [        R                  R	                  U5      5      5        UR                  U R                  5        U Vs/ s H  nSR                  U5      PM     nnU$ s  snf )Nz#include "{}.h"z{}
)r  rQ   ospathbasenamerf   rU  )rA   r0  rD  ls       rJ   r<  !CCodeGen._preprocessor_statements  sl    
+222773C3CF3KLM$6670:;
1fmmA&

; <s   A>c                 0    U R                  U5      nSU-  /$ Nz%s {
rn  rA   r&  	prototypes      rJ   r=  CCodeGen._get_routine_opening       &&w/	9$%%rV   c                     / $ rY   rN   rA   r&  s     rJ   r>  CCodeGen._declare_arguments      	rV   c                     / $ rY   rN   r~  s     rJ   r?  CCodeGen._declare_globals  r  rV   c           
         / nUR                    HH  n[        U[        5      (       d  M  UR                  (       a  M-  UR	                  UR
                  5        MJ     / nUR                   GHc  n[        U[        5      (       d  M  UR
                  UR                  :w  a  [        SR                  U5      5      eUR
                  nUR                  S5      n[        UR                  [        [        45      (       aM  UR                  R                  nUR	                  SR                  U[!        U5      US   US   -  5      5        Sn	OSR                  U5      n	U R#                  SS	US	S
.UR                  US9u  pn[%        U
[         S9 H  u  pUR	                  SU< SU< S35        M!     UR	                  SR                  X5      5        GMf     U$ )Nz)Result variable and name should match: {}rN  z{} {}[{}];
r   r   r|   z	const {} r   Fr   dereferencestrict	assign_tor   double const  = ;
z{}{}
)r=   r/   r   r   r  r5   r?   r!   r`   r"   rQ   r   r1   r   r   r   r<   r   r	  )rA   r&  r  rD   rD  r   r  rm  r  r0  r   not_cc_exprr5   values                  rJ   r@  CCodeGen._declare_locals  s   
 $$C#z**3>>>""388, % 
((F ff--{{f///IPPQWXYYI##C(A&++
J'?@@{{((!!."7"73y>4PQ7SWXYSZ?"[\$++A.'+'I'IU;RWXy (J (2$If  &iS9!!tU"KL  : hoof=>3 )6 rV   c           	         / n/ nUR                    HH  n[        U[        5      (       d  M  UR                  (       a  M-  UR	                  UR
                  5        MJ     S nUR                   H  n[        U[        5      (       aM  UR
                  S-   nUR                  S5      nUR	                  SR                  U[        U5      5      5        UnOUR                  n U R                  SSUSS.UR                  US9u  pn[        U	[        S
9 H  u  pUR	                  SU< SU< S	35        M!     UR	                  SU-  5        M     U(       a  UR	                  SU-  5        U$ ! [         ac    UR                  nUR	                  UR                  S5      < S[        U5      < S	35        U R                  SSUSS.UR                  US9u  pn Nf = f)N_resultrN  z{} {};
r   Fr  r  ri  r  r   r  r  %s
z   return %s;
)r=   r/   r   r   r  r5   rh   r!   r   rQ   r<   r`   r   r1   r   r	  )rA   r&  rD  r  rD   r  r   r  rm  r   r  r  r5   r  s                 rJ   rA  CCodeGen._call_printer  s   

 $$C#z**3>>>""388, % 
..F&&))#LL94	'',!!*"3"3As9~"FG&
"--	
6+/+M+M{V[\KK9 ,N ,6(	&  &iS9!!tU"KL  :fvo./ /2 /*<= # 6"--	!!"("5"5c":C	NKM+/+M+M{V[\KK9 ,N ,6(	&	6s   #E&&A*GGc                     S/$ Nz}
rN   r~  s     rJ   rB  CCodeGen._get_routine_ending  	    wrV   c                 *    U R                  XX4U5        g rY   rE  rA   r/  r6  r0  r2  r3  s         rJ   dump_cCCodeGen.dump_c       xFE:rV   c                    U(       a'  [        SR                  U R                  5       5      US9  U R                  R	                  SS5      R                  5       < SUR	                  SS5      R                  5       < S3nU(       a	  [        US9  [        SU-  US9  [        S	U-  US9  U(       a	  [        US9  U H!  nU R                  U5      n[        S
U-  US9  M#     U(       a	  [        US9  [        SUS9  U(       a
  [        US9  gg)a,  Writes the C header file.

This file contains all the function declarations.

Parameters
==========

routines : list
    A list of Routine instances.

f : file-like
    Where to write the file.

prefix : string
    The filename prefix, used to construct the include guards.
    Only the basename of the prefix is used.

header : bool, optional
    When True, a header comment is included on top of each source
    file.  [default : True]

empty : bool, optional
    When True, empty lines are included to structure the source
    files.  [default : True]

r|   fileri  r  __/__Hz
#ifndef %sz
#define %sz%s;z#endifN)printr;   rC  r   replacer   rn  )	rA   r/  r6  r0  r2  r3  
guard_namer&  rz  s	            rJ   dump_hCCodeGen.dump_h  s    6 "''$**,-A6$(LL$8$8%eg%%~~c37==?A
 qMlZ'a0lZ'a0qMG**73I%)#!,   qMhQqM rV   )rU  r   )r   NNFrG  )rP   rj   rk   rl   rm   code_extensioninterface_extensionrS  rK   rC  rn  r<  r=  r>  r?  r@  rA  rB  r  r,  r"   rE  r  r+  rp   __classcell__rO   s   @rJ   r#   r#   _  s     NH2638A	>4&&P'R;%F&&..FN/` +F HrV   r#   c                       \ rS rSrSrSrg)
C89CodeGeni;  C89rN   NrP   rj   rk   rl   rS  rp   rN   rV   rJ   r  r  ;      HrV   r  c                       \ rS rSrSrSrg)
C99CodeGeni>  C99rN   Nr  rN   rV   rJ   r  r  >  r  rV   r  c                      ^  \ rS rSrSrSrSrSU 4S jjrS rS r	S r
S	 rS
 rS rS rS rS rS rSS jr\\l        \R*                  R                  \l        SS jr\\l        \\/rSrU =r$ )r$   iA  zGenerator for Fortran 95 code

The .write() method inherited from CodeGen will output a code file and
an interface file, <prefix>.f90 and <prefix>.h respectively.

f90rO  c                 T   > [         TU ]  U5        U=(       d
    [        5       U l        g rY   )rR  rK   r   r   rA   r   r   rO   s      rJ   rK   FCodeGen.__init__L  s    !0,.rV   c                     / nUR                  S5        [        [        U R                  S.-  nUR	                  5        H&  nUR                  SUR                  S5      -  5        M(     UR                  S5        U$ )rX  zP!******************************************************************************
rY  z!*%s*
r[  r\  ra  s       rJ   rC  FCodeGen._get_headerP  so    
-.=|| % %NN$Di$++b/9: %-.rV   c                     / $ rY   rN   rA   r0  s     rJ   r<  !FCodeGen._preprocessor_statements[      	rV   c                 d  ^  / n[        UR                  5      S:  a  [        S5      e[        UR                  5      S:X  aA  UR                  S   nUR                  UR	                  S5      5        UR                  S5        OUR                  S5        SR                  U 4S jUR                   5       5      nS	R                  UR                  U5      nS
R                  [        R                  " USSS95      S-   nUR                  U5        SR                  U5      /nUR                  S5        U$ )z6Returns the opening statements of the fortran routine.r   z2Fortran only supports a single or no return value.r   fortranfunction
subroutiner-   c              3   `   >#    U  H#  nS TR                  UR                  5      -  v   M%     g7f)%sN)r   r5   )r[   rD   rA   s     rJ   r\   0FCodeGen._get_routine_opening.<locals>.<genexpr>k  s,      6#4C  0 0 ::#4s   +.z{}({})
z &
<   F)widthbreak_long_wordsr;  ri  zimplicit none
)rj  r>   r   r  r   r;   r=   rQ   r5   textwrapwrap)rA   r&  	code_listr   rg   call_sigs   `     rJ   r=  FCodeGen._get_routine_opening^  s   	w!#DF F!Q&__Q'FV00;<Z(\*yy 6#*#4#46 6 $$W\\48 ;;x}}X35>C E FHLM 	"XXi()	*+rV   c                 >   / n/ n/ nUR                    GH^  n[        U[        5      (       a  SUR                  S5      -  nOk[        U[        5      (       a  SUR                  S5      -  nOA[        U[
        5      (       a  SUR                  S5      -  nO[        S[        U5      -  5      eU R                  nUR                  (       a  SR                  UR                   Vs/ s H$  nU" US   S-   5      < S	U" US   S-   5      < 3PM&     sn5      n	US
U	-  -  nUR                  U< SU" UR                  5      < S35        GM5  UR                  U< SU" UR                  5      < S35        GMa     UR                  U5        UR                  U5        U$ s  snf )Nz%s, intent(in)r  z%s, intent(inout)z%s, intent(out)zUnknown Argument type: %sr-   r   r   :z, dimension(%s) :: r;  )r=   r/   r   r   r6   r    r   typer   r   r;   r  r5   rf   )
rA   r&  r  
array_listscalar_listrD   typeinfofprintr   dimstrs
             rJ   r>  FCodeGen._declare_argumentsy  so   	
$$C#}--+c.>.>y.IIC//.1A1A)1LLC00,s/?/?	/JJ"#>c#JKK%%F~~"~~$/- 3q6A:&s1vz(:%<-$/ 0 -66!!(F388<L"MN""8VCHH=M#NO+ %0 	%$$/s   "+F
c                     / $ rY   rN   r~  s     rJ   r?  FCodeGen._declare_globals  s	     	rV   c                     / n[        UR                  [        S9 H@  n[        U5      nUR	                  UR
                  < SU R                  U5      < S35        MB     U$ )Nr   r  r;  )r	  r?   r<   r   r  ru   r   )rA   r&  r  varr  s        rJ   r@  FCodeGen._declare_locals  sW    	',,#6C+C0H 0 0 57 8 7 rV   c                 @    [        UR                  5      S:X  a  S/$ S/$ )z6Returns the closing statements of the fortran routine.r   zend function
zend subroutine
)rj  r>   r~  s     rJ   rB  FCodeGen._get_routine_ending  s%    w1$$%%&''rV   c                    S/nUR                  U R                  U5      5        UR                  U R                  U5      5        UR                  U R                  U5      5        UR	                  S5        SR                  U5      $ )zReturns a string for the function interface.

The routine should have a single result object, which can be None.
If the routine has multiple result objects, a CodeGenError is
raised.

See: https://en.wikipedia.org/wiki/Function_prototype

z
interface
zend interface
r|   )rf   r=  r>  rB  r  r;   ry  s      rJ   get_interfaceFCodeGen.get_interface  su     $%	227;<009:11':;*+wwy!!rV   c           
         / n/ nUR                    GH5  n[        U[        5      (       a  UR                  nO'[        U[        [
        45      (       a  UR                  nU R                  SSSSSS.UR                  WS9u  pgn[        U[        S9 H7  u  p[        U	5      nUR                  UR                  < SU	< S	U
< S
35        M9     [        U[        S9 HU  n	[        U	5      n[        U	[        5      (       a  U	R                  nOU	nUR                  UR                  < SU< S
35        MW     UR                  SU-  5        GM8     X#-   $ )Nr   Ffree_   )r   source_formatrS  r  r  r   z, parameter :: r  r;  r  r  )rh   r/   r!   r5   r    r6   r`   r   r1   r	  r<   r   r  ru   r	   func)rA   r&  declarationsrD  r   r  r   not_fortranf_exprobjrb   rm  r5   s                rJ   rA  FCodeGen._call_printer  s-   
..F&&))#LL	F^]$CDD"--	-1-O-OUVQS_dey .P .2*IF !4(-##45GGS!DF 5 ks3(-c8,,88DD##AGGT$BC 4 fvo.- /. ((rV   c                 0    U R                  SSSSS.U5      $ )Nr   Fr  )r   r  r  r   r   s     rJ   r   FCodeGen._indent_code  s&    11UVuUW`b 	brV   c                    U H  nUR                    Vs1 s H  n[        U5      R                  5       iM     nnUR                    Vs1 s H  n[        U5      iM     n	n[        U5      [        U	5      :  d  Mu  [	        SSR                  UR                    V
s/ s H  n
[        U
5      PM     sn
5      -  5      e   U R                  XX4U5        g s  snf s  snf s  sn
f )Nz%Fortran ignores case. Got symbols: %sr-   )rc   r<   rT  rj  r   r;   rE  )rA   r/  r6  r0  r2  r3  rE   rI   	lowercase	orig_caser  s              rJ   dump_f95FCodeGen.dump_f95  s    A12=AQI=)*5AQI59~I."#J#DCH#DE$G H H	  	xFE: >5 $Es   #CCCc                     U(       a'  [        SR                  U R                  5       5      US9  U(       a	  [        US9  U H%  nU R                  U5      nUR	                  U5        M'     U(       a
  [        US9  gg)a  Writes the interface to a header file.

This file contains all the function declarations.

Parameters
==========

routines : list
    A list of Routine instances.

f : file-like
    Where to write the file.

prefix : string
    The filename prefix.

header : bool, optional
    When True, a header comment is included on top of each source
    file.  [default : True]

empty : bool, optional
    When True, empty lines are included to structure the source
    files.  [default : True]

r|   r  N)r  r;   rC  r  r8  )rA   r/  r6  r0  r2  r3  r&  rz  s           rJ   r  FCodeGen.dump_h  sd    4 "''$**,-A6qMG**73IGGI   qM rV   r   r   NrG  )rP   rj   rk   rl   rm   r  r  rK   rC  r<  r=  r>  r?  r@  rB  r  rA  r   r  r,  r"   rE  r  r+  rp   r  r  s   @rJ   r$   r$   A  s     N1	6 D
("$)8b; (H((00H#H +F &!HrV   r$   c                      ^  \ rS rSrSrSrSU 4S jjrS rS rS r	S r
S	 rS
 rS rS rS rS rSS jr\\l        \R(                  R                  \l        \/rSrU =r$ )r%   i  zlGenerator for Julia code.

The .write() method inherited from CodeGen will output a code file
<prefix>.jl.

jlc                 T   > [         TU ]  U5        U=(       d
    [        5       U l        g rY   )rR  rK   r   r   r  s      rJ   rK   JuliaCodeGen.__init__"  s     !4"2"4rV   c           
         [        U5      (       a6  [        U[        [        45      (       d  U(       d  [	        S5      e[        U6 nO[        U5      nUR                  [        5       Vs1 s H  ofR                  iM     nnUc
  [        5       O
[        U5      nUR                  U-
  U-
  n[        5       n	U Hj  n
[        U
[        5      (       a*  U	R                  U
R                  S   R                  5        MB  [        U
[        5      (       a  MY  U	R                  U
5        Ml     / n/ n[        U5       GHA  u  pb[        U[         5      (       Ga  UR"                  nUR$                  nUn[        U[        5      (       af  ['        UR(                   Vs/ s H  n[*        R,                  U4PM     sn5      nUR.                  R                  nUR1                  [3        XUUS95        [        U[        [4        [6        45      (       d  [9        S5      eUR1                  [;        X.US95        UR=                  U5      (       d  U	R?                  U5        GM  GM"  UR1                  [;        USUS-   -  S95        GMD     URA                  S S	9  [C        U5      n0 nUR                  [        5       H  nUUUR.                  R                  '   M     UR                  [6        5       H  nUUU'   M
     [E        U	[F        S	9 H  nUR1                  [I        U5      5        M     UGb  / nU HF  n[        U[J        5      (       a  UR1                  UR                  5        M5  UR1                  U5        MH     UnU Vs/ s H  nURL                  U;  d  M  UPM     nnU(       aR  S
nURO                  SRQ                  U Vs/ s H  n[G        URL                  5      PM     sn5      5      n[S        UU5      eU Vs0 s H  nURL                  U_M     nn/ nU H  n UR1                  UU   5        M     Un[W        UUXU5      $ s  snf s  snf s  snf s  snf s  snf ! [T         a    UR1                  [I        U5      5         Ml  f = f)z'Specialized Routine creation for Julia.r   r   r   r   r5   r`   out%drZ   c                 ,    [        U R                  5      $ rY   r   r   s    rJ   r   &JuliaCodeGen.routine.<locals>.<lambda>Z  r   rV   r   r   r-   ),r   r/   r   r   r7   r   r3   r   r8   r.   r2   r0   rg   r   r4   	enumerater   r  r  r   r   r   Oner  r  r6   r   r   r   r!   r  r  r
  r   r	  r<   r   r   r5   rQ   r;   r  r   r   )rA   r5   r1   r  r@   r  r  r?   old_symbolsrC   rG   return_valsr  r  r  r   r  r  r  r  r   rD   rI   r!  r"  r#  r$  r%  s                               rJ   r&  JuliaCodeGen.routine&  s    tZz:6N%O%O !677,K+K (3'8'8'=>'=!gg'=
>  +2ceK8H "..;kI%A!S!!qvvay5567++A	  ";/IQ$))((xx gw// 7==!I=CAEE3<=!IJD$\\//F&&}VdW['\]!'GV\+JKK& (F G G ""6$#PQxx'' NN6* ( ""6$W!_#EF+ 00 	23$ &&w/E.3M%****+ 0 &&|4E#(M%  5 W#.FOOM&12 / (L(c;// ''		2 '',	 )
 !-"*N(Qaff<M.Mq(GN:jj+IACK+I!JK.sG<< 1991QVVQYM9H+;OOM&$9: ,
  HtX{LL] ?. "JN O ,J :
   ;OOM&$9:;s6   )P9P>
3QQ6Q0QQ$Q:9Q:c                     / n[         [        U R                  S.-  nUR                  5        H0  nUS:X  a  UR	                  S5        M  UR	                  SU-  5        M2     U$ )rX  rY  r|   z#
z#   %s
r]  r^  r   r_  r  ra  s       rJ   rC  JuliaCodeGen._get_header  s`    
=|| % %NN$Drz!!%(!!*t"34	 %
 rV   c                     / $ rY   rN   r  s     rJ   r<  %JuliaCodeGen._preprocessor_statements  r  rV   c           	         / nUR                  S5        / nUR                   H  n[        U[        5      (       a   [	        S[        [        U5      5      -  5      e[        U[        [        45      (       d  MU  UR                  SU R                  UR                  5      -  5        M     SR                  U5      nUR                  UR                  < SU< S35        SR                  U5      /nU$ ).Returns the opening statements of the routine.	function z"Julia: invalid argument of type %sr  r-   r   )
r|   )r  r=   r/   r    r   r<   r  r   r6   r   r5   r;   )rA   r&  r  rg   rD   s        rJ   r=  !JuliaCodeGen._get_routine_opening  s    	% $$C#~.."#G#&tCy>$2 3 3#}=>>D4#3#3CHH#==> % yyw||T:;ggi(*	rV   c                     / $ rY   rN   r~  s     rJ   r>  JuliaCodeGen._declare_arguments  r  rV   c                     / $ rY   rN   r~  s     rJ   r?  JuliaCodeGen._declare_globals  r  rV   c                     / $ rY   rN   r~  s     rJ   r@  JuliaCodeGen._declare_locals  r  rV   c                     / nUR                    HP  n[        U[        5      (       a  U R                  UR                  5      nO[        S5      eUR                  U5        MR     SSR                  U5      -   S-   /$ )N$unexpected object in Routine resultszreturn r-   z
end
)r>   r/   r!   r   r5   r   r  r;   )rA   r&  outsr   rG   s        rJ   rB   JuliaCodeGen._get_routine_ending  sj    ooF&&))$$V[[1"#IJJKKN & DIIdO+i788rV   c                    / n/ nUR                    H  n[        U[        5      (       a  UR                  nO[	        S5      eU R                  SSSS.UR                  US9u  pgn[        U[        S9 H  u  pUR                  U	< SU
< S35        M      [        U[        S9 H;  n	[        U	[        5      (       a  U	R                  nOU	nUR                  S	U-  5        M=     UR                  S
U-  5        M     X#-   $ )Nr  r   Fr   r  r  r   r  r;  z# unsupported: %s
r  r>   r/   r!   r`   r   r   r1   r	  r<   r  r	   r  )rA   r&  r  rD  r   r  r   r   jl_exprr  rb   r5   s               rJ   rA  JuliaCodeGen._call_printer  s    
ooF&&))"--	"#IJJ040R0RUe<fkkU^ 1S 1`-Ig !4###&*, 5 m5c8,,88DD##)T24 6 f01' &( ((rV   c                 @    [        SSS.5      nUR                  U5      $ )NFr  )r   r   )rA   r   ps      rJ   r   JuliaCodeGen._indent_code  s"     u>?}}Y''rV   c                 *    U R                  XX4U5        g rY   r  r  s         rJ   dump_jlJuliaCodeGen.dump_jl  r  rV   r  r  rG  )rP   rj   rk   rl   rm   r  rK   r&  rC  r<  r=  r>  r?  r@  rB  rA  r   r$  r,  r"   rE  r+  rp   r  r  s   @rJ   r%   r%     st     N5YMv
&	9)2(; 'G''//GO yHrV   r%   c                      ^  \ rS rSrSrSrSU 4S jjrS rS rS r	S r
S	 rS
 rS rS rS rS rSS jr\\l        \R(                  R                  \l        \/rSrU =r$ )r&   i  a  Generator for Octave code.

The .write() method inherited from CodeGen will output a code file
<prefix>.m.

Octave .m files usually contain one function.  That function name should
match the filename (``prefix``).  If you pass multiple ``name_expr`` pairs,
the latter ones are presumed to be private functions accessed by the
primary function.

You should only pass inputs to ``argument_sequence``: outputs are ordered
according to their order in ``name_expr``.

r#  c                 T   > [         TU ]  U5        U=(       d
    [        5       U l        g rY   )rR  rK   r   r   r  s      rJ   rK   OctaveCodeGen.__init__  s     !5"3"5rV   c           
         [        U5      (       a6  [        U[        [        45      (       d  U(       d  [	        S5      e[        U6 nO[        U5      nUR                  [        5       Vs1 s H  ofR                  iM     nnUc
  [        5       O
[        U5      nUR                  U-
  U-
  n[        5       n	U Hj  n
[        U
[        5      (       a*  U	R                  U
R                  S   R                  5        MB  [        U
[        5      (       a  MY  U	R                  U
5        Ml     / n[        U5       H  u  pb[        U[         5      (       a  UR"                  nUR$                  nUn[        U[        5      (       a  UR&                  R                  n[        U[        [(        [*        45      (       d  [-        S5      eUR/                  [1        X-US95        UR3                  U5      (       d  U	R5                  U5        M  M  UR/                  [1        USUS-   -  S95        M     / n0 nUR                  [        5       H  nUUUR&                  R                  '   M     UR                  [*        5       H  nUUU'   M
     [7        U	[8        S9 H  nUR/                  [;        U5      5        M     UGb  / nU HF  n[        U[<        5      (       a  UR/                  UR                  5        M5  UR/                  U5        MH     UnU Vs/ s H  nUR>                  U;  d  M  UPM     nnU(       aR  SnURA                  S	RC                  U Vs/ s H  n[9        UR>                  5      PM     sn5      5      n[E        UU5      eU Vs0 s H  nUR>                  U_M     nn/ nU H  n UR/                  UU   5        M     Un[I        XXU5      $ s  snf s  snf s  snf s  snf ! [F         a    UR/                  [;        U5      5         Mf  f = f)
z(Specialized Routine creation for Octave.r   r   r   r  r  rZ   r   r   r-   )%r   r/   r   r   r7   r   r3   r   r8   r.   r2   r0   rg   r   r4   r  r   r  r  r  r   r   r   r  r!   r  r  r	  r<   r   r   r5   rQ   r;   r  r   r   )rA   r5   r1   r  r@   r  r  r?   r  rC   rG   r  r  r  r  r  r  r   rD   rI   r!  r"  r#  r$  r%  s                            rJ   r&  OctaveCodeGen.routine  su    tZz:6N%O%O !677,K+K (3'8'8'=>'=!gg'=
>  +2ceK8H "..;kI%A!S!!qvvay5567++A	  ";/IQ$))((xx gw//$\\//F!'GV\+JKK& (F G G ""6$#PQxx'' NN6* ( ""6$W!_#EF' 0,  &&w/E.3M%****+ 0 &&|4E#(M%  5 W#.FOOM&12 / (L(c;// ''		2 '',	 )
 !-"*N(Qaff<M.Mq(GN:jj+IACK+I!JK.sG<< 1991QVVQYM9H+;OOM&$9: ,
  Ht{LLU ?t O ,J :
   ;OOM&$9:;s0   )OOOO O!O$PPc                     / n[         [        U R                  S.-  nUR                  5        H0  nUS:X  a  UR	                  S5        M  UR	                  SU-  5        M2     U$ )rX  rY  r|   z%
z%%   %s
r  ra  s       rJ   rC  OctaveCodeGen._get_headerQ  s`    
=|| % %NN$Drz!!%(!!+"45	 %
 rV   c                     / $ rY   rN   r  s     rJ   r<  &OctaveCodeGen._preprocessor_statements]  r  rV   c           	      r   / nUR                  S5        / nUR                   HP  n[        U[        5      (       a  U R	                  UR
                  5      nO[        S5      eUR                  U5        MR     [        U5      S:  a'  UR                  SSR                  U5      -   S-   5        O UR                  SR                  U5      5        UR                  S5        / nUR                   H  n[        U[        [        45      (       a   [        S	[        [        U5      5      -  5      e[        U[        5      (       d  MU  UR                  S
U R	                  UR
                  5      -  5        M     SR                  U5      nUR                  UR
                  < SU< S35        SR                  U5      /nU$ )r  r  r  r   [r-   ]r|   r  z#Octave: invalid argument of type %sr  r   r  )r  r>   r/   r!   r   r5   r   rj  r;   r=   r    r6   r<   r  r   )rA   r&  r  r  r   rG   rg   rD   s           rJ   r=  "OctaveCodeGen._get_routine_opening`  sf   	% ooF&&))$$V[[1"#IJJKKN & t9q=SDIIdO4s:;RWWT]+ $$C#>??"#H#&tCy>$2 3 3#}--D4#3#3CHH#==> % yyw||T:;ggi(*	rV   c                     / $ rY   rN   r~  s     rJ   r>   OctaveCodeGen._declare_arguments  r  rV   c           
          UR                   (       d  / $ SR                  [        UR                    Vs/ s H  o R                  U5      PM     sn5      5      nSU-   S-   /$ s  snf )Nri  zglobal r;  )r@   r;   r	  r   )rA   r&  grG   s       rJ   r?  OctaveCodeGen._declare_globals  s[    ""IHHV':M:MN:MQ--a0:MNOPA$%% Os   A c                     / $ rY   rN   r~  s     rJ   r@  OctaveCodeGen._declare_locals  r  rV   c                     S/$ )Nzend
rN   r~  s     rJ   rB  !OctaveCodeGen._get_routine_ending  s
    yrV   c           	         / n/ nUR                    H  n[        U[        5      (       a  UR                  nO[	        S5      eU R                  SSSS.UR                  US9u  pgn[        U[        S9 H  u  pUR                  SU	< SU
< S	35        M!     [        U[        S9 H;  n	[        U	[        5      (       a  U	R                  nOU	nUR                  S
U-  5        M=     UR                  SU-  5        M     X#-   $ )Nr  r   Fr  r  r   z  r  z;  % constant
z  %% unsupported: %s
r  r  )rA   r&  r  rD  r   r  r   r   oct_exprr  rb   r5   s               rJ   rA  OctaveCodeGen._call_printer  s    
ooF&&))"--	"#IJJ151S1SUe<fkkU^ 2T 2`.Ih !4##36:< 5 m5c8,,88DD##,57 6 f12' &( ((rV   c                 .    U R                  SSSS.U5      $ )Nr   Fr  r  r   s     rJ   r   OctaveCodeGen._indent_code  s#    11Ue<iI 	IrV   c                    U R                  U5      n[        U5       GH  u  pUS:  a  U(       a  UR                  S5        UR                  U R	                  U	5      5        US:X  au  U	R
                  U:w  a  [        S5      eU(       aS  UR                  SUR                  5       -   S-   5        UR                  SR                  U R                  5       5      5        UR                  U R                  U	5      5        UR                  U R                  U	5      5        UR                  U R                  U	5      5        U(       a  UR                  S5        UR                  U R                  U	5      5        U(       a  UR                  S5        UR                  U R                  U	5      5        GM     U R                  SR                  U5      5      nU(       a  UR!                  U5        g g )Nr   r;  z(Octave function name should match prefix%z  Autogenerated by SymPy
r|   )r<  r  r  rf   r=  r5   r7   r   r;   rC  r>  r?  r@  rA  rB  r   r8  )
rA   r/  r6  r0  r2  r3  inlinerD  r  r&  s
             rJ   dump_mOctaveCodeGen.dump_m  s    226:
#H-JA1u%%d+d77@AAv<<6)$%OPP%%cFLLN&:&B'C D%%bggd.>.>.@&ABd55g>?d33G<=d227;<!!$'d009:!!$'d66w?@) ., &&rwwz':;
GGJ rV   r  r  )TTT)rP   rj   rk   rl   rm   r  rK   r&  rC  r<  r=  r>  r?  r@  rB  rA  r   rD  r,  r"   rE  r+  rp   r  r  s   @rJ   r&   r&     sw     N6XMt
 D&)2I @ &F&&..FN xHrV   r&   c                      ^  \ rS rSrSrSrSU 4S jjrS rS rS r	S r
S	 rS
 rS rS rS rS rSS jr\\l        \R(                  R                  \l        \/rSrU =r$ )r'   i  zjGenerator for Rust code.

The .write() method inherited from CodeGen will output a code file
<prefix>.rs

rsc                 P   > [         TU ]  US9  U=(       d
    [        5       U l        g )N)r   )rR  rK   r   r   r  s      rJ   rK   RustCodeGen.__init__  s"    )3/"3rV   c           
      .   [        U5      (       a6  [        U[        [        45      (       d  U(       d  [	        S5      e[        U6 nO[        U5      nUR                  [        5       Vs1 s H  ofR                  iM     nnUc
  [        5       O
[        U5      nUR                  U-
  U-
  UR                  [        5      -
  n/ n	/ n
[        U5       GH@  u  pb[        U[        5      (       Ga  UR                  nUR                  nUn[        U[        5      (       ae  [!        UR"                   Vs/ s H  n[$        R&                  U4PM     sn5      nUR(                  R                  nU
R+                  [-        XX.S95        [        U[        [.        [0        45      (       d  [3        S5      eU	R+                  [5        X,US95        UR7                  U5      (       d  UR9                  U5        GM  GM!  U	R+                  [5        USUS-   -  S95        GMC     U
R;                  S S	9  [=        U
5      n0 nUR                  [        5       H  nUUUR(                  R                  '   M     UR                  [0        5       H  nUUU'   M
     [?        U[@        S	9 H  nUR+                  [C        U5      5        M     UGb  / nU HF  n[        U[D        5      (       a  UR+                  UR                  5        M5  UR+                  U5        MH     UnU Vs/ s H  nURF                  U;  d  M  UPM     nnU(       aR  S
nURI                  SRK                  U Vs/ s H  n[A        URF                  5      PM     sn5      5      n[M        UU5      eU Vs0 s H  nURF                  U_M     nn/ nU H  n UR+                  UU   5        M     Un[Q        XXU5      $ s  snf s  snf s  snf s  snf s  snf ! [N         a    UR+                  [C        U5      5         Mk  f = f)z&Specialized Routine creation for Rust.r   r   r   r  r  r   rZ   c                 ,    [        U R                  5      $ rY   r   r   s    rJ   r   %RustCodeGen.routine.<locals>.<lambda>  r   rV   r   r   r-   ))r   r/   r   r   r7   r   r3   r   r8   r.   r2   r   r  r   r  r  r   r   r   r  r  r  r6   r   r   r   r!   r  r  r
  r   r	  r<   r   r   r5   rQ   r;   r  r   r   )rA   r5   r1   r  r@   r  r  r?   rC   r  r  r  r  r   r  r  r  r  r   rD   rI   r!  r"  r#  r$  r%  s                             rJ   r&  RustCodeGen.routine  s    tZz:6N%O%O !677,K+K (3'8'8'=>'=!gg'=
>  +2ceK8H **Z7+EHYHYZaHbb ";/IQ$))((xx gw// 7==!I=CAEE3<=!IJD$\\//F&&}Vd'\]!'GV\+JKK& (F G G ""6$#PQxx'' NN6* ( ""6$W!_#EF+ 00 	23$ &&w/E.3M%****+ 0 &&|4E#(M%  5 W#.FOOM&12 / (L(c;// ''		2 '',	 )
 !-"*N(Qaff<M.Mq(GN:jj+IACK+I!JK.sG<< 1991QVVQYM9H+;OOM&$9: ,
  Ht{LLQ ?" "JN O ,J :
   ;OOM&$9:;s6   )O-O
O&OO"O',O,,$PPc                    / nUR                  S5        [        [        U R                  S.-  nUR	                  5        H7  nUR                  SUR                  S5      -  R                  5       S-   5        M9     UR                  S5        U$ )rX  z/*
rY  z *%sr[  r;  z */
)r  r]  r^  r   r_  r`  rstripra  s       rJ   rC  RustCodeGen._get_header9  s{    
&!=+/<< 9 9NN$DvB7??ADHI %'"rV   c                    UR                    Vs/ s H  o"R                  S5      PM     nn[        U5      S:X  a	  SUS   -   nO3[        UR                   5      S:  a  SSR                  U5      -   S-   nOSn/ nUR                   H  nU R
                  R                  UR                  5      nUR                  (       d  [        U[        5      (       a'  UR                  S	U-  UR                  S5      45        Mu  UR                  XvR                  S5      45        M     SR                  U Vs/ s H  nS
U-  PM
     sn5      n	SUR                  < SU	< SU< 3$ s  snf s  snf )rf  Rustr   z -> r   z -> (r-   r   r|   rh  z%s: %szfn r   )r>   r   rj  r;   r=   r   r   r5   r   r/   r   r  )
rA   r&  r  r>   rstyperl  rD   r5   rm  r=   s
             rJ   rn  RustCodeGen.get_prototypeD  s)    4;??C?a>>&)?Cw<1gaj(F!A%tyy11C7FF	$$C<<''1D~~C!<!<  %$,0@0@0H!IJ  $(8(8(@!AB % IIi@i1i@A	 'i@@# D  As   E-E c                 
    / nU$ rY   rN   )rA   r0  rD  s      rJ   r<  $RustCodeGen._preprocessor_statements`  s    
rV   c                 0    U R                  U5      nSU-  /$ rw  rx  ry  s      rJ   r=   RustCodeGen._get_routine_openinge  r|  rV   c                     / $ rY   rN   r~  s     rJ   r>  RustCodeGen._declare_argumentsi  r  rV   c                     / $ rY   rN   r~  s     rJ   r?  RustCodeGen._declare_globalsm  r  rV   c                     / $ rY   rN   r~  s     rJ   r@  RustCodeGen._declare_localsq  r  rV   c           	      t   / n/ n/ n/ nUR                    HH  n[        U[        5      (       d  M  UR                  (       a  M-  UR	                  UR
                  5        MJ     UR                   GH	  n[        U[        5      (       a1  UR                  nUR	                  [        UR                  5      5        O[        S5      eU R                  SSSS.UR                  US9u  pn[        U	[        S9 H  u  pUR	                  SU< SU< S	35        M!     [        U
[        S9 H;  n[        U[        5      (       a  UR                  nOUnUR	                  S
U-  5        M=     UR	                  SU-  5        GM     [!        U5      S:  a  SSR#                  U5      -   S-   /nUR	                  S5        X2-   U-   $ )Nr  r   Fr  r  r   zconst z: f64 = r  z// unsupported: %s
zlet %s
r   r   r-   r   r;  )r=   r/   r   r   r  r5   r>   r!   r`   r<   r   r   r1   r	  r	   r  rj  r;   )rA   r&  rD  r  returnsr  rD   r   r  r   r   rs_exprr5   r  r  s                  rJ   rA  RustCodeGen._call_printeru  s   

 $$C#z**3>>>""388, % ooF&&))"--	s6#4#456"#IJJ040R0RUe<fkkU^ 1S 1`-Ig  &iS9##tU$KL  : m5c8,,88DD##$:d$CD 6 j723) &, w<!TYYw//#56Gt(722rV   c                     S/$ r  rN   r~  s     rJ   rB  RustCodeGen._get_routine_ending  r  rV   c                 *    U R                  XX4U5        g rY   r  r  s         rJ   dump_rsRustCodeGen.dump_rs  r  rV   r  r  rG  )rP   rj   rk   rl   rm   r  rK   r&  rC  rn  r<  r=  r>  r?  r@  rA  rB  rf  r,  r"   rE  r+  rp   r  r  s   @rJ   r'   r'     sv     N4SMl	A8
&)3V; 'G''//GO yHrV   r'   c                 (   U S:X  a1  Uc  O-UR                  5       S:X  a  Sn OUR                  5       S:X  a  Sn [        [        [        [        [
        [        [        S.R                  U R                  5       5      nUc  [        SU -  5      eU" X5      $ )Nr   c89r  rP  r  )r   r  r  F95r   r   r   zLanguage '%s' is not supported.)rT  r#   r  r  r$   r%   r&   r'   getr   r7   )r   r   rS  r   CodeGenClasss        rJ   get_code_generatorrm    s    3^^&H^^&H!*Z#l+') *-X^^-=)>  :XEFF))rV   c           	      *   Uc  U
c  [        S5      eOU
b  [        S5      e[        XX5      n
[        U S   [        5      (       a  U /n Uc  U S   S   n/ nU  H'  u  pUR	                  U
R                  XUU5      5        M)     U
R                  XXEU5      $ )ad  Generate source code for expressions in a given language.

Parameters
==========

name_expr : tuple, or list of tuples
    A single (name, expression) tuple or a list of (name, expression)
    tuples.  Each tuple corresponds to a routine.  If the expression is
    an equality (an instance of class Equality) the left hand side is
    considered an output argument.  If expression is an iterable, then
    the routine will have multiple outputs.

language : string,
    A string that indicates the source code language.  This is case
    insensitive.  Currently, 'C', 'F95' and 'Octave' are supported.
    'Octave' generates code compatible with both Octave and Matlab.

prefix : string, optional
    A prefix for the names of the files that contain the source code.
    Language-dependent suffixes will be appended.  If omitted, the name
    of the first name_expr tuple is used.

project : string, optional
    A project name, used for making unique preprocessor instructions.
    [default: "project"]

to_files : bool, optional
    When True, the code will be written to one or more files with the
    given prefix, otherwise strings with the names and contents of
    these files are returned. [default: False]

header : bool, optional
    When True, a header is written on top of each source file.
    [default: True]

empty : bool, optional
    When True, empty lines are used to structure the code.
    [default: True]

argument_sequence : iterable, optional
    Sequence of arguments for the routine in a preferred order.  A
    CodeGenError is raised if required arguments are missing.
    Redundant arguments are used without warning.  If omitted,
    arguments will be ordered alphabetically, but with all input
    arguments first, and then output or in-out arguments.

global_vars : iterable, optional
    Sequence of global variables used by the routine.  Variables
    listed here will not show up as function arguments.

standard : string, optional

code_gen : CodeGen instance, optional
    An instance of a CodeGen subclass. Overrides ``language``.

printer : Printer instance, optional
    An instance of a Printer subclass.

Examples
========

>>> from sympy.utilities.codegen import codegen
>>> from sympy.abc import x, y, z
>>> [(c_name, c_code), (h_name, c_header)] = codegen(
...     ("f", x+y*z), "C89", "test", header=False, empty=False)
>>> print(c_name)
test.c
>>> print(c_code)
#include "test.h"
#include <math.h>
double f(double x, double y, double z) {
   double f_result;
   f_result = x + y*z;
   return f_result;
}
<BLANKLINE>
>>> print(h_name)
test.h
>>> print(c_header)
#ifndef PROJECT__TEST__H
#define PROJECT__TEST__H
double f(double x, double y, double z);
#endif
<BLANKLINE>

Another example using Equality objects to give named outputs.  Here the
filename (prefix) is taken from the first (name, expr) pair.

>>> from sympy.abc import f, g
>>> from sympy import Eq
>>> [(c_name, c_code), (h_name, c_header)] = codegen(
...      [("myfcn", x + y), ("fcn2", [Eq(f, 2*x), Eq(g, y)])],
...      "C99", header=False, empty=False)
>>> print(c_name)
myfcn.c
>>> print(c_code)
#include "myfcn.h"
#include <math.h>
double myfcn(double x, double y) {
   double myfcn_result;
   myfcn_result = x + y;
   return myfcn_result;
}
void fcn2(double x, double y, double *f, double *g) {
   (*f) = 2*x;
   (*g) = y;
}
<BLANKLINE>

If the generated function(s) will be part of a larger project where various
global variables have been defined, the 'global_vars' option can be used
to remove the specified variables from the function signature

>>> from sympy.utilities.codegen import codegen
>>> from sympy.abc import x, y, z
>>> [(f_name, f_code), header] = codegen(
...     ("f", x+y*z), "F95", header=False, empty=False,
...     argument_sequence=(x, y), global_vars=(z,))
>>> print(f_code)
REAL*8 function f(x, y)
implicit none
REAL*8, intent(in) :: x
REAL*8, intent(in) :: y
f = x + y*z
end function
<BLANKLINE>

z Need either language or code_genz.You cannot specify both language and code_gen.r   )r7   rm  r/   r<   r  r&  r8  )	name_exprr   r0  r   r1  r2  r3  r  r@   rS  code_genr   r/  r5   r1   s                  rJ   r(   r(     s    J ?@@  MNN%hK)A,$$K	~1a H
((5F)46 	7  
 >>(HeDDrV   c                 <    [        U5      nUR                  XX#5      $ )a
  A factory that makes an appropriate Routine from an expression.

Parameters
==========

name : string
    The name of this routine in the generated code.

expr : expression or list/tuple of expressions
    A SymPy expression that the Routine instance will represent.  If
    given a list or tuple of expressions, the routine will be
    considered to have multiple return values and/or output arguments.

argument_sequence : list or tuple, optional
    List arguments for the routine in a preferred order.  If omitted,
    the results are language dependent, for example, alphabetical order
    or in the same order as the given expressions.

global_vars : iterable, optional
    Sequence of global variables used by the routine.  Variables
    listed here will not show up as function arguments.

language : string, optional
    Specify a target language.  The Routine itself should be
    language-agnostic but the precise way one is created, error
    checking, etc depend on the language.  [default: "F95"].

Notes
=====

A decision about whether to use output arguments or return values is made
depending on both the language and the particular mathematical expressions.
For an expression of type Equality, the left hand side is typically made
into an OutputArgument (or perhaps an InOutArgument if appropriate).
Otherwise, typically, the calculated expression is made a return values of
the routine.

Examples
========

>>> from sympy.utilities.codegen import make_routine
>>> from sympy.abc import x, y, f, g
>>> from sympy import Eq
>>> r = make_routine('test', [Eq(f, 2*x), Eq(g, x + y)])
>>> [arg.result_var for arg in r.results]
[]
>>> [arg.name for arg in r.arguments]
[x, y, f, g]
>>> [arg.name for arg in r.result_variables]
[f, g]
>>> r.local_vars
set()

Another more complicated example with a mixture of specified and
automatically-assigned names.  Also has Matrix output.

>>> from sympy import Matrix
>>> r = make_routine('fcn', [x*y, Eq(f, 1), Eq(g, x + g), Matrix([[x, 2]])])
>>> [arg.result_var for arg in r.results]  # doctest: +SKIP
[result_5397460570204848505]
>>> [arg.expr for arg in r.results]
[x*y]
>>> [arg.name for arg in r.arguments]  # doctest: +SKIP
[x, y, f, g, out_8598435338387848786]

We can examine the various arguments more closely:

>>> from sympy.utilities.codegen import (InputArgument, OutputArgument,
...                                      InOutArgument)
>>> [a.name for a in r.arguments if isinstance(a, InputArgument)]
[x, y]

>>> [a.name for a in r.arguments if isinstance(a, OutputArgument)]  # doctest: +SKIP
[f, out_8598435338387848786]
>>> [a.expr for a in r.arguments if isinstance(a, OutputArgument)]
[1, Matrix([[x, 2]])]

>>> [a.name for a in r.arguments if isinstance(a, InOutArgument)]
[g]
>>> [a.expr for a in r.arguments if isinstance(a, InOutArgument)]
[g + x]

)rm  r&  )r5   r1   r  r@   r   rp  s         rJ   r)   r)   d  s#    n "(+HD(9GGrV   rY   r   )NNr   FTTNNNNN)NNrj  )Crm   rq  r  ior   sympyr   r^  
sympy.corer   r   r   r   r	   r
   sympy.printing.cr   sympy.printing.codeprinterr   sympy.printing.fortranr   sympy.printing.juliar   sympy.printing.octaver   sympy.printing.rustr   sympy.tensorr   r   r   sympy.matricesr   r   r   r   r   sympy.utilities.iterablesr   __all__r   r   r   r   r   r   r   r   r   r    r6   r!   r"   	Exceptionr   r  r]  r#   r  r  r$   r%   r&   r'   rm  r(   r)   rN   rV   rJ   <module>r     s  Ob 
   . B B , 6 / 1 3 / 2 25 5 1	"s sl  E;r2u=h'2r5A,	2r7K  .2K/ K/\	x 		H 	 &+Xz +\Hj $HXz H^r  r j		9 	y Z w Z x  T"w T"nF7 FRrG rhV' Vv*, <EGKDH[E| 04,1YHrV   