tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

deRandom.js (8660B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 /**
     22 * This class allows one to create a random integer, floating point number or boolean (TODO, deRandom.choose random items from a list and deRandom.shuffle an array)
     23 */
     24 'use strict';
     25 goog.provide('framework.delibs.debase.deRandom');
     26 
     27 goog.scope(function() {
     28 
     29 var deRandom = framework.delibs.debase.deRandom;
     30 
     31 /**
     32 * Array of pseudo random numbers based on seed
     33 * @constructor
     34 * @struct
     35 */
     36 deRandom.deRandom = function() {
     37    /** @type {number} */ this.x = 0;
     38    /** @type {number} */ this.y = 0;
     39    /** @type {number} */ this.z = 0;
     40    /** @type {number} */ this.w = 0;
     41 };
     42 
     43 /**
     44 * deRandom.Random number generator init
     45 * @param {deRandom.deRandom} rnd Array to store random numbers
     46 * @param {number} seed Number for seed
     47 */
     48 deRandom.deRandom_init = function(rnd, seed) {
     49    rnd.x = (-seed ^ 123456789);
     50    rnd.y = (362436069 * seed);
     51    rnd.z = (521288629 ^ (seed >> 7));
     52    rnd.w = (88675123 ^ (seed << 3));
     53 };
     54 
     55 /**
     56 * Function to get random int
     57 * @param {deRandom.deRandom} rnd Initialised array of random numbers
     58 * @param {Array<number>=} opts Min and max for range
     59 * @return {number} deRandom.Random int
     60 */
     61 deRandom.deRandom_getInt = function(rnd, opts) {
     62    if (opts != undefined && opts[0] != undefined && opts[1] != undefined) {
     63        if (opts[0] == 0x80000000 && opts[1] == 0x7fffffff) {
     64            return deRandom.deRandom_getInt(rnd);
     65        } else {
     66            return opts[0] + (deRandom.deRandom_getInt(rnd) % (opts[1] - opts[0] + 1));
     67        }
     68    }
     69    var w = rnd.w;
     70    var t;
     71 
     72    t = rnd.x ^ (rnd.x << 11);
     73    rnd.x = rnd.y;
     74    rnd.y = rnd.z;
     75    rnd.z = w;
     76    rnd.w = w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
     77    return w;
     78 };
     79 
     80 /**
     81 * Function to get random float
     82 * @param {deRandom.deRandom} rnd Initialised array of random numbers
     83 * @param {Array<number>=} opts Min and max for range
     84 * @return {number} deRandom.Random float
     85 */
     86 deRandom.deRandom_getFloat = function(rnd, opts) {
     87    if (opts != undefined && opts[0] != undefined && opts[1] != undefined) {
     88        if (opts[0] <= opts[1]) {
     89            return opts[0] + (opts[1] - opts[0]) * deRandom.deRandom_getFloat(rnd);
     90        }
     91    } else {
     92        return (deRandom.deRandom_getInt(rnd) & 0xFFFFFFF) / (0xFFFFFFF + 1);
     93    }
     94    throw new Error('Invalid arguments');
     95 };
     96 
     97 /**
     98 * Function to get random boolean
     99 * @param {deRandom.deRandom} rnd Initialised array of random numbers
    100 * @return {boolean} deRandom.Random boolean
    101 */
    102 deRandom.deRandom_getBool = function(rnd) {
    103    var val;
    104    val = deRandom.deRandom_getInt(rnd);
    105    return ((val & 0xFFFFFF) < 0x800000);
    106 };
    107 
    108 /**
    109 * Function to get a common base seed
    110 * @return {number} constant
    111 */
    112 deRandom.getBaseSeed = function() {
    113    return 42;
    114 };
    115 
    116 /**
    117 * TODO Function to deRandom.choose random items from a list
    118 * @template T
    119 * @param {deRandom.deRandom} rnd Initialised array of random numbers
    120 * @param {Array<T>} elements Array segment already defined
    121 * @param {Array<T>=} resultOut Array where to store the elements in. If undefined, default to array of (num) elements.
    122 * @param {number=} num Number of items to store in resultOut. If undefined, default to 1.
    123 * @return {Array<T>} Even though result is stored in resultOut, return it here as well.
    124 */
    125 deRandom.choose = function(rnd, elements, resultOut, num) {
    126    var items = num || 1;
    127    var temp = elements.slice();
    128    if (!resultOut)
    129        resultOut = [];
    130 
    131    while (items-- > 0) {
    132        var index = deRandom.deRandom_getInt(rnd, [0, temp.length - 1]);
    133        resultOut.push(temp[index]);
    134        temp.splice(index, 1);
    135    }
    136    return resultOut;
    137 };
    138 
    139 /**
    140 * TODO Function to deRandom.choose weighted random items from a list
    141 * @param {deRandom.deRandom} rnd Initialised randomizer
    142 * @param {Array<number>} array Array to choose items from
    143 * @param {Array<number>} weights Weights array
    144 * @return {number} Result output
    145 */
    146 deRandom.chooseWeighted = function(rnd, array, weights) {
    147    // Compute weight sum
    148    /** @type {number} */ var weightSum = 0.0;
    149    /** @type {number} */ var ndx;
    150    for (ndx = 0; ndx < array.length; ndx++)
    151        weightSum += weights[ndx];
    152 
    153    // Random point in 0..weightSum
    154    /** @type {number} */ var p = deRandom.deRandom_getFloat(rnd, [0.0, weightSum]);
    155 
    156    // Find item in range
    157    /** @type {number} */ var lastNonZero = array.length;
    158    /** @type {number} */ var curWeight = 0.0;
    159    for (ndx = 0; ndx != array.length; ndx++) {
    160        /** @type {number} */ var w = weights[ndx];
    161 
    162        curWeight += w;
    163 
    164        if (p < curWeight)
    165            return array[ndx];
    166        else if (w > 0.0)
    167            lastNonZero = ndx;
    168    }
    169 
    170    assertMsgOptions(lastNonZero != array.length, 'Index went out of bounds', false, true);
    171    return array[lastNonZero];
    172 };
    173 
    174 /**
    175 * TODO Function to deRandom.shuffle an array
    176 * @param {deRandom.deRandom} rnd Initialised array of random numbers
    177 * @param {Array} elements Array to deRandom.shuffle
    178 * @return {Array} Shuffled array
    179 */
    180 deRandom.shuffle = function(rnd, elements) {
    181    var index = elements.length;
    182 
    183    while (index > 0) {
    184        var random = deRandom.deRandom_getInt(rnd, [0, index - 1]);
    185        index -= 1;
    186        var elem = elements[index];
    187        elements[index] = elements[random];
    188        elements[random] = elem;
    189    }
    190    return elements;
    191 };
    192 
    193 /**
    194 * This function is used to create the deRandom.Random object and
    195 * initialise the random number with a seed.
    196 * It contains functions for generating random numbers in a variety of formats
    197 * @constructor
    198 * @param {number} seed Number to use as a seed
    199 */
    200 deRandom.Random = function(seed) {
    201    /**
    202     * Instance of array of pseudo random numbers based on seeds
    203    */
    204    this.m_rnd = new deRandom.deRandom();
    205 
    206    //initialise the random numbers based on seed
    207    deRandom.deRandom_init(this.m_rnd, seed);
    208 };
    209 
    210 /**
    211 * Function to get random boolean
    212 * @return {boolean} deRandom.Random boolean
    213 */
    214 deRandom.Random.prototype.getBool = function() { return deRandom.deRandom_getBool(this.m_rnd) == true; };
    215 /**
    216 * Function to get random float
    217 * @param {number=} min Min for range
    218 * @param {number=} max Max for range
    219 * @return {number} deRandom.Random float
    220 */
    221 deRandom.Random.prototype.getFloat = function(min, max) { return deRandom.deRandom_getFloat(this.m_rnd, [min, max]) };
    222 /**
    223 * Function to get random int
    224 * @param {number=} min Min for range
    225 * @param {number=} max Max for range
    226 * @return {number} deRandom.Random int
    227 */
    228 deRandom.Random.prototype.getInt = function(min, max) {return deRandom.deRandom_getInt(this.m_rnd, [min, max])};
    229 /**
    230 * TODO Function to deRandom.choose random items from a list
    231 * @template T
    232 * @param {Array<T>} elements Array segment already defined
    233 * @param {Array<T>=} resultOut Array where to store the elements in. If undefined, default to array of (num) elements.
    234 * @param {number=} num Number of items to store in resultOut. If undefined, default to 1.
    235 * @return {Array<T>} Even though result is stored in resultOut, return it here as well.
    236 */
    237 deRandom.Random.prototype.choose = function(elements, resultOut, num) {return deRandom.choose(this.m_rnd, elements, resultOut, num)};
    238 /**
    239 * choose weighted random items from a list
    240 * @param {Array<number>} array Array to choose items from
    241 * @param {Array<number>} weights Weights array
    242 * @return {number} Result output
    243 */
    244 deRandom.Random.prototype.chooseWeighted = function(array, weights) {return deRandom.chooseWeighted(this.m_rnd, array, weights)};
    245 /**
    246 * TODO Function to deRandom.shuffle an array
    247 * @param {Array} elements Array to deRandom.shuffle
    248 * @return {Array} Shuffled array
    249 */
    250 deRandom.Random.prototype.shuffle = function(elements) {return deRandom.shuffle(this.m_rnd, elements)};
    251 
    252 /**
    253 * Function to get a common base seed
    254 * @return {number} constant
    255 */
    256 deRandom.Random.prototype.getBaseSeed = function() {
    257    return deRandom.getBaseSeed();
    258 };
    259 
    260 });