Wolfram mathematica 数学表函数

Wolfram mathematica 数学表函数,wolfram-mathematica,Wolfram Mathematica,我正在运行一个表函数,这将花费太多的时间来完成 我想知道是否有办法检索到目前为止计算的结果。不幸的是,没有。如果您想执行类似于lst=Table[f[I],{I,110000}]的操作,那么如果中止,您仍然可以得到结果 Clear[lst2]; lst2 = {}; (Do[lst2 = {lst2, f[i]}, {i, 1, 10000}]; lst2=Flatten[lst2];) // Timing 对于未定义的f,在我的机器上需要0.173066s,而lst=Table[f[i],{

我正在运行一个表函数,这将花费太多的时间来完成


我想知道是否有办法检索到目前为止计算的结果。

不幸的是,没有。如果您想执行类似于
lst=Table[f[I],{I,110000}]
的操作,那么如果中止,您仍然可以得到结果

Clear[lst2];
lst2 = {};
(Do[lst2 = {lst2, f[i]}, {i, 1, 10000}];
lst2=Flatten[lst2];) // Timing
对于未定义的
f
,在我的机器上需要0.173066s,而
lst=Table[f[i],{i,1,100000}]
大约需要0.06s(即,
Table
以不可中断为代价,速度快了3倍)

注意明显的“可中断”解决方案,
lst={};
做[AppendTo[lst,f[i]],{i,1,100000}]
大约需要40秒,所以不要这样做:使用链表并在末尾展平,就像在我的第一个示例中一样(但是,如果
f[i]
返回一个列表,这将中断,然后需要更加小心)。

建议的解决方案 下面是一个版本的
,它可以
中止
,并将保留到目前为止收集的中间结果。这是发布的解决方案的修改版本

它应该能够采用与
相同的迭代器规范

工作原理 下面是它的工作原理。第一条语句(
SetDelayed@……
)将“解析”迭代器,假设它们的形式都是
{iteratorSymbol,bounds}
,并将迭代器变量列表分配给变量
索引。需要使用
Hold
构造,以防止可能的迭代器变量求值。有很多方法可以做到这一点,我只用了其中一种。以下是它的工作原理:

In[44]:= 
{i, j, k} = {1, 2, 3}; 
Prepend[Thread[Map[Take[#, 1] &, List @@ Hold @@@ 
   Hold[{i, 1, 10}, {j, 1, 5}, {k, 1, 3}]], Hold], indices]

Out[45]= Hold[indices, {i, j, k}] 
使用
SetDelayed@@上述
将自然生成表单的延迟定义
索引:={i,j,k}
。我将这些值分配给指数
I,j,k
,以证明在使用此结构时不会对它们进行不必要的评估

下一条语句生成一个收集结果的列表,其中每个结果都分组在一个列表中,列表中包含用于生成结果的索引列表。由于
索引
变量是由延迟定义定义的,因此它每次都会重新计算一个新的索引组合。这里使用的另一个关键特性是
Do
循环接受与
相同的迭代器语法(还动态地本地化迭代器变量),同时是一个顺序(常量内存)构造。为了收集中间结果,使用了
reaw
Sow
。由于
expr
可以是任何一段代码,特别是也可以使用
Sow
,因此需要一个具有唯一名称的自定义标记,以便只
获取那些由我们的函数
播种的值,而不是它执行的代码。由于
Module
自然地生成具有唯一名称的(临时)符号,因此我仅使用
Module
生成的变量(没有值)作为标记。这是一种普遍有用的技术

为了能够在用户以交互方式或在代码中发出的
Abort[]
情况下收集结果,我们将
Do
循环包装在
CheckAbort
中。在这种方法中,
Abort[]
{}
)上执行的代码在很大程度上是任意的,因为结果的收集无论如何都是由
Sow
eaw
完成的,虽然在更复杂的版本中可能有用,该版本将结果保存到用户提供的某个变量中,然后重新发出
中止[]
(该功能当前未实现)

结果,我们进入了一个变量
indexedRes
表单的平面列表

