如何在Mathematica中编写长函数?使用Notebook作为功能?

时间:2011-12-04 18:55:39

标签: function wolfram-mathematica

我在Mathematica笔记本的开头定义了一些变量,然后用它来计算我的结果。现在我想对变量的不同值多次进行相同的计算,并在某处使用结果。因此,使用此变量作为参数以及我的笔记本作为正文的内容来定义新函数会很有用。但是,我必须在一个输入行中编写所有内容,并且没有一种方法可以看到中间结果。

有没有什么好方法可以应对这种情况?

澄清我的意思,一个简短的例子:

我能做的是这样的事情:

In[1] := f[variable_] := (
            calculations;
            many lines of calcalutions;
            many lines of calcalutions;
            (* some comments *);
            (* finally the result... *);
            result
         )

然后使用此功能:

In[1] := f[value1] + f[value2]

但如果有人对函数f的第1行(“计算”)的中间结果感兴趣,那么有必要将该行复制到其他地方。但是你不能只删除行尾的分号来查看行的结果。

3 个答案:

答案 0 :(得分:4)

使用

    lc = Notebook[{Cell[
   BoxData[\(\(Pause[1]\) ;\)]
   , "Input"], Cell[
   BoxData[\(\(Print[\(Date[]\)]\) ;\)]
   , "Input"], Cell[
   BoxData[\(\(Print[
         \("variable = ", variable\)] \) ;\)]
   , "Input"], Cell[
   BoxData[\(result = \(variable^2\)\)]
   , "Input"]}, WindowSize -> 
  {701, 810}, WindowMargins -> 
  {{Automatic, 149}, {Automatic, 
    35}}, FrontEndVersion -> "8.0 for Microsoft Windows (64-bit) (October \
6, 2011)", StyleDefinitions -> 
  "Default.nb"];

或者,如果您将它保存在longcalc.nb下与工作笔记本相同的目录中,那么

lc = Get[FileNameJoin[{SetDirectory[NotebookDirectory[]], "longcalc.nb"}]];

现在,在你的工作笔记本中评估:

f[var_] := (variable = var; 
   NotebookEvaluate[NotebookPut[lc], InsertResults -> True]);
f[value1] + f[value2]

会做你想做的事。

答案 1 :(得分:3)

如果你改为

f[variable_] := (
            {calculations,
            many lines of calcalutions,
            many lines of calcalutions,
            (* some comments *);
            (* finally the result... *);
            result}
         )

然后你的函数将返回一个列表{ir1,ir2,...,result},其中ir1等是中间结果。然后,您可以指定{ir1,ir2,..,re}=f[value],其中re将包含最终结果ir中间结果。

这有用吗?

答案 2 :(得分:2)

你也可以在函数转储值中使用intRes={};外部函数。当然,如果在函数内部使用并行化,或者并行化整个函数,这将变得棘手。

AppendTo[intRes,ir1];
AppendTo[intRes,ir2];

f[variable_] := Block[{output={}},
                      calculations;   
                      AppendTo[output,ir1];
                      many lines of calcalutions;   
                      (* some comments *);  
                      AppendTo[output,ir2]; 
                      (* finally the result... *);   
                      {output,result}];

并执行为{intRes,result}=f[var]; - intRes将是一个interrim结果列表。

如果您不需要保留计算的中间结果,只需看到它们,那么有更多优雅的方法来查看正在发生的事情。

对于较慢的功能,请使用Monitor[]Dynamic[]PrintTemporary[]ProgressIndicator[]
随着功能的进展,这些输出的结果会发生变化和/或消失。

如果你想要一个更永久的记录(假设该函数运行得非常快),那么使用Print []查看中间输出。

除非你需要在计算中使用中间结果。