[How to return list after function finishes] - A New Kind of Science: The NKS ForumA New Kind of Science: The NKS Forum
Pages:1
How to return list after function finishes
(Click here to view the original thread with full colors/images)
Posted by: Nataliya
kk[s3_] := For[t = 1, t <= 700, t++,
{If[ t == 1 ,
{ contr = Table[t, {t, 1, 700}];;
}];
Do[contr[[t + tt]] += tt/s3 , {tt, 1, 300}];
?? ??? I need to return contr after outer cycle is finished ????
}] ;
Manipulate[
ListPlot[ contr, Joined -> True, PlotRange -> All], {s3, 1, 100}]
The reason to do that just modulate contr when s3 changed.
Contr is defined in 2 nested cycles.
I defined these 2 cycles as function kk[s3_].
I initiate list contr at the beginning of cycle.
1. Can I use such 2 nested cycles for definition of function kk[s3_]?
I saw only simple definitions of functions in Help examples
2. How can I return list contr after function kk[s3] finishes?
I can find only in Help examples as Return[exp], where exp is one number, not a list of numbers.
3. Is any other way to do this?
Manipulate list defined in 2 nested cycles?
Posted by: Jason Cawley
Not transparently clear what you want from the code you give.
But perhaps you want something like -
kk[s3_] := Module[{contr = Range[700], t, tt},
For[t = 1, t <= 400, t++,
Do[contr[[t + tt]] += tt/s3, {tt, 1, 300}]
]; contr]
--- as your function, and then to see the results for different values of s3 you would use -
Manipulate[
ListPlot[kk[s3], Joined -> True, PlotRange -> All], {s3, 1, 100, 1}]
Some comments: first, you had a look up into the variable "contr" with index values ranging above its length, since your outer For loop was running over 700 and the inner Do added to it was running over 300 more. If you intend a total of a thousand, you would modify what I gave above to have 700 in the For iterator, but would need Range[1000] in the initialization step.
That is necessary just to avoid throwing errors for asking for a part of a list that does not exist.
Second, Range[1000] is all that is needed to make a table of values from 1 to 1000.
You don't need to use an If to see if you are on the first step of your loop, just initialize outside of it.
The inner Do loop will not return anything after operating on the expression, unless you tell it to. But the results are in the variable contr, so all you need to do after the loop finishes is ask for the simple expression itself, contr - that is what the last line of the kk function definition is doing.
The Module is a scoping construct to allow fresh use of named variables each time the function is called, instead of using a global variable. It also accepts initializations in the starting list of declared local variables - here that is used to initialize your contr array.
Notice that the Manipulate uses a form of 1,100,1 for the possible arguments passed into the kk function. The final ,1 is needed to restrict to integer values, since by default Manipulate expects its controls to range over a real value range.
You could do the same thing with functional forms rather than the procedural For and Do loop construction, but I tried to stay close to the code form you gave and will immediately understand. Generally in Mathematica we use Map for looped operations, or occasionally Table to make new array objects, and we use functions like Nest or Fold to repeat operations on the results of a previous function application. But to stick to the form you asked, the above will do what I think you intended.
I hope this helps.
Posted by: Nataliya
Thank you very much Jason, it helps a lot. I just missed about returning variables in Module description. The program is working now!!!! It's more complicated than I wrote before, but still has outer loop and few inner loops.
I've got 2 new question- is that possible in Module return not only contr list, but second list, smth like this:
kk[s3_] := Module[{contr = Range[700], sp = {}, t, tt},
For[t = 1, t <= 400, t++,
{If[RandomReal[] < 0.5,
{
Do[contr[[t + tt]] += tt/s3, {tt, 1, 300}];
sp = Join[sp, {{t, 0.1}}];
}]
}]; sp???; contr]
Manipulate[
ListPlot[kk[s3], Joined -> True, PlotRange -> All], {s3, 1, 100, 1}]
The point of all this is to show in Manipulate Graphic with both contr and sp on the same plot. I can easily do this in regular program, but with this Manipulate thing I need somehow get both lists from Module.
And 2 question- when program start running, the window where graphics supposed to be goes to "$Aborted" stage. I guess the program runs for 15 seconds, so there is nothing to display so that happens.
When I move slider, slider is not moving properly, just stucked, then window with graphs shows "$Aborted" and after that graphs are showed in right way.
When I put numbers to small window of extended version of slider, it goes OK. The program runs for 10-15 sec. So the problem is synchronize slider and program calculating.
Thank you for listening.
Posted by: Jason Cawley
To return multiple items, just pair them up into one expression, any way you like, and then pick off the parts you want at the display stage. In this simple case, just have the returned item at the end of your kk function be -
{contr, sp}
So the initial function would become -
kk[s3_] :=
Module[{contr = Range[700], sp = {}, t, tt},
For[t = 1, t <= 400,
t++, {If[
RandomReal[] < 0.5, {Do[contr[[t + tt]] += tt/s3, {tt, 1, 300}];
sp = Join[sp, {{t, 0.1}}];}]}]; { contr, sp}]
--- though I am really not sure what you are trying to do with sp and that "Join", since it seems to just give a list t long of {t, 0.1} pairs - not very interesting. But perhaps you mean it as a dummy slot and intend to add some other measure there. (If you explain what you intend sp to be, I might help more with that...)
For the output, you want a "control panel" with multiple plots side by side, picking off the two pieces of the returned expression, contr and sp. One simple example of that might be -
Manipulate[
With[{data = kk[s3]},
Row[{ListPlot[data[[1]], Joined -> True, PlotRange -> All,
PlotLabel -> "contr", ImageSize -> 400],
ListPlot[data[[2]], Joined -> True, PlotRange -> All,
PlotLabel -> "sp", ImageSize -> 400]}]], {s3, 1, 100, 1}]
As for your reported errors, I don't get any with the code above. If you use Manipulate and you leave off the ,1 a the end, you can often get mistakes like that, that comes from trying to index a list with real number values (part Pi of a list doesn't make much sense...) But I have not reproduced the error, so that is just a guess about what you might have seen.
Posted by: Nataliya
Thank you very much for answer, it really helps. I have now all graphs I need. But problem with slider persisted.
Actually I have different code with the same pattern- outer loop and 4 inner loops. Outer loops runs with index t from 1 to 3000. I still can't synchronize slider, every time program start running the window where graphics supposed to be goes to "$Aborted" stage. When I change index t from 1 to 1000 there is no "$Aborted" stage. Clearly the problem is the program tries to show graphs, but function kk[s3] is not computed yet. Is that any way to show something in the window before kk[s3] finishes computing?
I have the same program with Java + JLink libraries, everything is fine there, because I use threads. I just can't figure out how to do the same thing in Mathematica.
Posted by: Jason Cawley
Well, without seeing your exact code I can only make suggestions. But if the problem is memory or computation speed related, one way to handle it would be to have the step that computes the whole expression meant to be displayed occur first, in a separate line above the Manipulate with a global variable assignment, or in a With statement - and then have the latter just step through the resulting expression using Part. Instead of calling kk each time you move the slider, you'd be just calling Part each time you move the slider (extremely easy and fast) - the full table of kk values already having been generated. On the assumption that you aren't running up against memory limits etc.
Posted by: Nataliya
Thank you very much, it works just fine.The only problem is I plan to have not only one variable s3 get changed but few more variables also. It can consume a lot of time. Only computing of s3 takes about 4 minutes. May be I need to run table of k3 with all possible variation of changing variables first, then write it in file and just read the file for Manipulate.
Forum Sponsored by Wolfram Research
© 2004-2008 Wolfram Research, Inc. | Powered by vBulletin 2.3.0 © 2000-2002 Jelsoft Enterprises, Ltd. |
Disclaimer
vB Easy Archive Final - Created by Xenon and modified/released by SkuZZy from the Job Openings