14
$\begingroup$

Possible Duplicate:
How to create interrelated sliders?
locking a value when manipulating variables

I need to create a Manipulate with two control parameters which are linked by some mathematical relationship. So the user can decide to use either control and when that control is changed, the other will change too.

The example below works as required, using If statements to determine if one of the parameters has been changed and setting the other parameter appropriately.

Although this code works, I suspect there is a better/neater approach which avoids the need to "manually" keep track of oldx and oldy. What is the best way to do it?

oldx = oldy = 0;
Manipulate[
If[x != oldx, y = 1/x; oldx = x];
If[y != oldy, x = 1/y; oldy = y];
{x, y},
{x, 0.1, 10}, {y, 0.1, 10}]
$\endgroup$
4
  • $\begingroup$ I am almost positive this question is a duplicate yet I cannot find it. Does this seem overly familiar to anyone else? $\endgroup$
    – Mr.Wizard
    May 10, 2012 at 14:23
  • 4
    $\begingroup$ I suppose I was thinking of this: mathematica.stackexchange.com/q/1373/121 $\endgroup$
    – Mr.Wizard
    May 10, 2012 at 14:25
  • 3
    $\begingroup$ @Mr.Wizard I would say this is similar to this one: mathematica.stackexchange.com/questions/4212/… $\endgroup$
    – FJRA
    May 10, 2012 at 14:36
  • $\begingroup$ Thanks for the links. I did search before I posted the question, but didn't come up with anything. $\endgroup$ May 11, 2012 at 19:35

3 Answers 3

17
$\begingroup$

Not sure if this is the best way, but you could consider something like this:

Manipulate[
 {x, y},
 {x, Manipulator[Dynamic[x, (x = #; y = 1/#) &], {.1, 10}] &},
 {y, Manipulator[Dynamic[y, (y = #; x = 1/#) &], {.1, 10}] &},
 Initialization :> ({x, y} = {1, 1})]

Edit V10

Since V10 one can use a shorter form:

Manipulate[
    {x, y}
  , {x, .1, 10, TrackingFunction :> ((x = #; y = 1/#) &)}
  , {y, .1, 10, TrackingFunction :> ((y = #; x = 1/#) &)}
  , Initialization :> ({x, y} = {1, 1})
]
$\endgroup$
1
  • $\begingroup$ Thanks Heike, this is exactly what I need. $\endgroup$ May 11, 2012 at 19:35
9
$\begingroup$

You could also build a custom Manipulate-like object using sliders

Panel[DynamicModule[{x, y},
    Column[{
        Grid[{
            {"x", Slider[Dynamic[x, (x = #; y = 1/#) &], {0.1, 10}], Dynamic[x]},
            {"y", Slider[Dynamic[y, (y = #; x = 1/#) &], {0.1, 10}], Dynamic[y]}
        }],
        Panel[{Dynamic[x], Dynamic[y]}, ImageSize -> 300, Background -> White]
    }], ImageSize -> 300
]]

enter image description here

$\endgroup$
2
  • $\begingroup$ Did you want the 2nd ImageSize to be an option to outside Panel? $\endgroup$
    – Michael E2
    Jul 2, 2016 at 2:43
  • $\begingroup$ @MichaelE2 Hmm, I guess that isn't necessary. I don't actually remember why I had it any more, heh. I was just correcting an accepted suggested edit that fixed a typo (missing ]) but was applied in the wrong place and messed up the formatting. $\endgroup$
    – rm -rf
    Jul 2, 2016 at 5:27
3
$\begingroup$

This?

{Slider[Dynamic[x], {0.1, 10}], 
 Slider[Dynamic[1/ x, Set[x, 1/#] &], {0.1, 10}]}
Dynamic[x]

Mathematica graphics

$\endgroup$

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