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

发布于 2024-12-19 09:12:34 字数 647 浏览 2 评论 0原文

我在 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 行的中间结果感兴趣,那么就有必要将该行复制到其他地方。但是,您不能仅删除行末尾的分号来查看该行的结果。

I defined some variable in the beginning of a Mathematica notebook and used it afterwards to calculate my results. Now I want to do the same calculation several times for different values of the variable and use the results somewhere. So it would be useful to define a new function with this variable as parameter and the content of my notebook as body. But then I would have to write everything in one single input line and there would be no comfortable way to see the intermediate results.

Is there any good way to deal with this kind of situation?

To clarify what I mean, the a short example:

What I could do is something like this:

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

And afterwards use this function:

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

But if somebody is interested in the intermediate result of line 1 of function f ("calculations"), then it's necessary to copy the line somewhere else. But then you can't just remove the semicolon at the end of the line to see the line's result.

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

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

发布评论

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

评论(3

神仙妹妹 2024-12-26 09:12:34

使用

    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"];

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

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

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

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

将执行您想要的操作。

Using

    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"];

Or, if you saved it under longcalc.nb into the same directory as your working notebook, then

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

Now, in your working notebook evaluate:

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

will do what you want.

生活了然无味 2024-12-26 09:12:34

如果您这样做

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中间结果。

这有效吗?

If you do instead

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

then your function will return a list {ir1,ir2,...,result}, where the ir1 etc are the intermediate results. You could then assign {ir1,ir2,..,re}=f[value] whereupon re would contain the final result while the ir the intermediate results.

Does this work?

锦爱 2024-12-26 09:12:34

您还可以在函数外部执行 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 将是临时结果列表。

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

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

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

当然,除非您需要在计算中使用中间结果。

you can also do intRes={}; outside function and inside the function dump values into it. Of course this gets tricky if you use parallelization inside your function, or parallelize the whole function.

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

or

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

and execute as {intRes,result}=f[var]; -- intRes will be a list of interrim results.

If you don't need to retain intermediate results for computation, just see them, then there are much more elegant ways to view what's happenning.

For slower functions, use Monitor[] or Dynamic[] or PrintTemporary[] or ProgressIndicator[] 
Results of these outputs change and/or disappear as the function progresses.

If you want a more permanent record (let's say the function runs really fast), then use Print[] to see intermediate output.

UNLESS of course you need to use intermediate results in computation.

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