-1

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]
Erdem
  • 869
  • 4
  • 11
  • That is because Dynamic[{1,2,3}]//Dimensions gives {1}, you need something like Dynamic@Dimensions@Setting@values – Kuba Jul 27 '16 at 09:53
  • 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. – Erdem Jul 27 '16 at 10:02
  • 1
    Don't expect a new answer if you have a habit of deleting the whole content and replacing it with even more localized examples... – Kuba Jul 29 '16 at 11:34
  • 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. – Erdem Jul 30 '16 at 06:08
  • 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. – Kuba Aug 01 '16 at 06:24
  • I wish you luck but you have to put more effort in writing clear and compact questions. – Kuba Aug 01 '16 at 06:25

2 Answers2

2

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)

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • 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]. – Michael E2 Jul 27 '16 at 13:35
  • 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 – Erdem Jul 27 '16 at 14:15
  • @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. – Kuba Jul 27 '16 at 14:20
  • 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 – Erdem Jul 27 '16 at 14:45
  • @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). – Kuba Jul 28 '16 at 06:25
  • @Erdem Please take a look at the second comment here and follow the link. And questions linked there. Undestanding what Dynamic is for is essential. You can also take a look at Introduction to Dynamic tutorial. – Kuba Jul 28 '16 at 06:26
  • I am reading (going repeating what they did there) that link and I think I understand what Dynamic does. In this approach I have no access to the data other than displaying it. From the link you provided I reached link which almost the same problem that I have. I might be missing but both the links just explains why the there is a problem but not a way around it. ps: I realized that u=u/.->lims[[1]]->Dynamic@data[[1]] this was not a valid syntax :). – Erdem Jul 28 '16 at 18:15
  • @Erdem If you modify data with e.g. Sliders, You don't need Dynamic to access it. If you evaluate data in a notebook you will see that each time it will have values up to date with sliders. The question is, "when" do you want to perform your procedure and what do you want to do with u. If you want u to be always up to date you can use something like DynamicWrapper or the second argument of dynamic to do so. Or just use Dynamic[u = u/. ... ; PlotWithUOrWhatever], the point is, Dynamic is supposed to be a part of a procedure, not the interface. – Kuba Jul 29 '16 at 05:36
  • @Kuba I am trying to make the code Plot 2D planes of n dimensional function. User will choose 2 dimension variable outside lims,lims={x,z,y,p}; and assume u is u=x z y p w u in this case user choose w u plane. That means I will need to evaluate u with the slider values and do Plot3D =[uevaluated, {w,lw,rw},{u,lu,ru}] . I need to do that like it is done link second example. Inside the preplot module actually. I was thinking getting the data and plotting it but that does not make sense. – Erdem Jul 29 '16 at 08:01
  • @Erdem I've made a mistake in the last sentence, I meant "Dunamic is not supposed to be a part of a procedure but a GUI element". – Kuba Jul 29 '16 at 08:03
  • @Erdem take the code from this answer and replace the very last line with Graphics[Point@Dynamic@Thread[{data, 1}]]. It uses data to plot. So it is the same thing you need, what else do you need? – Kuba Jul 29 '16 at 08:06
  • @ Kuba either I am really missing your point in here or I am not clear enough. but I updated my question where I explain in detail. I think I explicitly need the values of the sliders so I can assign them to a variable in the function. – Erdem Jul 29 '16 at 11:39
0

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]
Erdem
  • 869
  • 4
  • 11