-1
$\begingroup$

I generated n number of Sliders using the idea from Manipulate with a variable number of sliders

But I need the updated values of these sliders to use to evaluate a function . I tried couple of things but I could not figure is out. I can get the values but even if I have 4 values , the dimension of the data is 1.How can I get these values?

  ClearAll@Preplot;
  SetAttributes[Preplot, HoldFirst]; 
  Preplot[u_, vars_, poi_] := Module[{v1, v2, posv1, posv2, vars1} ,
  v1 = poi[[1]];  (*Get the first variable for the plane of interest *)
  v2 = poi[[2]]; (*Get the second variable for the plane of interest *)
  posv1 = Position[vars, v1][[1]]; (* Position of v1 in vars list  *)
  posv2 = Position[vars, v2][[1]]; (* Position of v2 in vars list  *)
  lv1 = vars[[posv1[[1]], 2, 1]];    (*Lower limit of v1*)
  lv2 = vars[[posv2[[1]], 2, 1]]; (*Lower limit of v2*)
  rv1 = vars[[posv1[[1]], 2, 2]]; (*Upper limit of v1*)
  rv2 = vars[[posv2[[1]], 2, 2]]; (*Uppler limit of v2*)
  (*Print[{lv1,rv1,lv2,rv2}];*)
  (* Create a new list of the other dimensions vars1*)
  vars1 = Delete[vars, {{posv1[[1]]}, {posv2[[1]]}}]; 
  countersvar = Dimensions[vars1][[1]]; (*Size of it*)
  (* Lower and upper limits of n-2 variables *)

  limsL = ConstantArray[0, countersvar]; 
  limsR = ConstantArray[0, countersvar];
  lims = ConstantArray[0, countersvar];
  steplims = ConstantArray[0, countersvar];
  midpoints = ConstantArray[0, countersvar];
  transferd = ConstantArray[0, countersvar];
  Do[
  lims[[i]] = vars1[[i, 1]]; (*The variable *)

  limsL[[i]] = vars1[[i, 2, 1]]; (*Lower Limit*)

  limsR[[i]] = vars1[[i, 2, 2]]; (*Upper Limit*)

  steplims[[i]] = (-vars1[[i, 2, 1]] + vars1[[i, 2, 2]])/25; 

  midpoints[[i]] = 
  vars1[[i, 2, 1]] + (-vars1[[i, 2, 1]] + vars1[[i, 2, 2]])/
  2; (*Mid point for the sliders*)
 , {i, countersvar}];
 (*Dynamically create n-2 sliders*)
  data = midpoints;
  controls = 
  DynamicModule[{n = Length[midpoints]}, 
  Column[{Dynamic[
   Grid[Table[
     With[{i = i}, {lims[[i]], 
       Slider[Dynamic[data[[i]]], {limsL[[i]], limsR[[i]], 
         steplims[[i]]}], Dynamic[data[[i]]]}], {i, n}]]],
  Dynamic[data[[i]]];,
  (*I need to do the following because I can't use poi[[
  1]] as an argument in the plot3d*)
    (* 
  and for some reason I need to create new u function in every \
  change*)
  u1 = u /. poi[[1]] -> v3;
  u2 = u1 /. poi[[2]] -> v4;
  (*Here is my problem I need to do evaluate the u function with \
  the dynamic data which is changing as the user using sliders. 
  First I know that  Dynamic@data[[1]] is a number. 
  So I need each sliders numeric value so I can evaluate the \
  function wrt to corresponding slider value dynamically. *)

  u2 = u2 /. lims[[1]] -> Dynamic@data[[1]];
  u2 = u2 /. lims[[2]] -> Dynamic@data[[2]];
  u2 = u2 /. lims[[3]] -> Dynamic@data[[3]];
  u2 = u2 /. lims[[4]] -> Dynamic@data[[4]];
  Print[
   SetAccuracy[u2, 
    30]];  (*As you can see that the number are not evaluated *)
    \
  (*I need to evaluate u2 in a doloop of table because number of \
  variables can change *)
  (*Do[
  u2=u2/.lims[[i]]\[Rule]Dynamic@data[[i]];
  ,{i,n}];*)


  (* my goal is to able dynamically plot 2D slices of n \
     dimensional function. 
  And user will change dynamically how this 2D evaluated as well \
    as plane of interest by rerunning the code. *)

  Plot3D[u2, {v3, lv1, rv1}, {v4, lv2, rv2}, 
   PerformanceGoal -> "Quality", Mesh -> None, 
   ColorFunction -> Function[{x, y, z}, Hue[z]], 
   ImageSize -> Medium]

  }, Center]];

  Return[controls];
       ];

   (* Variables  and their limits    *)

  vars = {{x, {1, 2}}, {z, {3, 4}}, {y, {5, 6}}, {l, {7, 8}}, {w, {9, 
 10}}, {o, {11, 12}}};
  poi = {x, w};  (*Plane of interest*)
  u = Cos [x z] + Sin [Pi y l] + w^2/o;   (*Function*)
  Preplotvar = Preplot[u, vars, poi]
