How to write a long function in Mathematica? Using Notebook as function?
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.
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.
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?
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.
链接地址: http://www.djcxy.com/p/35590.html