def sgd_step(self, prev_velocity, learning_rate, momentum):
        if prev_velocity is None:
            prev_velocity = np.zeros((self.K, 1+self.K*self.B))

        # Compute this gradient row by row
        grad = np.zeros((self.K, 1+self.K*self.B))
        velocity = np.zeros((self.K, 1+self.K*self.B))

        # Get a minibatch
        mb = np.random.choice(len(self.data_list))
        T = self.data_list[mb][0].shape[0]

        # Compute gradient and take a step for each process
        for k in xrange(self.K):
            d_W_d_log_W = self._d_W_d_logW(k)
            grad[k,:] = self.compute_gradient(k, indices=[mb]).dot(d_W_d_log_W) / T
            velocity[k,:] = momentum * prev_velocity[k,:] + learning_rate * grad[k,:]

            # Gradient steps are taken in log weight space
            log_weightsk = np.log(self.weights[k,:]) + velocity[k,:]

            # The true weights are stored
            self.weights[k,:] = np.exp(log_weightsk)

        # Compute the current objective
        ll = self.log_likelihood()

        return self.weights, ll, velocity
Take a step of the stochastic gradient descent algorithm
dataset/ETHPy150Open slinderman/pyhawkes/pyhawkes/models.py/DiscreteTimeStandardHawkesModel.sgd_step