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

Спасибо большое за помощь.

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


person madalina    schedule 30.04.2010    source источник
comment
Попробуйте также опубликовать на comp.soft-sys.mathematica, я думаю, что сообщество пользователей Mathematica больше и более осведомлено, чем сообщество здесь.   -  person High Performance Mark    schedule 30.04.2010
comment
До этого момента вы задали 23 вопроса, но не приняли ни один из ответов. Ни один из ответов не соответствует вашим критериям?   -  person rcollyer    schedule 03.05.2010


Ответы (4)


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

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

person rcollyer    schedule 30.04.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};

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

person codeulike    schedule 30.04.2010
comment
Я пробовал использовать Global` в коде для переменных x, y, z, epsilon, возвращаемых в результате, но в результате все равно появляется Private`. Если я удалю 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 может затенить или быть затененным другими определениями. Если я добавлю Remove[x,y,z,epsilon], то предупреждающее сообщение исчезнет, ​​но на выходе появится Remove. - person madalina; 30.04.2010
comment
Если возможно, перезапустите ядро ​​между каждым из ваших тестов. Таким образом, вам не нужно беспокоиться о помехах от предыдущих оценок, это работает лучше, чем Удалить. Я думаю, что codeulike имеет правильный ответ. Также неясно, заменили ли вы все x,y,z,epsilon на Global`x,... как в первом, так и во втором аргументе Block. Я только что протестировал его на Mathematica 7.0.1 после перезагрузки, и у меня это сработало. - person Davorak; 30.04.2010
comment
Спасибо за этот Davorak, у меня нет под рукой Mathematica. Предположительно, переменные должны иметь префикс Global всякий раз, когда они упоминаются в пакете? - person codeulike; 30.04.2010
comment
да, это сработало после того, как я добавил Global` везде перед объявлением x, y, z или epsilon. Спасибо. - person madalina; 30.04.2010
comment
Хотя это работает, я думаю, что это плохая практика. Я изложил альтернативу в своем ответе. - person rcollyer; 30.04.2010
comment
У меня возникла та же проблема, и я решил ее, добавив префикс Global`. Спасибо - person LCFactorization; 27.11.2013

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

person ragfield    schedule 30.04.2010
comment
Не заметил этого бага. Хороший улов. Так как редактор играет с кодом в веселый хаос, перед Private должен стоять знак могилы. Таким образом, Private будет подконтекстом контекста пакета. К сожалению, это не решает проблему возврата символов из приватной секции пакета. - person rcollyer; 30.04.2010

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

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

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

person Alexey Popkov    schedule 16.06.2011