11(* ::Package:: *)
22
3- BeginPackage ["ToPython`" ]
4- ToPython ::usage = "ToPython[expression,numpystring] converts Mathematica expression to a Numpy compatible expression.
5- because Numpy can be imported in several ways, numpystring is a string that will be added to appended to function names, e.g., Cos->numpy.cos"
6- Begin ["Private`" ]
7- ToPython [x_ ,numpyprefix_ :"numpy" ]:= Module [{expression = x ,greekrule ,PythonForm ,numpypre = numpyprefix ,lp ,rp ,a ,b },
8- (*FUNCTION TO CONVERT MATHEMATICA EXPRESSION TO NUMPY;
3+ (*This package provides a function to convert a Mathematica expression to numpy
94----------------------------------------------------;
105INPUT ARGUMENTS;
11- x : your mathematica expression, it can be numbers, literals, complexes or lists;
6+ expression : your mathematica expression, it can be numbers, literals, complexes or lists;
127numpy\[LetterSpace]prefix: string defining your Numpy import prefix, e.g.:
138if your used "import numpy as np", your prefix should be the string "np"
149if your used "from numpy import *", your prefix should be the empty string ""
@@ -17,38 +12,110 @@ OUTPUT;
1712the Numpy python-ready expression (to be copied as a string);
1813!The formatted expression will be copied ot your clipboard, ready to paste on Python!;
1914------------------------------------------------------;
20- Not tested for every possible combination; use at your risk, by Gustavo Wiederhecker*)
21- If [numpyprefix == "" ,sep = "" ,sep = "." ]; (*if no prefix is included, the "." separator is not used*)
22- lp = "( " ;
23- rp = " )" ;
24- PythonForm [Rational [a_ ,b_ ]]:= PythonForm [a ]<> "/" <> PythonForm [b ];
25- PythonForm [Complex [a_ ,b_ ]]:= "complex" <> lp <> PythonForm [a ]<> "," <> PythonForm [b ]<> rp ;
26- PythonForm [Times [a_ ,b_ ]]:= PythonForm [a ]<> " * " <> PythonForm [b ];
27- PythonForm [Plus [a_ ,b_ ]]:= lp <> PythonForm [a ]<> " + " <> PythonForm [b ]<> rp ;
28- PythonForm [h_ [args__ ]]:= numpypre <> sep <> ToLowerCase [PythonForm [h ]]<> lp <> PythonForm [args ]<> rp ;
29- PythonForm [Power [a_ ,b_ ]]:= lp <> PythonForm [a ]<> rp <> "**" <> lp <> PythonForm [b ]<> rp ;
30- PythonForm [a_ ListQ ]:= numpypre <> sep <> "array" <> StringReplace [ToString [a ],{"{" -> "[" ,"}" -> "]" }];
31- PythonForm [Arg ]= numpypre <> sep <> "angle" ;
32- (*Some functions that are note defined in numpy*)
33- PythonForm [Csc ]:= "1/" <> numpypre <> sep <> "sin" ;
34- PythonForm [Sec ]:= "1/" <> numpypre <> sep <> "cos" ;
35- PythonForm [Cot ]:= "1/" <> numpypre <> sep <> "tan" ;
36- PythonForm [Csch ]:= "1/" <> numpypre <> sep <> "sinh" ;
37- PythonForm [Sech ]:= "1/" <> numpypre <> sep <> "cosh" ;
38- PythonForm [Coth ]:= "1/" <> numpypre <> sep <> "tanh" ;
39- (*Handling arrays*)
40- PythonForm [List [args__ ]]:= numpypre <> sep <> "array" <> lp <> "[" <> Table [PythonForm [{args }[[ii ]]]<> "," ,{ii ,1 ,Length @ {args }}]<> "]" <> rp ;
41- (*Pi and E*)
42- PythonForm [\[Pi ]]= numpypre <> sep <> "pi" ;
43- PythonForm [E ]= numpypre <> sep <> "e" ;
44- (*real numbers, engineering notation*)
45- PythonForm [r_ Real ]:= Block [{a = MantissaExponent [r ]},If [r >= 0 ,ToString [N [a [[1 ]],6 ]]<> "e" <> ToString [a [[2 ]]],"(" <> ToString [N [a [[1 ]],6 ]]<> "e" <> ToString [a [[2 ]]]<> ")" ]];
46- (*Greek characters*)
47- greekrule={"\[Alpha]"->"alpha","\[Beta]"->"beta","\[Gamma]"->"gamma","\[Delta]"->"delta","\[CurlyEpsilon]"->"curlyepsilon","\[Zeta]"->"zeta","\[Eta]"->"eta","\[Theta]"->"theta","\[Iota]"->"iota","\[Kappa]"->"kappa","\[Lambda]"->"lambda","\[Mu]"->"mu","\[Nu]"->"nu","\[Xi]"->"xi","\[Omicron]"->"omicron","\[Pi]"->"pi","\[Rho]"->"rho","\[FinalSigma]"->"finalsigma","\[Sigma]"->"sigma","\[Tau]"->"tau","\[Upsilon]"->"upsilon","\[CurlyPhi]"->"curlyphi","\[Chi]"->"chi","\[Psi]"->"psi","\[Omega]"->"omega","\[CapitalAlpha]"->"Alpha","\[CapitalBeta]"->"Beta","\[CapitalGamma]"->"Gamma","\[CapitalDelta]"->"Delta","\[CapitalEpsilon]"->"CurlyEpsilon","\[CapitalZeta]"->"Zeta","\[CapitalEta]"->"Eta","\[CapitalTheta]"->"Theta","\[CapitalIota]"->"Iota","\[CapitalKappa]"->"Kappa","\[CapitalLambda]"->"Lambda","\[CapitalMu]"->"Mu","\[CapitalNu]"->"Nu","\[CapitalXi]"->"Xi","\[CapitalOmicron]"->"Omicron","\[CapitalPi]"->"Pi","\[CapitalRho]"->"Rho","\[CapitalSigma]"->"Sigma","\[CapitalTau]"->"Tau","\[CapitalUpsilon]"->"Upsilon","\[CapitalPhi]"->"CurlyPhi","\[CapitalChi]"->"Chi","\[CapitalPsi]"->"Psi","\[CapitalOmega]"->"Omega"};
48- (*Everything else*)
49- PythonForm [allOther_ ]:= StringReplace [ToString [allOther ,FortranForm ],greekrule ];
50- (*Copy results to clipboard*)
51- CopyToClipboard [PythonForm [expression ]];
52- PythonForm [expression ]]
15+ Not tested for every possible combination; use at your risk, by Gustavo Wiederhecker with
16+ modifications by David Zwicker
17+ *)
18+
19+
20+ BeginPackage ["ToPython`" ]
21+
22+ ToPython ::usage = "ToPython[expression, numpyprefix, copy]
23+ converts Mathematica expression to a Numpy compatible expression. Because Numpy can
24+ be imported in several ways, numpyprefix is a string that will be added to appended
25+ to function names, e.g., Cos->np.cos. If copy==True, the result is copied to the clipboard"
26+
27+ ToPythonEquation ::usage = "ToPythonEquation[equation, numpyprefix, copy] converts a
28+ Mathematica equation to a Numpy compatible express"
29+
30+
31+
32+ Begin ["Private`" ]
33+
34+
35+ ToPython [expression_ , numpyprefix_ :"np" , copy_ :False ] := Module [
36+ {result , greekrule , format , PythonForm , np , a , b , l , m , args },
37+
38+ (* determine the correct numpy prefix *)
39+ If [numpyprefix == "" , np = numpyprefix , np = numpyprefix <> "." ];
40+
41+ (* general function for formating output *)
42+ format [pattern_ String , args__ ] := ToString @ StringForm [
43+ StringReplace [pattern , "numpy." -> np ],
44+ Sequence @@ PythonForm /@ List [args ]];
45+
46+ (* special forms that are recognized *)
47+ PythonForm [Times [- 1 , a_ ]] := format ["-(``)" , a ];
48+ PythonForm [Power [a_ , Rational [1 , 2 ]]] := format ["numpy.sqrt(``)" , a ];
49+ PythonForm [Times [a_ , Power [b_ , - 1 ]]] := format ["(``) / (``)" , a , b ];
50+
51+ (* Simple math *)
52+ PythonForm [Rational [a_ , b_ ]] := format ["(``) / (``)" , a , b ];
53+ PythonForm [Complex [a_ , b_ ]] := format ["complex(``, ``)" , a , b ];
54+ PythonForm [Times [a_ , b_ ]] := format ["(``) * (``)" , a , b ];
55+ PythonForm [Plus [a_ , b_ ]] := format ["`` + ``" , a , b ];
56+ PythonForm [Power [a_ , b_ ]] := format ["(``) ** (``)" , a , b ];
57+ PythonForm [Exp [a_ ]] := format ["numpy.exp(``)" , a ];
58+
59+ (* Some special functions *)
60+ PythonForm [Arg [a_ ]] := format ["numpy.angle(``)" , a ];
61+ PythonForm [SphericalHarmonicY [l_ , m_ , a_ , b_ ]] := format [
62+ "special.sph_harm(``, ``, (``) % (2 * numpy.pi), (``) % numpy.pi)" ,
63+ m , l , b , a ];
64+ PythonForm [BesselI [a_ , b_ ]] := format ["special.iv(``, ``)" , a , b ];
65+ PythonForm [BesselJ [a_ , b_ ]] := format ["special.jv(``, ``)" , a , b ];
66+ PythonForm [BesselK [a_ , b_ ]] := format ["special.kn(``, ``)" , a , b ];
67+ PythonForm [BesselY [a_ , b_ ]] := format ["special.yn(``, ``)" , a , b ];
68+
69+ (* Some functions that are not defined in numpy *)
70+ PythonForm [Csc [a_ ]] := format ["1 / numpy.sin(``)" , a ];
71+ PythonForm [Sec [a_ ]] := format ["1 / numpy.cos(``)" , a ];
72+ PythonForm [Cot [a_ ]] := format ["1 / numpy.tan(``)" , a ];
73+ PythonForm [Csch [a_ ]] := format ["1 / numpy.sinh(``)" , a ];
74+ PythonForm [Sech [a_ ]] := format ["1 / numpy.cosh(``)" , a ];
75+ PythonForm [Coth [a_ ]] := format ["1 / numpy.tanh(``)" , a ];
76+
77+ (* Handling arrays *)
78+ PythonForm [a_ NumericArray ] :=
79+ np <> "array(" <> StringReplace [ToString @ Normal @ a , {"{" -> "[" , "}" -> "]" }]<> ")" ;
80+ PythonForm [List [args__ ]] :=
81+ np <> "array([" <> StringRiffle [PythonForm /@ List [args ], ", " ]<> "])" ;
82+
83+ (* Constants *)
84+ PythonForm [\[Pi ]] = np <> "pi" ;
85+ PythonForm [E ] = np <> "e" ;
86+
87+ (* Greek characters *)
88+ greekrule = {
89+ "\[ Alpha]" -> "alpha" ,"\[ Beta]" -> "beta" ,"\[ Gamma]" -> "gamma" ,"\[ Delta]" -> "delta" ,
90+ "\[ CurlyEpsilon]" -> "curlyepsilon" ,"\[ Zeta]" -> "zeta" ,"\[ Eta]" -> "eta" ,
91+ "\[ Theta]" -> "theta" ,"\[ Iota]" -> "iota" ,"\[ Kappa]" -> "kappa" ,"\[ Lambda]" -> "lambda" ,
92+ "\[ Mu]" -> "mu" ,"\[ Nu]" -> "nu" ,"\[ Xi]" -> "xi" ,"\[ Omicron]" -> "omicron" ,"\[ Pi]" -> "pi" ,
93+ "\[ Rho]" -> "rho" ,"\[ FinalSigma]" -> "finalsigma" ,"\[ Sigma]" -> "sigma" ,"\[ Tau]" -> "tau" ,
94+ "\[ Upsilon]" -> "upsilon" ,"\[ CurlyPhi]" -> "curlyphi" ,"\[ Chi]" -> "chi" ,"\[ Phi]" -> "phi" ,
95+ "\[ Psi]" -> "psi" ,
96+ "\[ Omega]" -> "omega" ,"\[ CapitalAlpha]" -> "Alpha" ,"\[ CapitalBeta]" -> "Beta" ,
97+ "\[ CapitalGamma]" -> "Gamma" ,"\[ CapitalDelta]" -> "Delta" ,
98+ "\[ CapitalEpsilon]" -> "CurlyEpsilon" ,"\[ CapitalZeta]" -> "Zeta" ,
99+ "\[ CapitalEta]" -> "Eta" ,"\[ CapitalTheta]" -> "Theta" ,"\[ CapitalIota]" -> "Iota" ,
100+ "\[ CapitalKappa]" -> "Kappa" ,"\[ CapitalLambda]" -> "Lambda" ,"\[ CapitalMu]" -> "Mu" ,
101+ "\[ CapitalNu]" -> "Nu" ,"\[ CapitalXi]" -> "Xi" ,"\[ CapitalOmicron]" -> "Omicron" ,
102+ "\[ CapitalPi]" -> "Pi" ,"\[ CapitalRho]" -> "Rho" ,"\[ CapitalSigma]" -> "Sigma" ,
103+ "\[ CapitalTau]" -> "Tau" ,"\[ CapitalUpsilon]" -> "Upsilon" ,"\[ CapitalPhi]" -> "CurlyPhi" ,
104+ "\[ CapitalChi]" -> "Chi" ,"\[ CapitalPsi]" -> "Psi" ,"\[ CapitalOmega]" -> "Omega" };
105+
106+ (* Everything else *)
107+ PythonForm [h_ [args__ ]] := np <> ToLowerCase [PythonForm [h ]]<> "(" <> PythonForm [args ]<> ")" ;
108+ PythonForm [allOther_ ] := StringReplace [ToString [allOther , FortranForm ], greekrule ];
109+
110+ result = StringReplace [PythonForm [expression ], greekrule ];
111+ (* Copy results to clipboard *)
112+ If [copy , CopyToClipboard [result ]];
113+ result
114+ ]
115+
116+
117+ ToPythonEquation [Equal [a_ , b_ ], numpyprefix_ :"np" , copy_ :True ] := ToPython [a - b , numpyprefix , copy ]
118+
119+
53120End []
54121EndPackage []
0 commit comments