在Mathematica包中输出“Private”“内容

时间:2010-04-30 12:59:25

标签: wolfram-mathematica

我正在尝试解决Mathematica 7.0中的以下实现问题已有几天了,我不知道到底发生了什么,所以我希望有人可以给我一些提示。 我有3个函数,我在Mathematica中实现了一个扩展名为* .nb的源文件。 他们对所有的例子都很好。现在我想将这些功能放到3个不同的包中。所以我用扩展名。* m创建了三个不同的包,其中我放了所有想要的Mathematica函数。 “stereographic.m”包中的一个示例,其中包含代码:

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[]

现在测试我加载包的功能

Needs["stereographic`"]
一切都很好。但是当我用

测试函数时
formEqs[x^2-y^2,{x,y}]

我得到以下输出:

{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}

当然我不明白为什么Private`出现在我在最终结果中返回的任何局部变量的前面。我想不要在计算输出中有这个私有`。 任何想法或更好的解释可以表明我为什么会这样?

非常感谢你的帮助。

祝福, madalina

4 个答案:

答案 0 :(得分:8)

当你从包中返回符号函数时,你的问题很常见,当我遇到这种情况时,我认为它就好像我在编写包时做错了一样。虽然使用Global为所有这些符号添加前缀将“解决”问题,但它会破坏程序包的一些用途:实现隐藏。此外,由于它使用符号污染全局命名空间,因此必须小心运行代码,这会进一步破坏程序包的用途。您的包裹不应该关心全球环境是什么样的。如果它需要任何东西,它可以在BeginPackage或在包的私有部分内使用Needs自行加载。

相反,您可以执行Plot之类的功能,接受Symbol参数,如下所示:

 (*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  

在内部,符号变量像普通一样被引用,但是您的函数现在将使用您选择使用的任何全局符号返回符号表达式。这也将您对变量名称的选择与函数的实现细节分离。

答案 1 :(得分:2)

discussion here开始,看起来将包内的符号分配给全局上下文将使它们在没有私有上下文前缀的情况下输出。

也就是说,任何可能构成输出一部分的符号都可以使用Global`前缀声明,如下例所示:

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[]; 

在你的包中,它可能看起来像这样:

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};

编辑:全局变量需要在任何地方都给出全局`前缀,如上所述

答案 2 :(得分:1)

尝试将Begin["Private`"]更改为Begin["`Private`"]

答案 3 :(得分:1)

您可以使用formal symbols代替普通符号来避免您的问题。

同时,使用形式符号是输出涉及形式参数的通用表达式的更方便的方法。它们没有值,因为它们是Protected,所以不能无意中设置它们的值。

您可以使用“特殊字符”调色板来表示正式符号。