//  [python]
def newton_method_nu_square_in_log_space(self,
                                             doc_lambda,
                                             doc_nu_square,
                                             doc_zeta_factor,
                                             total_word_count,
                                             newton_method_iteration=10,
                                             newton_method_decay_factor=0.9,
                                             newton_method_step_size=0.1,
                                             eigen_value_tolerance=1e-9
                                             ):
        assert doc_zeta_factor.shape == (self._number_of_topics, self._number_of_topics);

        doc_log_nu_square = numpy.log(doc_nu_square);
        exp_doc_log_nu_square = numpy.exp(doc_log_nu_square);

        newton_method_power_index = 0;
        for newton_method_iteration_index in range(newton_method_iteration):
            log_exp_over_doc_zeta_combine = numpy.max(
                doc_zeta_factor - doc_lambda[:, numpy.newaxis] - 0.5 * exp_doc_log_nu_square[:,
                                                                       numpy.newaxis] - doc_log_nu_square[:,
                                                                                        numpy.newaxis], axis=1) + numpy.log(numpy.sum(
                numpy.exp(doc_zeta_factor - doc_lambda[:, numpy.newaxis] - 0.5 * exp_doc_log_nu_square[:,
                                                                       numpy.newaxis] - doc_log_nu_square[:,
                                                                                        numpy.newaxis] - log_exp_over_doc_zeta_combine[:, numpy.newaxis]), axis=1))
            exp_over_doc_zeta_combine = numpy.exp(-log_exp_over_doc_zeta_combine);

            if self._diagonal_covariance_matrix:
                first_derivative_log_nu_square = -0.5 / self._alpha_sigma * exp_doc_log_nu_square;
            else:
                first_derivative_log_nu_square = -0.5 * numpy.diag(self._alpha_sigma_inv) * exp_doc_log_nu_square;
            first_derivative_log_nu_square += 0.5
            first_derivative_log_nu_square += -0.5 * total_word_count * exp_over_doc_zeta_combine

            if self._diagonal_covariance_matrix:
                second_derivative_log_nu_square = -0.5 / self._alpha_sigma * exp_doc_log_nu_square;
            else:
                second_derivative_log_nu_square = -0.5 * numpy.diag(self._alpha_sigma_inv) * exp_doc_log_nu_square;
            second_derivative_log_nu_square += -0.5 * total_word_count * exp_over_doc_zeta_combine * (
                        1 + 0.5 * exp_doc_log_nu_square);

            step_change = first_derivative_log_nu_square / second_derivative_log_nu_square;

            # step_change *= newton_method_step_size;
            step_change /= numpy.sqrt(numpy.sum(step_change ** 2));

            # if numpy.any(numpy.isnan(step_change)) or numpy.any(numpy.isinf(step_change)):
            # break;

            step_alpha = numpy.power(newton_method_decay_factor, newton_method_power_index);

            doc_log_nu_square -= step_alpha * step_change;
            exp_doc_log_nu_square = numpy.exp(doc_log_nu_square);

            # if numpy.all(numpy.abs(step_change) <= local_parameter_converge_threshold):
            # break;

            # print "update nu to %s" % (doc_nu_square)

        doc_nu_square = numpy.exp(doc_log_nu_square);

        return doc_nu_square;