# .wchoose([0.1, 0.2, 0.7]) Keeping proportions consistent?

Hi everyone,

1. How can I keep the sum of the three relative to each other, keeping the sum of them always equal to 1?

let’s say that with a knob I would like to move the weight of the probabilities, from the first to the second and then to the third value etc…

Any strategie?

when the knob is full left = .wchoose([1.0, 0.0, 0.0])
when the knob is halfway = .wchoose([0.0, 1.0, 0.0])
when the knob is full right = .wchoose([0.0, 0.0, 1.0])

1. How can I change the values ​​in real time,?

Best

.

hey,
not very pretty, but i think it should work:

``````(

~chances = { |val|
var given = ["red", "blue", "green"];
var chanceArray = {|x|
[(1-(x*2)).clip(0,1), 1 - ((x - 0.5).abs * 2), ((x - 0.5) * 2).clip(0, 1)]
};
given.wchoose(chanceArray.(val))

};
)

``````

don’t know what the values for the knob are. you would need to normalize it to `0 < val >1`. you could add a test to the function to be safe. or just scale it in the function e.g. ` val.linlin(0, 126, 0, 1)`

1 Like

what exactly do you mean? maybe you can give a little more context.

You can use normalizeSum:

``````[1, 2, 3, 4].normalizeSum; // -> [ 0.1, 0.2, 0.3, 0.4 ]

``````
2 Likes

Yee, thanks! val.linlin(0, 127, 0, 1); Works for me I’m using a simple Midi knob.

Thanks, I remember this method in the documentation, but probably I just made a mistake in the thinking, and asking.

My idea it is :
using a midi knob 0-127 how could I change the wights in the array .wchoose([0.0, 0.0, 0.0])
having the possibility to say :

if you are at 0 on the midi .wchoose([1.0, 0.0, 0.0])
if you are at 32 on the midi .wchoose([0.5, 0.5, 0.0])
if you are at 64 on the midi .wchoose([0.5, 0.5, 0.5])
if you are at 96 on the midi .wchoose([0.0, 0.5, 0.5])
if you are at 127 on the midi .wchoose([0.0, 0.0, 1.0])

and everything in beetween …
just to speculate, I don’t know if they are correct rescaled like this
if you are at 45 on the midi .wchoose([0.4, 0.3, 0.2])

sorry for the misunderstanding!

I shoud try in this way if it sounds good the result

f = { arg x;[(1-(x*2)).clip(0,1),1 -((x - 0.5).abs * 2), ((x - 0.5) * 2).clip(0, 1)] };
[2,4,8].wchoose(f.(0.3).asArray.postln)

Thanks again!

1 Like

Will this work?

``````(
~weights = {
arg val = 64; // 0 .. 127
[
val.linlin(0, 63, 1, 0), // left
val.linlin(0, 127, 0, 2).fold(0, 1), // center
val.linlin(64, 127, 0, 1) // right
].normalizeSum
};

// test:
(0..127).collect{|i| ~weights.(i)}.flop.plot;
)
``````

Not exactly to your specs. I made it so that both 63 and 64 return [0, 1, 0] since the actual midpoint (63.5) is inaccessible.

1 Like