Message Boards Message Boards

0
|
6825 Views
|
6 Replies
|
0 Total Likes
View groups...
Share
Share this post:

How to dynamically update some variables and some not, wrt RandomInteger?

Posted 11 years ago
Hi,

What is the correct method to implement the following?

Requirement:

- We have an array a of randomly generated integers (RandomInteger[]) of variable length n.
- We compute and display the multiple t*a for a variable t.
- We expect the following behaviour:
  1. If we change the value of the array length n, then the array a should be newly updated by new random values (and also the output t*a, of course).
  2. If we change the value of the factor t, then the array a should not change, i.e., no generation of new random variables, and the output should just update the multiple t*a with the new t.
  3. Of course, any output of the variables t and n should also be updated, if changed.
Basically, I have a problem with behaviour 2., since changing the variable t apparently triggers the random generator to generate new variables.

Examples:


This has the correct update behaviour for n, but not for t:
 ClearAll["n", "t", "a"]
 Manipulate[
 
  Column[{
    Row[{Text["n = "], n}],
    Row[{Text["t = "], t}],
    Row[{Text["a = "], ToString[a]}],
    Row[{Text["ta = "], ToString[t a]}]
    }],
{{n, 4, "n ="}, 1, 60, 1},
{{t, 2, "t ="}, -20, 20, 0.1},

Initialization :> (
   a := Table[RandomInteger[{0, 100}], {i, 1, n}];
   )

]

This has the correct update behaviour for t, but not for n:
 ClearAll["n", "t", "a"]
 Manipulate[
 
  Column[{
    Row[{Text["n = "], n}],
    Row[{Text["t = "], t}],
    Row[{Text["a = "], ToString[a]}],
    Row[{Text["ta = "], ToString[t a]}]
    }],
{{n, 4, "n ="}, 1, 60, 1},
{{t, 2, "t ="}, -20, 20, 0.1},

Initialization :> (
   a = Table[RandomInteger[{0, 100}], {i, 1, n}];
   )
]

I tried to figure out how to maybe use BlockRandom[] or Module[], but didn't get it. Somewhat of a workaround is the following, but includes the additional use of a button to explicitely generate newly a:
 ClearAll["n", "t", "a"]
 Manipulate[
  arr = BlockRandom[a];
  Column[{
    Row[{Text["n = "], n}],
    Row[{Text["t = "], t}],
    Row[{Text["a = "], ToString[arr]}],
    Row[{Text["ta = "], ToString[t arr]}]
    }],
{{n, 4, "n ="}, 1, 60, 1},
{{t, 2, "t ="}, -20, 20, 0.1},
Button["Generate new a",
  arr = Table[RandomInteger[{0, 100}], {i, 1, n}]],

Initialization :> (
   a := Table[RandomInteger[{0, 100}], {i, 1, n}];
   )
]

Btw., I don't understand why the button action is only executed every second time I click (any reason for this?).

I am very interested to learn how this functionality would be implemented by a Mathematica expert! Since any further "trial and error" tweaking by me will probably only be a "dirty" workaround :-)

Thank you!

Andreas
POSTED BY: Andreas Leiser
6 Replies
Hi Daniel,

ah, by the way: of course it must be currN == lastN. I wrote it the wrong way round...

Yes, now it seems to work. Finally I added an initialization line, so that we don't get the (first and only) error message about the loop due to non initialization of lastN. Now, it seems to be perfect. Summarizing:
 ClearAll["n", "t", "a"] ;
 Manipulate[currN = n;
  b = If[(currN == lastN), b,
    Table[RandomInteger[{0, 100}], {i, 1, n}]];
  lastN = currN;
  Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}],
    Row[{Text["a = "], ToString[b]}],
    Row[{Text["ta = "], ToString[t b]}]}],
  {{n, 4, "n ="}, 1, 60, 1},
{{t, 2, "t ="}, -20, 20, 0.1},

Initialization :> (
   lastN := 0;
   )
]

This does the job perfectly. Thanks for the help!

