code: def categorical(p, upper=None, rng=None, size=()):
      """Draws i with probability p[i]"""
      if len(p) == 1 and isinstance(p[0], np.ndarray):
          p = p[0]
      p = np.asarray(p)
  
      if size == ():
          size = (1,)
      elif isinstance(size, (int, np.number)):
          size = (size,)
      else:
          size = tuple(size)
  
      if size == (0,):
          return np.asarray([])
      assert len(size)
  
      if p.ndim == 0:
          raise NotImplementedError()
      elif p.ndim == 1:
          n_draws = int(np.prod(size))
          sample = rng.multinomial(n=1, pvals=p, size=int(n_draws))
          assert sample.shape == size + (len(p),)
          rval = np.dot(sample, np.arange(len(p)))
          rval.shape = size
          return rval
      elif p.ndim == 2:
          n_draws_, n_choices = p.shape
          (n_draws,) = size
          assert n_draws == n_draws_
          rval = [
              np.where(rng.multinomial(pvals=p[ii], n=1))[0][0]
              for ii in range(n_draws)
          ]
          rval = np.asarray(rval)
          rval.shape = size
          return rval
      else:
          raise NotImplementedError()
  
imports: from __future__ import print_function
  from __future__ import division
  from builtins import range
  from past.utils import old_div
  import sys
  import numpy
  from .base import scope, as_apply, dfs, rec_eval, clone
label_desc: Use image node_id 13 for calling a global function with example usage: categorical(p, upper, rng, size) and returns: np, rval, rval