# Buggy code
def bound(self, corpus, gamma=None, subsample_ratio=1.0):
    """
    Estimate the variational bound of documents from `corpus`:
    E_q[log p(corpus)] - E_q[log q(corpus)]

    `gamma` are the variational parameters on topic weights for each `corpus`
    document (=2d matrix=what comes out of `inference()`).
    If not supplied, will be inferred from the model.

    """
    score = 0.0
    _lambda = self.state.get_lambda()
    Elogbeta = dirichlet_expectation(_lambda)

    for d, doc in enumerate(
        corpus
    ):  # stream the input doc-by-doc, in case it's too large to fit in RAM
        if d % self.chunksize == 0:
            logger.debug("bound: at document #%i", d)
        if gamma is None:
            gammad, _ = self.inference([doc])
        else:
            gammad = gamma[d]
        Elogthetad = dirichlet_expectation(gammad)

        # E[log p(doc | theta, beta)]
        score += np.sum(
            cnt * logsumexp(Elogthetad + Elogbeta[:, id]) for id, cnt in doc
        )

        # E[log p(theta | alpha) - log q(theta | gamma)]; assumes alpha is a vector
        score += np.sum((self.alpha - gammad) * Elogthetad)
        score += np.sum(gammaln(gammad) - gammaln(self.alpha))
        score += gammaln(np.sum(self.alpha)) - gammaln(np.sum(gammad))

    # Compensate likelihood for when `corpus` above is only a sample of the whole corpus. This ensures
    # that the likelihood is always rougly on the same scale.
    score *= subsample_ratio

    # E[log p(beta | eta) - log q (beta | lambda)]; assumes eta is a scalar
    score += np.sum((self.eta - _lambda) * Elogbeta)
    score += np.sum(gammaln(_lambda) - gammaln(self.eta))

    if np.ndim(self.eta) == 0:
        sum_eta = self.eta * self.num_terms
    else:
        sum_eta = np.sum(self.eta)

    score += np.sum(gammaln(sum_eta) - gammaln(np.sum(_lambda, 1)))

    return score


# Traceback (ValueError)
In [16]: model = models.LdaModel(corpus, id2word=dictionary, num_topics=2, distributed=True)
2016-10-03 09:21:04,056 : INFO : using symmetric alpha at 0.5
2016-10-03 09:21:04,056 : INFO : using symmetric eta at 0.5
2016-10-03 09:21:04,057 : DEBUG : looking for dispatcher at PYRO:gensim.lda_dispatcher@127.0.0.1:41212
2016-10-03 09:21:04,089 : INFO : using distributed version with 3 workers
2016-10-03 09:21:04,090 : INFO : running online LDA training, 2 topics, 1 passes over the supplied corpus of 9 documents, updating model once every 9 documents, evaluating perplexity every 9 documents, iterating 50x with a convergence threshold of 0.001000
2016-10-03 09:21:04,090 : WARNING : too few updates, training might not converge; consider increasing the number of passes or iterations to improve accuracy
2016-10-03 09:21:04,090 : INFO : initializing 3 workers
2016-10-03 09:21:04,097 : DEBUG : bound: at document #0
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-16-46e2552e21a7> in <module>()
----> 1 model = models.LdaModel(corpus, id2word=dictionary, num_topics=2, distributed=True)

/home/lev/Dropbox/raretech/os/release/gensim/gensim/models/ldamodel.py in __init__(self, corpus, num_topics, id2word, distributed, chunksize, passes, update_every, alpha, eta, decay, offset, eval_every, iterations, gamma_threshold, minimum_probability, random_state, ns_conf)
344         if corpus is not None:
345             use_numpy = self.dispatcher is not None
--> 346             self.update(corpus, chunks_as_numpy=use_numpy)
347
348     def init_dir_prior(self, prior, name):