Bye
POSTED BY: Andreas Leiser
Posted 11 years ago
Hi  Andreas,
yes you are right the example seem to work if you open only it in mathematica.
if you copy the same example two time in the same notebook or in different notebook both example go in loop.
I think to have an idea because this happen, both example use the same variable and each example affects the another because the variable declared inside
Manipulate seem became global variable and them are defined every time the manipulate loop is called.
This is my sensation... I renamed the variables defined inside the Manipulate and now not more loop...
you can try to put the two example in the same notebook or in two different notebook.
 
example1:
ClearAll["n", "t", "a"] Manipulate[currN = n; a = If[(currN == lastN), a, Table[RandomInteger[{0, 100}], {i, 1, n}]]; lastN = currN; Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}], Row[{Text["a = "], ToString[a]}], Row[{Text["ta = "], ToString[t a]}]}], {{n, 4, "n ="}, 1, 60, 1}, {{t, 2, "t ="}, -20, 20, 0.1}]
example2:
ClearAll["n", "t", "a"] Manipulate[currN1 = n; b = If[(currN1 == lastN1), b, Table[RandomInteger[{0, 100}], {i, 1, n}]]; lastN1 = currN1; Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}], Row[{Text["a = "], ToString[b]}], Row[{Text["ta = "], ToString[t b]}]}], {{n, 4, "n ="}, 1, 60, 1}, {{t, 2, "t ="}, -20, 20, 0.1}]
try to put the two example in the same notebook or in two different notebook. Bye,
POSTED BY: daniel
Hi,

I am sorry, but your last solution can't work as intended, since your condition is currN == lastN. In any case, I think it should be currN != lastN as in your previous suggestion. Also, I only see this and the addition of the bracket ( ) around the condition as the difference between your two solutions (the brackets are imo not necessary).

If you implement your two solutions in two files and -- for being 200% certain to initialize everything cleanly -- start mathematica with the notebook each time freshly, then

- your suggestion 1 equals my example 1 in its behaviour,
- your suggestion 2 doesn't work because the condition jumps into an infinite loop exactly because of the behaviour I am struggling with...
POSTED BY: Andreas Leiser
Posted 11 years ago
Hi, I am a beginner with mathematica, I dont' know if I understand your problem, but you can try this code:

it seems that the simple problems in this forum are ignored by the experts,
maybe need a license gold for answers. However, putting the top of the function manipulate the calculation of the array, I realized that this is called infinite times,

ClearAll["n", "t", "a"] Manipulate[a = Table[RandomInteger[{0, 100}], {i, 1, n}]; Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}], Row[{Text["a = "], ToString[a]}], Row[{Text["ta = "], ToString[t a]}]}], {n, 0, 60, 1}, {t, 0, 1, 0.1}]


so with this dirty trick I avoid to recalculate every time the array but I do calculate only when n changes
ClearAll["n", "t", "a"] Manipulate[currN = n; a = If[currN != lastN, a, Table[RandomInteger[{0, 100}], {i, 1, n}]] ; lastN = currN; Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}], Row[{Text["a = "], ToString[a]}], Row[{Text["ta = "], ToString[t a]}]}], {{n, 4, "n ="}, 1, 60, 1}, {{t, 2, "t ="}, -20, 20, 0.1}]
POSTED BY: daniel
Hi Daniel,

thanks for your reply. But the problem with your solution is, that changing t still triggers the random number generator to be executed and generating a new array a (at least on my computer). This, I don't want, however.  Your solution behaves like my first example.

Best,
Andreas
POSTED BY: Andreas Leiser
Posted 11 years ago
Hello,
now seem work. The random array is recalculate only when n change and not when t change,
ClearAll["n", "t", "a"] Manipulate[currN = n; a = If[(currN == lastN), a, Table[RandomInteger[{0, 100}], {i, 1, n}]]; lastN = currN; Column[{Row[{Text["n = "], n}], Row[{Text["t = "], t}], Row[{Text["a = "], ToString[a]}], Row[{Text["ta = "], ToString[t a]}]}], {{n, 4, "n ="}, 1, 60, 1}, {{t, 2, "t ="}, -20, 20, 0.1}]
POSTED BY: daniel
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract