开发者

output with "Private`" Content in Mathematica Package

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`ep开发者_运维技巧silon^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`"].


You could use formal symbols instead of ordinary symbols to avoid your problem.

At the same time, using of formal symbols is more convenient way to output general expressions involving formal parameters. They have no values and values for them cannot be unintentionally set since they are Protected.

You can use "Special characters" palette to inter formal symbols.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