FunctionProbabilityDistributionSampling
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5

// @description Methods for probability distribution sampling selection.
library(title="FunctionProbabilityDistributionSampling")

import RicardoSantos/ArrayOperationsFloat/1 as aof
import RicardoSantos/DebugConsole/2 as console
[__T, __C] = console.init(20)

// @function Computes  a random selected index from a probability distribution.
// @param probabilities float array, probabilities of sample.
// @returns int.
export sample (float[] probabilities) => //{
	int _size_p = array.size(probabilities)
	float _sum_p = array.sum(probabilities)
	//
	// errors
	switch
	    (_size_p < 1) => runtime.error('FunctionProbabilityDistributionSampling -> sample(): "probabilities" has the wrong size.')
	    (_sum_p <= 0) => runtime.error(str.format('FunctionProbabilityDistributionSampling -> sample(): "probabilities" must sum to a value greater than 0, actual: {0}.', _sum_p))
	//
	float[] _normalized = aof.divide(probabilities, array.from(_sum_p))
	float _sample = math.random()
	float _total = 0.0
	int _idx = na
	for _i = 0 to _size_p - 1
	    _total += array.get(_normalized, _i)
	    if _sample < _total
	        _idx := _i
	        break
	_idx
//{ usage:
if barstate.isfirst
    var int[] counts = array.new_int(10, 0)
    for _i = 0 to 10000
        int _idx = sample(array.from(0.02, 0.03, 0.05, 0.1, 0.25, 0.35, 0.25, 0.05, 0.03, 0.02))
        array.set(counts, _idx, array.get(counts, _idx) + 1)
    console.queue_one(__C, str.tostring(counts))
    console.queue_one(__C, str.tostring(aof.multiply(aof.divide(counts, array.from(10000)), array.from(100)), format.percent))
//{ remarks:
//      https://gist.github.com/brannondorsey/dc4cfe00d6b124aebd3277159dcbdb14
//}}}




console.update(__T, __C)