$\endgroup$
6
  • $\begingroup$ That is because Dynamic[{1,2,3}]//Dimensions gives {1}, you need something like Dynamic@Dimensions@Setting@values $\endgroup$
    – Kuba
    Commented Jul 27, 2016 at 9:53
  • $\begingroup$ Well, actually I don't care about the dimension. I want the values inside the data. Let me update that part in my statement. So I need the first value and I will use as x inside a n+2 dimensioned function, i.e., f(x,y,z,t,w,v) with 4 values from slider I will plot 2D plane. $\endgroup$
    – Erdem
    Commented Jul 27, 2016 at 10:02
  • 1
    $\begingroup$ Don't expect a new answer if you have a habit of deleting the whole content and replacing it with even more localized examples... $\endgroup$
    – Kuba
    Commented Jul 29, 2016 at 11:34
  • $\begingroup$ I did that because I thought I was not able to explain well what I was trying to achieve. I would not say it is more localized, i represent the exact same question in this code too. Maybe it is little too much detail and people will not read the whole thing, I would accept that. However, I am only allowed to give answer to my question, not a create second version, where I felt like it was necessary because I got a warning message that comments where getting too long. I did not want to "break" the rules. $\endgroup$
    – Erdem
    Commented Jul 30, 2016 at 6:08
  • $\begingroup$ I know but this is not a free debugging/consulting service. The more you reduce your example and make it clear the more likely you get attention. As you have noticed there are not so many people commenting your questions, I am because I like this topic, but others may just take a look and decide: "it is just a dump of code, why should I read this?". There are many not relevan things in your code, for example generation of multiple sliders is completely irrelevant, complicated functions could be just a+b instead of all this unclear procedures. $\endgroup$
    – Kuba
    Commented Aug 1, 2016 at 6:24

2 Answers 2

2
$\begingroup$

There may be a confusion in what Dynamic really is and how to use it. Follow those links please:

  1. Programming with Dynamic
  2. Why won't this work? Dynamic in a Select
  3. IntroductionToDynamic
  4. AdvancedDynamicFunctionality
  5. Synchronizing code in Dynamics with other procedures

The very last edit I will make here.

From your recent questions and updates I think you have to work more ("hands on") with sources I've provided above.

Doing things like u2 = u2 /. lims[[1]] -> Dynamic@data[[1]]; and expecting to perform calculations on u2 indicates that you don't know what Dynamic is for even though you've already been told about relevant tutorials/sources.

Not to mention Dynamic[ data[[i]] ]; in the column.

Nevertheless, this is a minimal example of code which is supposed to do what you want:

DynamicModule[{x = 0, y = {1, 0}},
 Column[{
   Slider@Dynamic[x],
   Dynamic[
    y = {1, x}; (*complicated stuff you want to do with x whenever Slider    changes it*)
    ListLinePlot[y, PlotRange -> 1] (*and a result you want the user to see*)
    ]
   }]
 ]

For heavy/time consuming procedures you may want to use SynchronousUpdating -> False - take a look at AdvancedDynamicFunctionality. You can also use DynamicWrapper for a more idiomatic approach to "background calculations". If you want to learn more follow the 5th link and linked sources there.


Old stuff, not so relevant since an original code was deleted.

Now, this should be more flexible approach, pass a symbol to Preplot, treat Preplot as a controller. I think it is also a more idiomatic approach.

ClearAll@Preplot;
SetAttributes[Preplot, HoldFirst];

Preplot[data_, lims_, initialData_, limsL_, limsR_, limsteps_] := 
  DynamicModule[{n = Length[initialData]},
   data = initialData;
   Grid[Table[With[{i = i},
      {
       lims[[i]],
       Slider[
         Dynamic[data[[i]]], {limsL[[i]], limsR[[i]], limsteps[[i]]}
       ], 
       Dynamic[data[[i]]]
       }
      ],
     {i, n}
     ]]
   
   ];

lims = {x, z, y, p};
midpoints = {0.5, 3, 4.5, 7};
limsL = {0, 2, 3, 4};
limsR = {1, 4, 6, 10};
limsteps = (limsL - limsR)/25;

Preplot[data, lims, midpoints, limsL, limsR, limsteps]

