def search(self, input_values, eol_symbol, max_length,
               ignore_first_eol=False, as_arrays=False,
               char_discount=0, round_to_inf=1e9,
               stop_on='patience',
               validate_solution_function=None):
        if not self.compiled:
            self.compile()

        contexts = self.compute_contexts(input_values)
        large_contexts = OrderedDict(contexts)
        states = self.compute_initial_states(contexts)

        # This array will store all generated outputs, including those from
        # previous step and those from already finished sequences.
        all_outputs = states['outputs'][None, :]
        all_costs = numpy.zeros_like(all_outputs, dtype=config.floatX)

        done = []
        min_cost = 1000

        for i in range(max_length):
            if len(states.values()[0].flatten()) == 0:
                break

            if stop_on == 'patience':
                done = sorted(done, key=lambda x: x[1][-1] - char_discount * len(x[1]))
                done = done[:self.beam_size]
                if done:
                    current_best_cost = done[0][1][-1] - char_discount * len(done[0][1])
                    if current_best_cost < min_cost:
                        min_cost = current_best_cost
                        patience = 30
                    else:
                        patience -= 1
                        if patience == 0:
                            break
            elif stop_on == 'optimistic_future_cost':
                # stop only when we have at least self.beam_size sequences,
                # that are all cheaper than we can possibly obtain by extending
                # other ones
                if (len(done) >= self.beam_size):
                    optimistic_future_cost = (all_costs[-1, :].min() -
                                              char_discount * max_length)
                    last_in_done = done[self.beam_size - 1][1]
                    # note: done is sorted by the cost with char discount subtracted
                    last_in_done_cost = (last_in_done[-1] -
                                         char_discount * len(last_in_done))
                    if last_in_done_cost < optimistic_future_cost:
                        break
            else:
                raise ValueError('Unknown stopping criterion {}'.format(stop_on))

            # We carefully hack values of the `logprobs` array to ensure
            # that all finished sequences are continued with `eos_symbol`.
            if large_contexts.values()[0].shape[1] != states.values()[0].shape[0]:
                for name, ctx in contexts.items():
                    large_contexts[name] = numpy.take(ctx, [0]*states.values()[0].shape[0], axis=1)
            logprobs = self.compute_logprobs(large_contexts, states)
            assert numpy.isfinite(logprobs).all()
            next_costs = (all_costs[-1, :, None] + logprobs)

            (indexes, outputs), chosen_costs = self._smallest(
                next_costs, self.beam_size)

            # Rearrange everything
            for name in states:
                states[name] = numpy.take(states[name], indexes, axis=0)
            all_outputs = numpy.take(all_outputs, indexes, axis=1)
            all_costs = numpy.take(all_costs, indexes, axis=1)

            # Record chosen output and compute new states
            if large_contexts.values()[0].shape[1] != states.values()[0].shape[0]:
                for name, ctx in contexts.items():
                    large_contexts[name] = numpy.take(ctx, [0]*states.values()[0].shape[0], axis=1)
            states = self.compute_next_states(large_contexts, states, outputs)

            all_outputs = numpy.vstack([all_outputs, outputs[None, :]])
            all_costs = numpy.vstack([all_costs, chosen_costs[None, :]])

            mask = outputs != eol_symbol
            if ignore_first_eol and i == 0:
                mask[:] = 1

            for idx in numpy.where(
                    (all_outputs[-1] == eol_symbol) &
                    (all_costs[-1] - all_costs[-2] < round_to_inf))[0]:
                if (validate_solution_function is None or
                        validate_solution_function(input_values,
                                                   all_outputs[:, idx])):
                    done.append((all_outputs[:, idx], all_costs[:, idx]))

            unfinished = numpy.where(mask == 1)[0]
            for name in states:
                states[name] = numpy.take(states[name], unfinished, axis=0)
            all_outputs = numpy.take(all_outputs, unfinished, axis=1)
            all_costs = numpy.take(all_costs, unfinished, axis=1)

        if not done:
            raise CandidateNotFoundError()

        done = sorted(done, key=lambda x: x[1][-1] - char_discount * len(x[1]))

        max_len = max((seq[0].shape[0] for seq in done))
        all_outputs = numpy.zeros((max_len, len(done)))
        all_masks = numpy.zeros((max_len, len(done)))
        all_costs = numpy.zeros((max_len, len(done)))
        for i, (seq, cost) in enumerate(done):
            all_outputs[:len(seq), i] = seq
            all_masks[:len(seq), i] = 1
            all_costs[:len(cost), i] = cost
            all_costs[len(cost):, i] = cost[-1]
        all_outputs = all_outputs[1:]
        all_masks = all_masks[1:]
        all_costs = all_costs[1:] - all_costs[:-1]
        result = all_outputs, all_masks, all_costs
        if as_arrays:
            return result
        return self.result_to_lists(result)
Performs beam search.
dataset/ETHPy150Open rizar/attention-lvcsr/libs/blocks/blocks/search.py/BeamSearch.search