{{expr1, {ind11,ind21,...indn1}},...,{exprk, {ind1k,ind2k,...indnk}}
其中,结果与相应的索引组合一起分组。我们需要这些索引组合来从平面列表重建多维结果列表。方法是根据
i
-th索引的值重复拆分列表。函数
SplitBy
具有此功能,但我们需要提供用于拆分步骤的函数列表。由于子列表
{expr,{ind1,…,indn}
中的
i
-第个迭代器索引的索引是
2,i
,在
i
-第四步进行拆分的函数是
\[[2,i]]&
,我们需要动态构建此类函数的列表,以将其提供给
SplitBy
。以下是一个例子:

In[46]:= Table[With[{i = i}, Function[Slot[1][[2, i]]]], {i, 5}]

Out[46]= {#1[[2, 1]] &, #1[[2, 2]] &, #1[[2, 3]] &, #1[[2, 4]] &, #1[[2, 5]] &}
带有[{i=i},body]
构造的
用于在纯函数中注入
i
的特定值。将
i
的值注入
函数
的替代方法确实存在,例如:

In[75]:= 
Function[Slot[1][[2, i]]] /. Map[List, Thread[HoldPattern[i] -> Range[5]]]

Out[75]= {#1[[2, 1]] &, #1[[2, 2]] &, #1[[2, 3]] &, #1[[2, 4]] &, #1[[2, 5]] &}

但可能更加模糊(也许除了最后一个)

生成的嵌套列表具有适当的结构,子列表
{expr,{ind1,…,indn}
处于
-3
级别(从底部开始的第三级)。通过使用
Map[First,lst,{-3}]
,我们删除了索引组合,因为嵌套列表已经重建,不再需要它们。剩下的是我们的结果-结果表达式的嵌套列表,其结构与
生成的类似嵌套列表的结构相对应。最后一条语句包装在
AbortProtect
-以防万一,以确保在触发可能的
Abort[]
之前返回结果

使用示例 下面是一个示例,在评估命令后不久,我按下了
Alt+。
Abort[]
):

In[133]:= abortableTable[N[(1+1/i)^i],{i,20000}]//Short
Out[133]//Short= {2.,2.25,2.37037,2.44141,<<6496>>,2.71807,2.71807,2.71807}
但它不会自动编译,而
会:

In[134]:= Table[N[(1+1/i)^i],{i,10000}]//Short//Timing
Out[134]= {0.,{2.,2.25,2.37037,2.44141,<<9993>>,2.71815,2.71815,2.71815}}

另一种解决方案是将中间计算的结果导出到正在运行的日志文件中,如中所述(请参阅“内存中备份的文件方法”一节)。有了这一点,您将获得新的中间计算结果,并将始终能够调查到目前为止的计算结果

另外,我认为应该按照建议使用
监视器

In[86]:= Replace[Table[{2, i}, {i, 5}], {inds__} :> (#[[inds]] &), 1]

Out[86]= {#1[[2, 1]] &, #1[[2, 2]] &, #1[[2, 3]] &, #1[[2, 4]] &, #1[[ 2, 5]] &}
In[133]:= abortableTable[N[(1+1/i)^i],{i,20000}]//Short
Out[133]//Short= {2.,2.25,2.37037,2.44141,<<6496>>,2.71807,2.71807,2.71807}
In[132]:= abortableTable[N[(1+1/i)^i,20],{i,10000}]//Short//Timing
Out[132]= {1.515,{2.0000000000000000000,2.2500000000000000000,<<9997>>,2.7181459268252248640}}

In[131]:= Table[N[(1+1/i)^i,20],{i,10000}]//Short//Timing
Out[131]= {1.5,{2.0000000000000000000,2.2500000000000000000,<<9997>>,2.7181459268252248640}}
In[134]:= Table[N[(1+1/i)^i],{i,10000}]//Short//Timing
Out[134]= {0.,{2.,2.25,2.37037,2.44141,<<9993>>,2.71815,2.71815,2.71815}}
ClearAll[abortableTableAlt];
SetAttributes[abortableTableAlt, HoldAll];
abortableTableAlt[expr_, iter : {_Symbol, __} ..] :=
  Module[{indices, indexedRes, sowTag, depth =  Length[Hold[iter]] - 1},
   Hold[iter] /. {sym_Symbol, __} :> sym /. Hold[syms__] :> (indices := {syms});
   indexedRes =  Replace[#, {x_} :> x] &@ Last@Reap[
      CheckAbort[Do[Sow[{expr, indices}, sowTag], iter], Null],sowTag];
   AbortProtect[
      SplitBy[indexedRes, Array[Function[x, #[[2, x]] &], {depth}]][[##,1]] & @@ 
      Table[All, {depth + 1}]
   ]];
Monitor[Table[Integrate[1/(x^n + 1), x], {n, 20}], 
 ProgressIndicator[n, {1, 20}]]