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.

If I have a function call wrapped in Dynamic can I make one or more of the parameters in the call non-dynamic?

i.e. I would like to make diskcx and diskcy in the following snippet be unaffected by changes in their values after the call while making the output of colorer and the value of rectangleCoordinates dynamic:

...Graphics[ {Dynamic[colorer[ rectangleCoordinates, {radius + diskcx, diskcy}, .4 radius]], Disk[{radius + diskcx, diskcy}, .4 radius]....

Edit: As requested, here is the relatively large block of code the problem is concerned with. Of note is that: rectangleCoordinates refers to a set of rectangles that can pass over a disk to change its color;colorer[rectangles_,center_,radius_] is a function whose output is a color that depends on whether a rectangle passes over the disk defined by the center and radius that are given as parameters; the radius variable is defined outside the module; and of course as a precondition amount_ is never greater than 5.

    diskGenerator[amount_, space_] := 
    Module[{z = 1, listx, listy, positionx, positiony, diskcx, diskcy, 
    intervals = space/11, disks = {}},
    listx = {1, 3, 5, 7, 9};
    listy = {1, 2, 3, 7, 8, 9, 10};
    For[z = 1, z <= amount, z++,
      positionx = RandomChoice[listx];
      positiony = RandomChoice[listy];
      listx = DeleteCases[listx, positionx];
      (*listy=DeleteCases[listy,positiony];*)
      diskcx = positionx*intervals;
      diskcy = positiony*intervals;
      disks = 
      AppendTo[disks,

      Graphics[{
        Dynamic[colorer[rectangleCoordinates, {radius + diskcx, diskcy}, .4 radius]], 
        Disk[{radius + diskcx, diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {.5 radius + diskcx, Sqrt[3]/2 radius + diskcy}, .4 radius]], 
        Disk[{.5 radius + diskcx, Sqrt[3]/2 radius + diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {-.5 radius + diskcx, Sqrt[3]/2 radius + diskcy}, .4 radius]], 
        Disk[{-.5 radius + diskcx, Sqrt[3]/2 radius + diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {-radius + diskcx, diskcy}, .4 radius]], 
        Disk[{-radius + diskcx, diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {-.5 radius + diskcx, -(Sqrt[3]/2) radius + diskcy}, .4 radius]], 
        Disk[{-.5 radius + diskcx, -(Sqrt[3]/2) radius + diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {.5 radius + diskcx, -(Sqrt[3]/2) radius + diskcy}, .4 radius]],
        Disk[{.5 radius + diskcx, -(Sqrt[3]/2) radius + diskcy}, .4 radius],

        Dynamic[colorer[rectangleCoordinates, {diskcx, diskcy}, .5 radius]], 
        Disk[{diskcx, diskcy}, .5 radius]
      }]
      ]
    ];
    Return[disks]
    ];

I'm thinking I should just create a List of diskcx and diskcy values that the function would refer to just to avert the problem, but if this solution seems unsound I would be happy to read others. Thanks for your time, in any case.

share|improve this question
    
Please post more of your code so we can see how these variables are filled, and be able to determine how to provide the best solution. –  R Hall May 6 '12 at 2:14
    
I did as you asked. If it's still overly vague, please let me know. –  Tips McGee May 6 '12 at 4:02
1  
In the function above colorer uses input called rectangles, but rectangleCoordinates is the variable called in the function diskGenerator. Also the variable intervals should be defined outside the module variable list since it takes input from space. The two variables mentioned are not included in the Dynamic calculation but appear only as input to the Dynamic, so your problem is not there but with the colorer function and the way it's called. Where does the input for the variable radius come from? –  R Hall May 6 '12 at 12:55
    
I meant it like rectangles_ was part of the signature of colorer: the name of its parameter. Apologies for that confusion. As you suggested I'll move intervals outside the variable list. You were correct, however, the issue was in the way it was being called, which is what Mr. Wizard's comment below has now addressed. I think with that solved I shouldn't have any other problems with this project I'm working on. Thank you for all your advice though. –  Tips McGee May 6 '12 at 19:16
add comment

2 Answers

up vote 4 down vote accepted

You have the option of only updating the Dynamic object when a specified set of symbols changes, but all symbol values will update when an update is triggered. For example:

a = 1; b = 2;
Dynamic[{a, b}, TrackedSymbols :> {a}]

Then evaluating b = 3; should not change the output. Nevertheless, when you evaluate a = 4; you will get {4, 3} rather than {4, 2}.

You could use Dynamic only on the objects you want to be dynamic, e.g. {Dynamic[a], b}, but since this is an obvious solution there is presumably a problem with that.


Incorporating my comment for persistence:

If I understand your problem you can force evaluation of the symbols outside of Dynamic, e.g. Dynamic[{a, #}]& @ b will use the fixed value of b, assuming that b has a value at the time of evaluating that expression.

share|improve this answer
    
Yes, if Dynamic isn't wrapped around colorer then it never seems to change the disks' colors. –  Tips McGee May 6 '12 at 3:56
1  
@TipsMcGee if I understand your problem you can force evaluation of the symbols outside of Dynamic, e.g. Dynamic[{a, #}]& @ b will use the fixed value of b. –  Mr.Wizard May 6 '12 at 8:38
    
Hey, that was exactly what I needed. Thanks! –  Tips McGee May 6 '12 at 19:08
add comment

The solution given by Mr.Wizard using pure functions is absolutely correct and useful. For the following reasons I still wanted to mention a construct (With) which I think is a more standard way to solve the general problem to insert evaluated subexpressions into an expression which is held, and that's what you are actually after here.

  • In general my experience with Mathematica is that it's always worth to learn those internal functions which were made for the purpose you are using them. That will make your code simpler, less error prone, easier to read and -- in many cases -- more performant.
  • It's good to know the standard ways to do certain things. You'll find it easier to read and understand other people's code, and I think you'll find With in a lot of good code, on this site and elsewhere.
  • Using non-standard ways, like pure functions in this case, can be a sign of knowing your tool and elegance if you are aware of the alternatives. It rather is a sign that you are not really knowing what you are doing if you are not aware of them.
  • I have seen a lot of code in which people have used nonstandard ways to do things which became more and more complicated over time because of not knowing the alternatives. This is not, by the way, a phenomenon limited to Mathematica.

The more standard way to achieve what you want is to use With, which is somewhat more verbose than the version with the pure function but basically does the same thing:

With[{diskcx=diskcx,diskcy=diskcy},
  Graphics[{Dynamic[colorer[ rectangleCoordinates, {radius + diskcx, diskcy}, .4 radius]], 
    Disk[{radius + diskcx, diskcy}, .4 radius]
]
share|improve this answer
    
I see. This actually would have been a much cleaner implementation in my case, too; I had to make a pure function for every Dynamic whereas this could have just surrounded the entire block of code I used Dynamic in. Still, for a single Dynamic, the pure functions are much easier. –  Tips McGee May 11 '12 at 11:02
    
As I said, there is nothing wrong with the pure function way, and there are some other possibilities not mentioned. I have elaborated why I did add my answer although I consider Mr. Wizards answer to be absolutely correct and useful and I fully support your decision to accept it. –  Albert Retey May 13 '12 at 10:20
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.