function _pickRandom (possibles, { number, weights, elementWise = true }) {
    const single = (typeof number === 'undefined')
    if (single) {
      number = 1
    }

    const createMatrix = isMatrix(possibles)
      ? possibles.create
      : isMatrix(weights)
        ? weights.create
        : null

    possibles = possibles.valueOf() // get Array
    if (weights) {
      weights = weights.valueOf() // get Array
    }

    if (elementWise === true) {
      possibles = flatten(possibles)
      weights = flatten(weights)
    }

    let totalWeights = 0

    if (typeof weights !== 'undefined') {
      if (weights.length !== possibles.length) {
        throw new Error('Weights must have the same length as possibles')
      }

      for (let i = 0, len = weights.length; i < len; i++) {
        if (!isNumber(weights[i]) || weights[i] < 0) {
          throw new Error('Weights must be an array of positive numbers')
        }

        totalWeights += weights[i]
      }
    }

    const length = possibles.length

    const result = []
    let pick

    while (result.length < number) {
      if (typeof weights === 'undefined') {
        pick = possibles[Math.floor(rng() * length)]
      } else {
        let randKey = rng() * totalWeights

        for (let i = 0, len = possibles.length; i < len; i++) {
          randKey -= weights[i]

          if (randKey < 0) {
            pick = possibles[i]
            break
          }
        }
      }

      result.push(pick)
    }

    return single
      ? result[0]
      : createMatrix
        ? createMatrix(result)
        : result
  }
@param {Array | Matrix} possibles
@param {{
  number?: number,
  weights?: Array | Matrix,
  elementWise: boolean
}} options
@returns {number | Array}
@private