/home/lev/Dropbox/raretech/os/release/gensim/gensim/models/ldamodel.py in update(self, corpus, chunksize, decay, offset, passes, update_every, eval_every, iterations, gamma_threshold, chunks_as_numpy)
648
649                 if eval_every and ((reallen == lencorpus) or ((chunk_no + 1) % (eval_every * self.numworkers) == 0)):
--> 650                     self.log_perplexity(chunk, total_docs=lencorpus)
651
652                 if self.dispatcher:

/home/lev/Dropbox/raretech/os/release/gensim/gensim/models/ldamodel.py in log_perplexity(self, chunk, total_docs)
539         corpus_words = sum(cnt for document in chunk for _, cnt in document)
540         subsample_ratio = 1.0 * total_docs / len(chunk)
--> 541         perwordbound = self.bound(chunk, subsample_ratio=subsample_ratio) / (subsample_ratio * corpus_words)
542         logger.info("%.3f per-word bound, %.1f perplexity estimate based on a held-out corpus of %i documents with %i words" %
543                     (perwordbound, numpy.exp2(-perwordbound), len(chunk), corpus_words))

/home/lev/Dropbox/raretech/os/release/gensim/gensim/models/ldamodel.py in bound(self, corpus, gamma, subsample_ratio)
740                 logger.debug("bound: at document #%i", d)
741             if gamma is None:
--> 742                 gammad, _ = self.inference([doc])
743             else:
744                 gammad = gamma[d]

/home/lev/Dropbox/raretech/os/release/gensim/gensim/models/ldamodel.py in inference(self, chunk, collect_sstats)
438         # to Blei's original LDA-C code, cool!).
439         for d, doc in enumerate(chunk):
--> 440             if doc and not isinstance(doc[0][0], six.integer_types):
441                 # make sure the term IDs are ints, otherwise numpy will get upset
442                 ids = [int(id) for id, _ in doc]

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

# Fixed code
def bound(self, corpus, gamma=None, subsample_ratio=1.0):
    """
    Estimate the variational bound of documents from `corpus`:
    E_q[log p(corpus)] - E_q[log q(corpus)]

    `gamma` are the variational parameters on topic weights for each `corpus`
    document (=2d matrix=what comes out of `inference()`).
    If not supplied, will be inferred from the model.

    """
    score = 0.0
    _lambda = self.state.get_lambda()
    Elogbeta = dirichlet_expectation(_lambda)

    for d, doc in enumerate(
        corpus
    ):  # stream the input doc-by-doc, in case it's too large to fit in RAM
        if d % self.chunksize == 0:
            logger.debug("bound: at document #%i", d)
        if gamma is None:
            gammad, _ = self.inference([doc])
        else:
            gammad = gamma[d]
        Elogthetad = dirichlet_expectation(gammad)

        # E[log p(doc | theta, beta)]
        score += np.sum(
            cnt * logsumexp(Elogthetad + Elogbeta[:, int(id)]) for id, cnt in doc
        )

        # E[log p(theta | alpha) - log q(theta | gamma)]; assumes alpha is a vector
        score += np.sum((self.alpha - gammad) * Elogthetad)
        score += np.sum(gammaln(gammad) - gammaln(self.alpha))
        score += gammaln(np.sum(self.alpha)) - gammaln(np.sum(gammad))

    # Compensate likelihood for when `corpus` above is only a sample of the whole corpus. This ensures
    # that the likelihood is always rougly on the same scale.
    score *= subsample_ratio

    # E[log p(beta | eta) - log q (beta | lambda)]; assumes eta is a scalar
    score += np.sum((self.eta - _lambda) * Elogbeta)
    score += np.sum(gammaln(_lambda) - gammaln(self.eta))

    if np.ndim(self.eta) == 0:
        sum_eta = self.eta * self.num_terms
    else:
        sum_eta = np.sum(self.eta)

    score += np.sum(gammaln(sum_eta) - gammaln(np.sum(_lambda, 1)))

    return score