Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Guides / Randomness.schelp
blob6cb0d10cc0dac625f2fcfd19e9d70fedfc2f96f0
1 title:: Randomness
2 categories:: Random
3 summary:: Randomness in SC
4 related:: Reference/randomSeed
6 As in any computer program, there are no "truly random" number generators in SC.
7 They are pseudo-random, meaning they use very complex, but deterministic
8 algorithms to generate sequences of numbers that are long enough and complicated enough
9 to seem "random" for human beings. (i.e. the patterns are too complex for us to detect.)
11 If you start a random number generator algorithm with the same "seed" number
12 several times, you get the same sequence of random numbers.
13 (See example below, randomSeed)
15 section:: Create single random numbers
17 subsection:: Between zero and <number>
18 code::
19 5.rand          // evenly distributed.
21 1.0.linrand     // probability decreases linearly from 0 to <number>.
24 subsection:: Between -<number> and <number>
25 code::
26 5.0.rand2       // evenly distributed.
28 10.bilinrand    // probability is highest around 0,
29                 // decreases linearly toward +-<number>.
31 1.0.sum3rand    // quasi-gaussian, bell-shaped distribution.
34 subsection:: Within a given range
35 code::
36 rrand(24, 48)       // linear distribution in the given range.
38 exprand(0.01, 1)    // exponential distribution;
39                     // both numbers must have the same sign.
42 subsection:: Test them multiple times with a do loop
43 code::
44 20.do({ 5.rand.postln; });                      // evenly distributed
46 20.do({ 1.0.linrand.postln; });         // probability decreases linearly from 0 to 1.0
48 20.do({ 5.0.rand2.postln; });           // even
50 20.do({ 10.bilinrand.postln; });                // probability is highest around 0,
51                                                         // decreases linearly toward +-<number>.
53 20.do({ 1.0.sum3rand.postln; });        // quasi-gaussian, bell-shaped.
56 subsection:: Collect the results in an array
57 code::
58 Array.fill(10, { 1000.linrand }).postln;
60 // or more compact:
62 { 1.0.sum3rand }.dup(100)
64 // or:
66 ({ 1.0.sum3rand } ! 100)
69 subsection:: Seeding
70 You can seed a random generator in order to repeat
71 the same sequence of random numbers:
72 code::
74 5.do({
75         thisThread.randSeed = 4;
76         Array.fill(10, { 1000.linrand}).postln;
77 });
80 // Just to check, no seeding:
83 5.do({ Array.fill(10, { 1000.linrand }).postln; });
86 See also link::Reference/randomSeed::.
89 subsection:: Histograms
90 Demonstrate the various statistical distributions visually, with histograms:
92 note:: plot may not work in non-Mac SC3 versions.::
93 code::
94 Array.fill(500, {  1.0.rand }).plot("Sequence of 500x 1.0.rand");
96 Array.fill(500, {  1.0.linrand }).plot("Sequence of 500x 1.0.linrand");
98 Array.fill(500, {  1.0.sum3rand }).plot("Sequence of 500x 1.0.sum3rand");
101 Use a histogram to display how often each (integer)
102 occurs in a collection of random numbers, :
103 code::
105 var randomNumbers, histogram, maxValue = 500, numVals = 10000, numBins = 500;
107 randomNumbers = Array.fill(numVals, { maxValue.rand; });
108 histogram = randomNumbers.histo(numBins, 0, maxValue);
109 histogram.plot("histogram for rand 0 - " ++ maxValue);
113 A histogram for linrand:
114 code::
116 var randomNumbers, histogram, maxValue = 500.0, numVals = 10000, numBins = 500;
118 randomNumbers = Array.fill(numVals, { maxValue.linrand; });
119 histogram = randomNumbers.histo(numBins, 0, maxValue);
120 histogram.plot("histogram for linrand 0 - " ++ maxValue);
123 A histogram for bilinrand:
124 code::
126 var randomNumbers, histogram, minValue = -250, maxValue = 250, numVals = 10000, numBins = 500;
128 randomNumbers = Array.fill(numVals, { maxValue.bilinrand; });
129 histogram = randomNumbers.histo(numBins, minValue, maxValue);
130 histogram.plot("histogram for bilinrand" + minValue + "to" + maxValue);
134 A histogram for exprand:
135 code::
137 var randomNumbers, histogram, minValue = 5.0, maxValue = 500, numVals = 10000, numBins = 500;
139 randomNumbers = Array.fill(numVals, { exprand(minValue, maxValue); });
140 histogram = randomNumbers.histo(numBins, minValue, maxValue);
141 histogram.plot("histogram for exprand: " ++ minValue ++ " to " ++ maxValue);
145 And for sum3rand (cheap quasi-gaussian):
146 code::
148 var randomNumbers, histogram, minValue = -250, maxValue = 250, numVals = 10000, numBins = 500;
150 randomNumbers = Array.fill(numVals, { maxValue.sum3rand; });
151 histogram = randomNumbers.histo(numBins, minValue, maxValue);
152 histogram.plot("histogram for sum3rand " ++ minValue ++ " to " ++ maxValue);
157 subsection:: on Collections
158 All of the single-number methods also work for (Sequenceable)Collections,
159 simply by applying the given random message to each element of the collection:
160 code::
161 [ 1.0, 10, 100.0, \aSymbol ].rand.postln;               // note: Symbols are left as they are.
162 List[ 10, -3.0, \aSymbol ].sum3rand.postln;
165 subsection:: Arbitrary random distributions
167 An integral table can be used to create an arbitrary random distribution quite efficiently. The table
168 building is expensive though. The more points there are in the random table, the more accurate the
169 distribution.
170 code::
172 var randomNumbers, histogram, distribution, randomTable, randTableSize=200;
173 var minValue = -250, maxValue = 250, numVals = 10000, numBins = 500;
175 // create some random distribution with values between 0 and 1
176 distribution = Array.fill(randTableSize,
177         { arg i; (i/ randTableSize * 35).sin.max(0) * (i / randTableSize) }
180 // render a randomTable
181 randomTable = distribution.asRandomTable;
183 // get random numbers, scale them
185 randomNumbers = Array.fill(numVals, { randomTable.tableRand * (maxValue - minValue) + minValue; });
186 histogram = randomNumbers.histo(numBins, minValue, maxValue);
189 histogram.plot("this is the histogram we got");
190 distribution.plot("this was the histogram we wanted");
194 section:: Random decisions
196 code:: coin :: simulates a coin toss and results in true or false.
197 1.0 is always true, 0.0 is always false, 0.5 is 50:50 chance.
198 code::
199 20.do({ 0.5.coin.postln });
201 biased random decision can be simulated bygenerating a single value
202 and check against a threshhold:
203 code::
204 20.do({ (1.0.linrand > 0.5).postln });
205 20.do({ (exprand(0.05, 1.0) > 0.5).postln });
208 section:: Generating Collections of random numbers
209 code::
210                 // size, minVal, maxVal
211 Array.rand(7, 0.0, 1.0).postln;
213 // is short for:
215 Array.fill(7, { rrand(0.0, 1.0) }).postln;
217 code::
218                 // size, minVal, maxVal
219 List.linrand(7, 10.0, 15.0).postln;
221 // is short for:
223 List.fill(7, { 10 + 5.0.linrand }).postln;
226 code::
227 Signal.exprand(10, 0.1, 1);
229 Signal.rand2(10, 1.0);
232 section:: Random choice from Collections
234 code::choose:: : equal chance for each element.
235 code::
236 10.do({ [ 1, 2, 3 ].choose.postln });
239 Weighted choice:
241 code::wchoose(weights):: : An array of weights sets the chance for each element.
242 code::
243 10.do({ [ 1, 2, 3 ].wchoose([0.1, 0.2, 0.7]).postln });
246 section:: Randomize the order of a Collection
248 code::
249 List[ 1, 2, 3, 4, 5 ].scramble.postln;
252 section:: Generate random numbers without duplicates
253 code::
254 f = { |n=8, min=0, max=7| (min..max).scramble.keep(n) };
255 f.value(8, 0, 7)
258 section:: Randomly group a Collection
259 code::
260 curdle(probability)
262 The probability argument sets the chance that two adjacent elements will be separated.
263 code::
264 [ 1, 2, 3, 4, 5, 6, 7, 8 ].curdle(0.2).postln;  // big groups
266 [ 1, 2, 3, 4, 5, 6, 7, 8 ].curdle(0.75).postln; // small groups
269 section:: Random signal generators, i.e. UGens
270 list::
271 ## link::Classes/PinkNoise::
272 ## link::Classes/WhiteNoise::
273 ## link::Classes/GrayNoise::
274 ## link::Classes/BrownNoise::
275 ## link::Classes/ClipNoise::
276 ## link::Classes/LFNoise0::
277 ## link::Classes/LFNoise1::
278 ## link::Classes/LFNoise2::
279 ## link::Classes/LFClipNoise::
280 ## link::Classes/LFDNoise0::
281 ## link::Classes/LFDNoise1::
282 ## link::Classes/LFDNoise3::
283 ## link::Classes/LFDClipNoise::
284 ## link::Classes/Dust::
285 ## link::Classes/Dust2::
286 ## link::Classes/Crackle::
287 ## link::Classes/TWChoose::
290 Also see UGens>Generators>Stochastic in the link::Browse#UGens>Generators>Stochastic:: page.
292 subsection:: UGens that generate random numbers once, or on trigger:
294 definitionlist::
295 ## link::Classes/Rand:: || uniform distribution of float between (lo, hi), as for numbers.
296 ## link::Classes/IRand:: || uniform distribution of integer numbers.
297 ## link::Classes/TRand:: || uniform distribution of float numbers, triggered
298 ## link::Classes/TIRand:: || uniform distribution of integer numbers, triggered
299 ## link::Classes/LinRand:: || skewed distribution of float numbers, triggered
300 ## link::Classes/NRand:: || sum of n uniform distributions, approximates gaussian distr. with higher n.
301 ## link::Classes/ExpRand:: || exponential distribution
302 ## link::Classes/TExpRand:: || exponential distribution, triggered
303 ## link::Classes/CoinGate:: || statistical gate for a trigger
304 ## link::Classes/TWindex:: || triggered weighted choice between a list.
307 subsection:: Seeding
308 Like using randSeed to set the random generatorsfor each thread in sclang,
309 you can choose which of several random generators on the server to use,
310 and you can reset (seed) these random generators:
311 list::
312 ## link::Classes/RandID::
313 ## link::Classes/RandSeed::
316 subsection:: UGens that generate random numbers on demand
317 ("Demand UGens")
318 list::
319 ## link::Classes/Dwhite::
320 ## link::Classes/Dbrown::
321 ## link::Classes/Diwhite::
322 ## link::Classes/Dibrown::
323 ## link::Classes/Drand::
324 ## link::Classes/Dxrand::
327 see random patterns with analogous names
329 section:: Random Patterns
330 definitionlist::
331 ## link::Classes/Prand:: || choose randomly one from a list ( list, numRepeats)
332 ## link::Classes/Pxrand:: || choose one element from a list, no repeat of previous choice
333 ## link::Classes/Pwhite:: || within range [<hi>, <lo>], choose a random value.
334 ## link::Classes/Pbrown:: || within range [<hi>, <lo>], do a random walk with a maximum <step> to the next value.
335 ## link::Classes/Pgbrown:: || geometric brownian motion
337 ## link::Classes/Plprand::
338 ## link::Classes/Phprand::
339 ## link::Classes/Pmeanrand::
340 ## link::Classes/Pbeta::
341 ## link::Classes/Pcauchy::
342 ## link::Classes/Pgauss::
343 ## link::Classes/Ppoisson::
344 ## link::Classes/Pexprand::
346 ## link::Classes/Pwrand:: || choose from a list, probabilities by weights
347 code::
348 Pwrand([ 1, 2, 3 ], [0.1, 0.3, 0.6], 20);
351 ## link::Classes/Pshuf:: || scramble the list, then repeat that order <repeats> times.
353 ## link::Classes/Pwalk:: || code::Pwalk( (0 .. 10), Prand([ -2,-1, 1, 2], inf));:: random walk.
355 ## link::Classes/Pfsm:: || random finite state machine pattern, see its help file. see also MarkovSet in MathLib quark
357 ## link::Classes/Pseed:: || sets the random seed for that stream.
360 some basic examples
361 code::
363 Pbind(\note, Prand([ 0, 2, 4 ], inf),
364         \dur, 0.2
365 ).play;
369 Pbind(
370         \note, Pxrand([ 0, 2, 4 ], inf),
371         \dur, 0.2
372 ).play;
376 Pbind(
377         \note, Pwrand([ 0, 2, 4 ], [0.1, 0.3, 0.6], inf),
378         \dur, 0.2
379 ).play;
383 Pbind(
384         \midinote, Pwhite(48, 72, inf),
385         \dur, 0.2
386 ).play;
390 Pbind(
391         \midinote, Pbrown(48, 72, 5, inf),
392         \dur, 0.2
393 ).play;
397 Pbind(
398         \midinote, Pgbrown(48, 72, 0.5, inf).round,
399         \dur, 0.2
400 ).play;