3
$\begingroup$

I made a Manipulate box that is working very well, using lots of random numbers. I would like to add a button to "reset" (i.e. to change, randomize, or reselect) all the random parameters.

Here's the code I added to the Manipulate box, but it doesn't work :

Row[{Spacer[200],
    Button[
        "Randomize all parameters",
        Clear["alpha", "Phase", "Amplitude", "Frequency"],
        Appearance -> "Palette",
        ImageSize -> {150, 28}
    ]
}],

What should I use instead of Clear["alpha", "Phase", "Amplitude", "Frequency"] to randomize all these parameters, according to their definitions ?

EDIT : Here's a complete MWE showing the problem :

Clear["Global`*"]

Amplitude[k_] := Amplitude[k] = RandomReal[{0.5, 1.5}]
Frequency[k_] := Frequency[k] = RandomReal[{1, 5}]
Phase[k_] := Phase[k] = RandomReal[{0, 2Pi}]

Manipulate[
    Plot[
        Sum[Amplitude[k]Sin[2Pi Frequency[k]t + Phase[k]],
        {k, 1, Nwaves}
        ],
    {t, 0, 1},
    Frame -> True, 
    PlotRange -> {{0, 1}, {-5, 5}},
    PerformanceGoal -> "Quality",
    ImageSize -> 600
    ],
    {{Nwaves, 1, Style["Number of waves", 10]}, 1, 20, 1, Appearance -> "Labeled"},
    Delimiter,
    Row[{
        Button[
            "Reset random parameters",
            {(* Reset command for "Amplitude", "Frequency", "Phase" *)},
            Appearance -> "Palette",
            ImageSize -> {250, 28}
        ]
    }],
    ControlPlacement -> Bottom
]

EDIT 2 : The "duplicate" referenced above doesn't apply to this question, since the answers are specific to that question. I don't see how to apply them to the question here.

$\endgroup$
  • $\begingroup$ Maybe you can directly manipulate the DownValues. Something like, DownValues[alpha] = DownValues[alpha][[{-1}]], which resets the rules associated with alpha to only the original definition. Without an idea of what's happening inside the Manipulate, that's the best I can say right now. $\endgroup$ – march Mar 25 '16 at 15:24
  • $\begingroup$ Ok then, I'll add a complete MWE to the question in a few minutes. $\endgroup$ – Cham Mar 25 '16 at 15:31
  • $\begingroup$ Doesn't have to be complete! Just an idea of what it looks like, a minimal example as it where! $\endgroup$ – march Mar 25 '16 at 15:31
  • $\begingroup$ @march, I've edited the question. $\endgroup$ – Cham Mar 25 '16 at 15:48
  • $\begingroup$ @garej, I've added an edit to my question. The answers in your "duplicate" are very specific to the question, and I don't see how to apply them to my problem. I believe my question is much more general. $\endgroup$ – Cham Mar 25 '16 at 16:05
3
$\begingroup$

Here's one way, by directly manipulating the DownValues of the variables:

resetDVs[var_Symbol] := (DownValues[var] = List@Last@DownValues[var])

Then, in the place where

{(* Reset command for "Amplitude", "Frequency", "Phase" *)}

appears in your code, put

{resetDVs /@ {Phase, Amplitude, Frequency}}

This takes advantage of the fact that the definitions of these functions will necessarily be the last element of the list of DownValues. This breaks if you have definitions elsewhere, but since you are Clearing first, this should be fine.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Hmm, it isn't clear. My button do nothing. Could you post a modified version of the MWE code I've added to my question ? $\endgroup$ – Cham Mar 25 '16 at 15:53
  • $\begingroup$ Did you include resetDVs after Clear["Global*"]`? $\endgroup$ – march Mar 25 '16 at 15:54
  • $\begingroup$ I've added your first line above (resetDVs[var_Symbol]) after the Clear all, yes. Also, take note that I do have other definitions in my whole code, but not random variables. $\endgroup$ – Cham Mar 25 '16 at 15:56
  • $\begingroup$ I'll post a simplified working version. $\endgroup$ – march Mar 25 '16 at 15:56
  • 1
    $\begingroup$ Also, hitting the button doesn't change the image immediately, you have to move the scroll-bar in order to see a difference. It's easiest to see by going to the NWaves == 1, hitting the rest button, and then scrolling away and back to NWaves == 1. $\endgroup$ – march Mar 25 '16 at 15:58
2
$\begingroup$

I may have found a simple solution, but it asks that I change a big chunk of my whole code. In the case of the MWE above, it's very simple :

Just add a new random parameter to the random functions :

Clear["Global`*"]

Phase[k_, r_] := Phase[k, r] = RandomReal[{0, 2 Pi}]
Amplitude[k_, r_] := Amplitude[k, r] = RandomReal[{0.5, 1.5}]
Frequency[k_, r_] := Frequency[k, r] = RandomReal[{1, 5}]
r = 1;

Manipulate[
    Plot[
        Sum[Amplitude[k, r]Sin[2Pi Frequency[k, r]t + Phase[k, r]], {k, 1, Nwaves}],
    {t, 0, 1},
    Frame -> True,
    PlotRange -> {{0, 1}, {-5, 5}},
    PerformanceGoal -> "Quality",
    ImageSize -> 600
    ],
    {{Nwaves, 1, Style["Number of waves", 10]}, 1, 20, 1, Appearance -> "Labeled"},
    Delimiter,
    Row[{
        Button[
            "Reset random parameters",
            {r = RandomReal[]},
            Appearance -> "Palette",
            ImageSize -> {250, 28}
        ]
    }],
    ControlPlacement -> Bottom
]

The effect is immediate on the picture.

Is there a better/simpler way of doing this ? Is this trick robust, or are there any drawback that I don't see yet ?

|improve this answer|||||
$\endgroup$
  • $\begingroup$ This is clever, and I doubt that you'll ever get overlapping r's. However, depending on how many times you reset, the DownValues to the function are going to proliferate. I imagine it would take a lot of resets to actually start filling up memory, but it's at least something to keep in mind. $\endgroup$ – march Mar 25 '16 at 16:30
  • 1
    $\begingroup$ Wow ! Manipulate is so powerfull to visualize things ! It's incredible ! :-) The Randomize button is now giving some very nice outputs ! I couldn't resist to post a picture of my project : s17.postimg.org/qjbpsg21r/manipulate.jpg $\endgroup$ – Cham Mar 25 '16 at 16:49
1
$\begingroup$

As you are using memoization you can Map Unset over the saved states. Quiet is also used as depending on how far the slider has been moved along (up and back) then not all 20 saved states may be present.

You can add

Function[{f}, Quiet@Unset[f[#]] & /@ Range[20]] /@ {Amplitude, Frequency, Phase}

as your (*Reset command for "Amplitude","Frequency","Phase"*) in Button.

This updates immediately on click and does not require redefining your functions (i.e. adding additional parameters).

Hope this helps.

|improve this answer|||||
$\endgroup$

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.