вывод с контентом "Private`" в пакете Mathematica - PullRequest
8 голосов
/ 30 апреля 2010

Я пытаюсь решить следующую проблему реализации в 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` появляется перед любой локальной переменной, которую я возвратил в конечном результате. Я бы не хотел иметь этот Private` в вычисленном выводе. Любая идея или лучшие объяснения, которые могли бы указать мне, почему это происходит?

Большое спасибо за вашу помощь.

С наилучшими пожеланиями, Madalina

Ответы [ 4 ]

8 голосов
/ 30 апреля 2010

Ваша проблема является обычной, когда вы возвращаете символические функции из пакета, и когда это происходит со мной, я вижу это, как будто я сделал что-то не так при написании пакета. Хотя префикс всех таких символов с 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  

Внутренне, на символические переменные ссылаются, как обычно, но ваша функция теперь будет возвращать символическое выражение, используя любые глобальные символы, которые вы выбрали для использования. Это также разъединяет ваш выбор имен переменных с деталями реализации вашей функции.

2 голосов
/ 30 апреля 2010

Из обсуждения здесь похоже, что назначение символов внутри пакета глобальному контексту приведет к их выводу без префикса частного контекста.

То есть любые символы, которые могут составлять часть вывода, могут быть объявлены с префиксом 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};

edit: глобальные переменные должны иметь префикс Global`, где бы они ни находились, как указано выше

1 голос
/ 16 июня 2011

Вы можете использовать формальные символы вместо обычных символов, чтобы избежать вашей проблемы.

В то же время использование формальных символов является более удобным способом вывода общих выражений, включающих формальные параметры. У них нет значений, и значения для них не могут быть установлены непреднамеренно, так как они Protected.

Вы можете использовать палитру «Специальные символы» для межформальных символов.

1 голос
/ 30 апреля 2010

Попробуйте изменить Begin["Private`"] на Begin["`Private`"].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...