1
$\begingroup$

I'm trying to do some interactive fitting of data using an arbitrary number of the same function (a Gaussian in this case). This means that I also have an arbitrary number of variables and constraints. I want to do some preprocessing on the data in an interactive manner, and have it automatically update my list of constraints. I would also like the constraints to be manually editable in some way (I'm using InputField because it seemed intuitive) so that they can be further refined if necessary.

The issue I'm running into is that I can't figure out how to get the InputField to update automatically. I think that it has something to do with the way that my grid of constraints is constructed (using With and Sequence) or the way I'm selecting variables in my Table, and that Dynamic doesn't realize that any values have changed. I'm also not sure if creating variables using the syntax $\mu$[i]["min"] is the source of my problems. It seems to work really nicely for everything else I'm doing in my code, but that might be pure luck.

I've tried to create an MWE below. I can slide the $\mu$ slider around and the minimum is not updated. In my actual code, I can show the value of $\mu$[1]["min"] as an Epilog to a graph, and it seems to change with the slider. However, the constraints only seem to update when I increase or decrease $n$ (the total number of Gaussians), which seems like I must be triggering it to rebuild my Table.

I've tried using Refresh, setting an UpdateInterval for Dynamic, setting ContinuousAction -> True for the InputField, and explicitly setting TrackedSymbols :> {\[Mu][1]["min"] for Dynamic, with no luck. Although I'm not entirely sure that $\mu$[1]["min"] actually counts as a variable in Mathematica, so I also tried :> {\[Mu]} hoping that it might see that a SubValue of $mu$ changed. I have also tried adding n++; n-- to my Dynamic in the hopes that it would trigger my table to rebuild, but I think that just ends up resetting $n$ before the Grid can see that $n$ has even changed.

Does anyone have any ideas on how to get the InputField (or some other interactive element that makes it easy to enter numbers) to update either continuously with the slider or at least update within a few seconds?

DynamicModule[
 {
  (* Set the initial number of Gaussians *)
  n = 1,

  (* Create a list of fitting variables *)
  sortvars = Table[\[Mu][i], {i, 100}]
  },

 (* Set the minimum and maximum for the constraints on each variable *)
 Do[\[Mu][i]["min"] = 300; \[Mu][i]["max"] = 1000, {i, 100}];
 Grid[{{

    (* Manipulators for \[Mu][1]["min"] and n *)
    Row[{"\[Mu][1][min]:  ", 
      Manipulator[Dynamic[\[Mu][1]["min"]], {200, 1700}], Spacer[10], 
      "n:  ", Manipulator[Dynamic[n], {1, 10, 1}]}]},
   {Dynamic[

     (* Construct a nice grid to show all of the constraints *)
     Grid[
      {Table[
        With[
         {i = i},
         Sequence @@ {InputField[Dynamic[sortvars[[i]]["min"]], 
            Number, FieldSize -> 5], "<", 
           ToString[\[Mu][i]], "<", 
           InputField[Dynamic[sortvars[[i]]["max"]], Number, 
            FieldSize -> 5]}
         ],
        {i, n}
        ]}
      ]
     ]
   }}]
 ]
$\endgroup$
2
$\begingroup$

This is maybe not yet all you need, but at least the input field variable changes as desired. Writing a bit more complicated UI-structures seems still to be time-consuming in WL. Probably this will change once the GUI facilities get modernized one day.

    DynamicModule[
 {
  (* Set the initial number of Gaussians *)
  n = 1,
  (* Create a list of fitting variables *)
  sortvars = Table[\[Mu][i], {i, 100}]
  },
 (* Set the minimum and maximum for the constraints on each variable *)
 Do[\[Mu][i]["min"] = 300; \[Mu][i]["max"] = 1000, {i, 100}];
 Grid[{{

    (* Manipulators for \[Mu][1]["min"] and n *)
    Row[{"\[Mu][1][min]:  ", 
      Manipulator[Dynamic[\[Mu][1]["min"]], {200, 1700,1}], Spacer[10], 
      "n:  ", Manipulator[Dynamic[n], {1, 10, 1}]}]},
   {
     (* Construct a nice grid to show all of the constraints *)
     Dynamic[
     Grid[
      {Table[With[{vari=sortvars[[i]]},
        Sequence @@ {InputField[Dynamic[vari["min"]], 
            Number, FieldSize -> 5], "<", 
           ToString[\[Mu][i]], "<", 
           InputField[Dynamic[vari["max"]], Number, 
            FieldSize -> 5]}]
         ,
        {i, n}
        ]}
      ], TrackedSymbols:>{n}]

   }}]
 ]
$\endgroup$
  • $\begingroup$ Awesome, thanks! It works perfectly with the rest of my code as well. Yeah, I'm not sure MMA was the best choice to build my UI, but I already had most of the other code written so I just kind of went with it. $\endgroup$ – MassDefect Jun 13 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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