Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

During the execution of the following code a column of three lists and two sliders are displaying in output. The first list updates if either a or b changes. The second list updates only if the value of a is changed. Similarly, the third list updates only if the value of b is changed.

a = 0;
b = 0;
Column[
{
  Dynamic[{a, b}, TrackedSymbols :> {a,b}],
  Dynamic[{a, b}, TrackedSymbols :> {a}],
  Dynamic[{a, b}, TrackedSymbols :> {b}],
  Slider[Dynamic[a], {0, 1}],
  Slider[Dynamic[b], {0, 1}]
}
]

Next I would like to replace {a,b} by a list x with two elements:

x = {0, 0};
Column[
{
  Dynamic[{x[[1]], x[[2]]}, TrackedSymbols :> {x}],
  Dynamic[{x[[1]], x[[2]]}, TrackedSymbols :> {x[[1]]}],
  Dynamic[{x[[1]], x[[2]]}, TrackedSymbols :> {x[[2]]}],
  Slider[Dynamic[x[[1]]], {0, 1}],
  Slider[Dynamic[x[[2]]], {0, 1}]
}
]

It is easy to check that now only the first list updates. Please help me to solve this problem.

share|improve this question
4  
My first thought is that x[[1]] is not a Symbol. The dynamic updating system probably only tracks symbols, not parts of them, so probably you can't do it the second way. –  Michael E2 Sep 17 '13 at 15:09
    
I believe TrackedSymbols must be taken strictly; i.e., it accepts only symbols, not expressions. –  m_goldberg Sep 17 '13 at 16:00
    
I presume you are aware that you can write {a, b} = {0, 0} in your first example, so I ask: why doesn't that work for you? –  m_goldberg Sep 17 '13 at 16:10
    
@m_goldberg, thank you for your comment. I want to write a code, which manipulates a big list (say 20 elements). I want to display the list and update it only when its first element is changes. Moreover, I don't want to use additional "tester" variables like Dynamic[x[[1]], (x[[1]] = tester = #1) &] ... TrackedSymbols :> {tester} –  Vahagn Poghosyan Sep 17 '13 at 16:53
add comment

2 Answers 2

up vote 3 down vote accepted

You can create your own list of symbols with Unique.

Clear[x];
nVars = 20;
x = Table[Unique[x], {nVars}];
vars = Map[Hold, OwnValues@x, {-1}][[-1, -1]]
(# = 0.) & /@ x; 

(* {Hold[x$363], Hold[x$364], ...} *)

It's convenient to store the held variables, since once they are initialized, it's tricky to get the symbols unevaluated. We can get at the symbols via various tricks:

vars[[2]] /. Hold[var_] :> (TrackedSymbols :> {var}
(* --> TrackedSymbols :> {x$364} *)

Dynamic @@ vars[[3]]]
(* --> Dynamic[x$364] *)

Here's an example like the one in the question.

Grid[Transpose@
  {Table[Dynamic[x, #] &[vars[[i]] /. Hold[var_] :> (TrackedSymbols :> {var})],
     {i, Length@x}],
    Table[Slider[Dynamic @@ vars[[i]]], {i, Length@x}]}
]

Here's the output for nVars = 4, where each slider has been clicked once in turn:

Screenshot of output

share|improve this answer
    
Thank you for your smart trick. I would like to ask you, what is the role of the Refresh function ? Namely, why you don't use shorter possibility like this Table[Slider[Dynamic @@ vars[[i]]], {i, Length@x}] Table[Dynamic[x, Evaluate[vars[[i]] /. Hold[var_]:> (TrackedSymbols :> {var})]], {i, Length@x}] –  Vahagn Poghosyan Sep 17 '13 at 22:28
    
Actually what confuses me is why I seem to have to inject TrackedVariables in there twice. Doing it once does not always work. In any case, your example does not work for me from a fresh kernel in V9.0.1. For the first Dynamic[x,...], I get symbols x$363 etc. that are never updated. Of all the variations I tried, only the one with Refresh worked in all cases. I'm afraid I have not completely figured out why yet. –  Michael E2 Sep 17 '13 at 22:55
    
It is amasing, but I got such problem with your version. By the way, if I evaluate the code twice, the symbols are starting to uptate. I use also V9.0.1. In my example the sliders are constructed first. Maybe they initialize the sybols and the updating becomes possible ? –  Vahagn Poghosyan Sep 17 '13 at 23:11
    
@VahagnPoghosyan Oops, I forgot to copy the initialization line -- your comment made me notice. Now it should work. I'm not sure why the symbols need initialization. For instance {Dynamic@y, Slider[Dynamic@y]} does not need to have y initialized beforehand. –  Michael E2 Sep 18 '13 at 1:11
    
I must be missing something; why don't you merely define vars = Hold /@ x ? –  Mr.Wizard Sep 18 '13 at 2:28
show 6 more comments

Using the ideas/tricks/solutions given in comments, I arrived to the following compact code, which uses only the variables x, x1, x2, ...

nVars = 10;
Clear @@ Names["x" ~~ DigitCharacter ...]
x = Table[ToExpression["x" <> ToString[i], InputForm], {i, 1, nVars}]

Column[Table[
ToExpression["x" <> ToString[i], InputForm, Hold] /. Hold[var_] :>
    Dynamic[Evaluate[x], TrackedSymbols :> {var}]
, {i, 1, nVars}]]

Column[Table[
ToExpression["x" <> ToString[i], InputForm, Hold] /. Hold[var_] :> Slider[Dynamic[var]]
, {i, 1, nVars}]]
share|improve this answer
    
Feel free to unaccept mine and accept your own. I think it is better, and future visitors would appreciate having the best answer marked. Unless someone else posts an even better solution. –  Michael E2 Sep 18 '13 at 13:08
    
@MichaelE2, this answer is based on the ideas of your answer and comments. Both answers are acceptable for me. –  Vahagn Poghosyan Sep 18 '13 at 13:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.