I am trying to solve the following implementation problem in Mathematica 7.0 for some days now and I do not understand exactly what is happening so I hope someone can give me some hints. I have 3 functions that I implemented in Mathematica in a source file with extension *.nb. They are working okay to all the examples. Now I want to put these functions into 3 different packages. So I created three different packages with extension .*m in which I put all the desired Mathematica function. An example in the "stereographic.m" package which contain the code:
BeginPackage["stereographic`"]
stereographic::usage="The package stereographic...."
formEqs::usage="The function formEqs[complexBivPolyEqn..."
makePoly::usage="The function makePoly[algebraicEqn] ..."
getFixPolys::usage="The function..."
milnorFibration::usage="The function..."
Begin["Private`"]
Share[];
formEqs[complex_,{m_,n_}]:=Block[{complexnew,complexnew1, realeq, imageq, expreal,
expimag, polyrealF, polyimagF,s,t,u,v,a,b,c,epsilon,x,y,z},
complexnew:=complex/.{m->s+I*t,n->u+I*v};
complexnew1:=complexnew/.{s->(2 a epsilon)/(1+a^2+b^2+c^2),t->(2 b
epsilon)/(1+a^2+b^2+c^2),u->(2 c epsilon)/(1+a^2+b^2+c^2),v->(-
epsilon+a^2 epsilon+b^2 epsilon+c^2
epsilon)/(1+a^2+b^2+c^2)};
realeq:=ComplexExpand[Re[complexnew1]];
imageq:=ComplexExpand[Im[complexnew1]];
expreal:=makePoly[realeq];
expimag:=makePoly[imageq];
polyrealF:=expreal/.{a->x,b->y,c->z};
polyimagF:=expimag/.{a->x,b->y,c->z};
{polyrealF,polyimagF}
]
End[]
EndPackage[]
Now to test the function I load the package
Needs["stereographic`"]
everything is okay. But when I test the function for example with
formEqs[x^2-y^2,{x,y}]
I get the following ouput:
{Private`epsilon^2 + 2 Private`x^2 Private`epsilon^2 +
Private`x^4 Private`epsilon^2 -
6 Private`y^2 Private`epsilon^2 +
2 Private`x^2 Private`y^2 Private`epsilon^2 +
Private`y^4 Private`epsilon^2 -
6 Private`z^2 Private`epsilon^2 +
2 Private`x^2 Private`z^2 Private`epsilon^2 +
2 Private`y^2 Private`z^2 Private`epsilon^2 +
Private`z^4 Private`epsilon^2,
8 Private`x Private`y Private`epsilon^2 +
4 Private`z Private`epsilon^2 -
4 Private`x^2 Private`z Private`epsilon^2 -
4 Private`y^2 Private`z Private`epsilon^2 -
4 Private`z^3 Private`epsilon^2}
Of course I do not understand why Private` appears in front of any local variable which I returned in the final result. I would want not to have this Private` in the computed output. Any idea or better explanations which could indicate me why this happens?
Thank you very much for your help.
Best wishes, madalina
Your problem is a common one when you are returning symbolic functions from a package, and when this happens to me, I view it as if I've done something wrong in writing the package. While prefixing all such symbols with Global
will "fix" the problem, it defeats some of the purpose of a package: implementation hiding. Also, since it pollutes the global namespace with your symbols, you must be careful in how you run your code which further defeats the purpose of a package. Your package should not care what the global environment is like. If it needs anything, it can load it itself either in BeginPackage
or using Needs
within the private portion of the package.
Instead, you can do what functions like Plot
do, accept a Symbol
parameter, as follows:
(*Note: if z is not a symbol this won't work, i.e. if it is Set to some value.*)
In[1] := f[x_Symbol] := x^2
In[2] := f[z]
Out[2] := z^2
Internally, symbolic variables are referenced like normal, but your function will now return a symbolic expression using whatever global symbols you've chosen to use. This also decouples your choice of variable names with the implementation details of your function.
From the discussion here, it looks like assigning the symbols inside the package to the global context will make them be output without the private context prefix.
That is, any symbols that might form part of the output could be declared with a Global` prefix, as in this example:
BeginPackage["PackageContext`"];
Rule1::usage = "Rule1 is a test exported rule.";
Begin["`Private`"];
Rule1 = Cos[Global`x_]^2 + Sin[Global`x_]^2 :> Global`x;
End[];
EndPackage[];
In your package, it might look something like this:
formEqs[complex_,{m_,n_}]:=Block[{complexnew,complexnew1, realeq, imageq,
expreal,expimag, polyrealF, polyimagF,s,t,u,v,a,b,c,
Global`epsilon,Global`x,Global`y,Global`z},
complexnew:=complex/.{m->s+I*t,n->u+I*v};
complexnew1:=complexnew/.{s->(2 a Global`epsilon)/(1+a^2+b^2+c^2),t->(2 b
Global`epsilon)/(1+a^2+b^2+c^2),u->(2 c Global`epsilon)/(1+a^2+b^2+c^2),v->(-
Global`epsilon+a^2 Global`epsilon+b^2 Global`epsilon+c^2
Global`epsilon)/(1+a^2+b^2+c^2)};
realeq:=ComplexExpand[Re[complexnew1]];
imageq:=ComplexExpand[Im[complexnew1]];
expreal:=makePoly[realeq];
expimag:=makePoly[imageq];
polyrealF:=expreal/.{a->Global`x,b->Global`y,c->Global`z};
polyimagF:=expimag/.{a->Global`x,b->Global`y,c->Global`z};
edit: the Global variables need to be given the Global` prefix wherever they occur, as above
Try changing Begin["Private`"]
to Begin["`Private`"]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With