2nd Update
Here's a snapshot of a graphical user interface I'm thinking. I hope this could be self-explanatory and demonstrate the functionalities I mentioned in the 1st update. Thank you all!
Update
I really appreciate Kuba's help. The code greatly helped me to understand the approach of achieving the task. Here I still have a few quick questions in refinement.
I saw Kuba set the range of Slider from 0 to 0.99 instead of 1, as an approach to protect all the others becoming 0 at the same time. I'm considering to have a column of Checkbox right next to the slider. Only when the box is checked, the variable would have corresponding updates. So in this case, ideally even all the other elements become 0, (means one of the element is 1 at that time), when that 1-element decreases, all the others should equally increase correspondingly.
Is there a way to construct a dynamic list whose length is user-defined, and create corresponding number of sliders? And also, is there a way to allows users to input the value of each element from InputField? That means the variable is Slider-control and InputField-control at same time.
Original Question
I would like to have a dynamic list of five elements such that if one changes, all the others would change correspondingly to keep the sum invariant at 1. This requirement comes from a practical problem where five probabilities always have a total of 1. I would like to have a slider control for each element in the list which can change that element. When any of the sliders is moved, the list should update as described.
My intention was to create a pure function f
that would allow the list to be updated following the rule of sum is 1, as the elements of the list were changed. But this didn't work in the way I thought it should.
And here is what I tried:
v = {0.2, 0.2, 0.2, 0.2, 0.2};
v[[1]] = Dynamic[val];
Dynamic[val]
Slider[Dynamic[val]]
sum = 1;
Dynamic[v]
f := (#/(sum - #))*(sum - val) &
Slider[Dynamic[v[[1]], f /@ v], {0, 1}]
Slider[Dynamic[v[[2]], f /@ v], {0, 1}]
Slider[Dynamic[v[[3]], f /@ v], {0, 1}]
Slider[Dynamic[v[[4]], f /@ v], {0, 1}]
Slider[Dynamic[v[[5]], f /@ v], {0, 1}]
The algorithm of distribution is that if the first element changes, the other four would change proportionally. For instance, if I change the first 0.5 -> 0 in {0.5, 0.05, 0.1, 0.15, 0.2}
, the list would automatically update to {0, 0.1, 0.2, 0.3, 0.4}
.