在General::stop
的{{3}}文档中,我们读到了:
此消息是在生成之后生成的 指示的消息已生成 第三次在一个单一的 评价即可。
消息被抑制 防止多余或重复 长时间计算中的消息。
我的问题是,在MathLink
工作时,我将每一点作为单一评估传递,因此General::stop
永远不会出现。
例如,如果我定义:
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
f[z_?NumericQ] := (Print@LinkRead[link];
LinkWrite[link,
Unevaluated[
EnterExpressionPacket[NIntegrate[Sin[1/x], {x, .001, z}]]]];
While[Head[packet = LinkRead[link]] =!= OutputNamePacket,
Print[packet]]; First@LinkRead[link]);
Plot[f[z], {z, 1, 10}, PlotPoints -> 6, MaxRecursion -> 0]
我获得Message
个f[z]
个General::stop
个数据包。当然,我希望在生成相同的消息3次之后,$MessageList
在从属内核中停止消息生成。有没有办法实现这个目标?
在tutorial/Messages
的文档页面上,我们读到了
使用标准 Mathematica main 循环,$ MessageList重置为{}时 处理特定输入 线已经完成。
在页面General::stop
上我们读到了:
在你做的每一次计算中, Mathematica 维护一个列表 所有消息的$ MessageList 生产。 在标准 Mathematica 会话中, 每行后清除此列表 输出的产生。
这可能是$MessageList
没有出现的原因吗?如果确实有办法控制主循环的这个方面?有没有办法创建这样的非标准 Mathematica 会话?
修改
似乎我的假设是正确的。如果我们在每封邮件之后清除General::stop
,则Unprotect[$MessageList]
Do[$MessageList = {}; 1/0, {10}]
永远不会出现:
$MessageList
所以问题仍然存在:如何在生成输出后禁用自动清除{{1}}?
答案 0 :(得分:1)
可能有更好的解决方案,但这里似乎有效。据我所知,重要的是你在奴隶内核中有一些累积消息的持久变量。
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
f[z_?NumericQ] :=
(Print@LinkRead[link];
LinkWrite[link, Unevaluated[EnterExpressionPacket[
If[! ValueQ[oldMessageList], oldMessageList = {}];
Block[{$MessageList = oldMessageList},
Module[{result},
oldMessageList =
Join[oldMessageList, (result =
NIntegrate[Sin[1/x], {x, .001, z}]; $MessageList)];
result
]]]]];
While[Head[packet = LinkRead[link]] =!= OutputNamePacket,
Print[packet]]; First@LinkRead[link]);
Plot[f[z], {z, 1, 10}, PlotPoints -> 6, MaxRecursion -> 0]
HTH
答案 1 :(得分:0)
我找到了解决方案。它再次利用elegant hack by Todd Gayley
。这是(当然,它必须在从属内核中进行评估):
$globalMessageList = {};
Unprotect[Message];
Message[args___] :=
Block[{$inMsg = True, $MessageList = $globalMessageList},
Message[args];
$globalMessageList = $MessageList;
] /; ! TrueQ[$inMsg];
Protect[Message];
通过检查$Line
的当前值并将其与之前的值进行比较,可以完全模拟从属内核中消息的标准行为:
If[TrueQ[$Line > lastLine],
LinkWrite[$kern,
Unevaluated[ExpressionPacket[$globalMessageList = {};]]];
LinkRead[$kern]]; lastLine = $Line;
:)