tags:

views:

129

answers:

3

Hello everyone,

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

A: 

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

codeulike
I tried with Global` in the code for the variables x,y,z,epsilon returned in the result but still Private` appears in the result. If I remove Begin["Private`"] then the output looks nice but the warning messages for x,y,z, epsilon appears: x::shdw: "Symbol x appears in multiple contexts "stereographic`", "Global`"; definitions in context "stereographic`" may shadow or be shadowed by other definitions."If I add Remove[x,y,z,epsilon] then the warning message dissapear but Remove appears in the output..
madalina
If possible restart the kernel between each of your tests. That way you do not need to worry about interference from previous evaluations, it works better then Remove. I think codeulike has the correct answer. Also it is not clear weather you replaced all of the x,y,z,epsilon with Global`x,... in both the first and second argument of Block. I just tested it on Mathematica 7.0.1 after a restart and it worked for me.
Davorak
Thanks for that Davorak, I don't have Mathematica handy. Presumably the variables have to be prefixed with Global whenever they are mentioned in the package?
codeulike
yes it worked after I added Global` everywhere in front of an x,y,z or epsilon declaration. thank you.
madalina
While it works, I think it is bad practice. I've outlined an alternative in my answer.
rcollyer
+3  A: 

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.

rcollyer
A: 

Try changing Begin["Private"] with Begin["Private`"]

ragfield
Didn't notice that bug. Good catch. Since the editor is playing merry havoc with the code, `Private` should be preceded and followed by a grave mark. That way, `Private` will be a subcontext of the package context. Unfortunately, this does not solve the problem of returning symbols from the private section of a package.
rcollyer