Dynamic@ First @ data (*First or whatever you want to do*)
$\endgroup$
12
  • $\begingroup$ It might be worth pointing out to the OP and others struggling to understand Dynamic[data] vs. data, that data itself contains the values to be used "to evaluate a function," not Dynamic[data]. $\endgroup$
    – Michael E2
    Commented Jul 27, 2016 at 13:35
  • $\begingroup$ I think I have the problem Michael is pointing out. I am reading to understand of I can use the values from Dynamic@data. I can get the values from the sliders Dynamic@data[[1]] first one. However, if I want to do it in a loop to evaluate the function as Do[u=u/.->lims[[i]]->Dynamic@data[[i]];,{i,n}] . The i is creating a problem for me. @Kuba @Micheal E2 $\endgroup$
    – Erdem
    Commented Jul 27, 2016 at 14:15
  • $\begingroup$ @Erdem using my approach you can just use Dynamic@whateverFunction@data instead of whateverFunction@Dynamic@Data. With yours, you have to strip the Dynamic, you are returning, with Setting. Why whateverFunction will usualy not work on Dynamic[data] is explained in the answer linked in my previous comment. $\endgroup$
    – Kuba
    Commented Jul 27, 2016 at 14:20
  • $\begingroup$ first, thank you for taking your time and helping. The idea of using the dynamic is to able to obtain current values of the sliders. Without dynamic the current values will be the initialData all the time. I even tired to insert the Plot3D in the preplot module. That way I would not need to get the data out. What troubles me why u=u/.->lims[[1]]->Dynamic@data[[1]] is working but I can't do that inside a loop. Assume u = x z y p w o, & lims[[1]]=x, so this takes the x value and evaluates the u function. @Kuba $\endgroup$
    – Erdem
    Commented Jul 27, 2016 at 14:45
  • $\begingroup$ @Erdem please focus u=u/.->lims[[1]]->Dynamic@data[[1]] this is an invalid syntax with those two ->. Moreover it does not what you think it does. u will have Dynamic inside, it is not a value, it is a specially handled place in a notebook but you can't use it as an ordinary variable. But you can use data and wrap Dynamic over the whole GUI element that you want to display. Dynamic[value] only makes sense when it is meant to display just Dynamic[value] (or for the FrontEnd in some cases, not relevant here). $\endgroup$
    – Kuba
    Commented Jul 28, 2016 at 6:25
0
$\begingroup$

Here is the solution. It was too obvious maybe, sorry for taking so many time in here.

    ClearAll@Preplot;
    SetAttributes[Preplot, HoldFirst]; 
    Preplot[u_, vars_, poi_] := Module[{v1, v2, posv1, posv2, vars1} ,
    v1 = poi[[1]];  

    v2 = poi[[2]];   
    posv1 = Position[vars, v1][[1]]; (* Position of v1 in vars list  *)

    posv2 = Position[vars, v2][[1]]; (* Position of v2 in vars list  *)

    lv1 = vars[[posv1[[1]], 2, 1]];    (*Lower limit of v1*)

    lv2 = vars[[posv2[[1]], 2, 1]]; (*Lower limit of v2*)

    rv1 = vars[[posv1[[1]], 2, 2]]; (*Upper limit of v1*)

    rv2 = vars[[posv2[[1]], 2,  2]]; (*Upper limit of v2*)
    (*Print[{lv1,rv1,lv2,rv2}];*)
   (* 
   Create a new list of the other dimensions vars1*)
   vars1 = Delete[vars, {{posv1[[1]]}, {posv2[[1]]}}]; 
   countersvar = Dimensions[vars1][[1]]; (*Size of it*)
   (* 
   Lower and upper limits of n-2 variables *)

   limsL = ConstantArray[0, countersvar]; 
   limsR = ConstantArray[0, countersvar];
   lims = ConstantArray[0, countersvar];
   steplims = ConstantArray[0, countersvar];
   midpoints = ConstantArray[0, countersvar];
   transferd = ConstantArray[0, countersvar];
    Do[
    lims[[i]] = vars1[[i, 1]]; (*The variable *)

    limsL[[i]] = vars1[[i, 2, 1]]; (*Lower Limit*)

   limsR[[i]] = vars1[[i, 2, 2]]; (*Upper Limit*)

    steplims[[i]] = (-vars1[[i, 2, 1]] + vars1[[i, 2, 2]])/
    25; (*Step size for the slider*)

    midpoints[[i]] = 
    vars1[[i, 2, 1]] + (-vars1[[i, 2, 1]] + vars1[[i, 2, 2]])/
    2; (*Mid point for the sliders*)
   , {i, countersvar}];
   (*Dynamically create n-2 sliders*)
   data = midpoints;
   controls = 
   DynamicModule[{n = Length[midpoints]}, 
   Column[{Grid[
   Table[With[{i = i}, {lims[[i]], 
      Slider[Dynamic[data[[i]]], {limsL[[i]], limsR[[i]], 
        steplims[[i]]}], Dynamic[data[[i]]]}], {i, n}]],

   Dynamic[u1 = u /. poi[[1]] -> v3;
    u2 = u1 /. poi[[2]] -> v4;

     Do[
     u2 = u2 /. lims[[i]] -> data[[i]];
     , {i, n}];


    Plot3D[Evaluate[u2], {v3, lv1, rv1}, {v4, lv2, rv2}, 
    PerformanceGoal -> "Quality", Mesh -> None, 
    ColorFunction -> Function[{x, y, z}, Hue[z]], 
    ImageSize -> 200]]

     }, Center]];

    Return[controls];
    ];
  (* Variables  and their limits    *)
  vars = {{x, {1, 2}}, {z, {3, 4}}, {y, {5, 6}}, {l, {7, 8}}, {w, {9, 
  10}}, {o, {11, 12}}};
  poi = {x, w};  (*Plane of interest*)

  u=Cos [x z] + Sin [Pi y l] + w^2/o;   (*Function*)
  Preplotvar =  Preplot[u, vars, poi]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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