4

在我们阅读的文档page中:General::stop

此消息是在单个评估中第三次生成指示的消息之后生成的。

消息被抑制以防止在长计算中出现冗余或重复消息。

我的问题是,在完成工作时,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我们阅读的文档页面上

使用标准Mathematica主循环,当特定输入行的处理完成时,$MessageList 被重置为 {}。

tutorial/Messages在我们阅读的页面上:

在您进行的每一次计算中, Mathematica都会维护一个列表 $MessageList ,其中包含所有产生的消息。在标准 Mathematica会话中,在生成每一行输出后清除此列表。

可能这就是为什么General::stop不出现的原因?如果是真的,有没有办法控制主循环的这个方面?有没有办法创建这样一个非标准的Mathematica会话?

编辑: 看来我的假设是正确的。如果我们将$MessageList在每条消息之后清除,则General::stop永远不会出现:

Unprotect[$MessageList]
Do[$MessageList = {}; 1/0, {10}]

$MessageList所以问题依然存在:生成输出后如何禁用自动清零?

4

2 回答 2

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]

高温高压

于 2011-03-02T11:40:56.867 回答
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;

:)

于 2011-03-03T16:15:12.200 回答