在 Mathematica 中使用 Context 作为范围构造

发布于 2024-11-01 22:35:08 字数 614 浏览 5 评论 0原文

在思考关于在大型 Mathematica 项目中在数值和分析“模式”之间切换的上一个问题的解决方案时,我想到了使用Context作为范围构造的想法。

基本思想是在它们自己的上下文中进行所有数值分配,例如

Begin["Global`Numerical`"]
par1 = 1;
par2 = 2;
...
End[]

在全局上下文中具有所有复杂的分析函数、矩阵等。

理想情况下,我能够在全局上下文中工作,并通过简单的 Begin[Global'Numeric'] 切换到所有数字,并使用 End[] 切换回来。

不幸的是,这不起作用,因为例如在全局上下文中定义的 f[par1_,par2_,...] := foo 将不会使用 par1, par2< /code> 等已在 Global 的子上下文中定义。

有没有办法让子上下文继承父上下文的定义?是否有其他方法可以使用上下文来创建简单的可切换范围?

Thinking about a solution to my previous question about switching between numerical and analytical "modes" in a large Mathematica project, I thought about the idea of using Context as a scoping construct.

The basic idea is to make all numerical value assignments in their own context, e.g.

Begin["Global`Numerical`"]
par1 = 1;
par2 = 2;
...
End[]

and have all the complicated analytical functions, matrices, etc. in the Global context.

Ideally I would be able to work in the Global context and switch to everything being numeric with a simple Begin[Global'Numeric'] and switch back with End[].

Unfortunately this doen not work, since e.g. f[par1_,par2_,...] := foo defined in the Global context will not use par1, par2, etc which have been defined in a sub context of Global.

Is there a way to make sub contexts inherit definitions from their parent context? Is there some other way to use contexts to create a simple switchable scope?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦冥 2024-11-08 22:35:08

好吧,这是通过适当调整 $ContextPath 来解决(我认为)问题的一种方法:

SetOptions[EvaluationNotebook[], CellContext -> "GlobalTestCtxt`"];
Remove[f, GlobalTestCtxt`Numerical`f, par1, par2];
f[par1_, par2_] := {par1, par2};

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
Print[{$ContextPath, $Context}];
$ContextPath = DeleteCases[$ContextPath, "GlobalTestCtxt`"];
par1 = 1;
par2 = 2;
End[];
$ContextPath = savedContextPath;

现在,这将进行分析评估:

f[par1, par2]

并且从数字上看:

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
$ContextPath = Prepend[$ContextPath, $Context];
f[par1, par2]
End[];
$ContextPath = savedContextPath;

我说它脆弱的原因是,除非你请小心,很容易将符号放入错误的上下文中。例如,假设您在评估“数字”块之前忘记在全局上下文中评估 f 。好吧,现在您的数字块将无法工作,因为它会变成一个(完全有效的)符号 GlobalTestCtxt`Numerical`f,您在第一次评估数字时无意中将其输入到符号表中堵塞。由于存在这样的潜在错误,我个人不使用这种方法。

编辑:修复了一个错误(在数字上下文中进行赋值时需要隐藏“全局”上下文)

Well, here's one way to get around (what I think) is your problem by adjusting $ContextPath appropriately:

SetOptions[EvaluationNotebook[], CellContext -> "GlobalTestCtxt`"];
Remove[f, GlobalTestCtxt`Numerical`f, par1, par2];
f[par1_, par2_] := {par1, par2};

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
Print[{$ContextPath, $Context}];
$ContextPath = DeleteCases[$ContextPath, "GlobalTestCtxt`"];
par1 = 1;
par2 = 2;
End[];
$ContextPath = savedContextPath;

Now, this will evaluate analytically:

f[par1, par2]

And this numerically:

savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
$ContextPath = Prepend[$ContextPath, $Context];
f[par1, par2]
End[];
$ContextPath = savedContextPath;

The reason I say it's fragile is that unless you are careful, it's easy to get the symbol into the wrong context. For instance, suppose you forgot to evaluate f in the global context before evaluating the "numerical" block. Well, now your numerical block will not work simply because it'll turn to a (perfectly valid) symbol GlobalTestCtxt`Numerical`f, which you have inadvertently entered into the symbol table when you first evaluated the numerical block. Because of potential bugs like this, I personally don't use this approach.

Edit: fixed a bug (it is necessary to hide the "Global" context when doing assignments in numerical context)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文