def fit_with_bfgs(self):
        # If W_max is specified, set this as a bound
        if self.W_max is not None:
            bnds = [(1e-16, None)] + [(1e-16, self.W_max)] * (self.K * self.B)
        else:
            bnds = [(1e-16, None)] * (1 + self.K * self.B)

        def objective(x, k):
            self.weights[k,:] = x
            return np.nan_to_num(-self.log_posterior(ks=np.array([k])))

        def gradient(x, k):
            self.weights[k,:] = x
            return np.nan_to_num(-self.compute_gradient(k))

        itr = [0]
        def callback(x):
            if itr[0] % 10 == 0:
                print "Iteration: %03d\t LP: %.1f" % (itr[0], self.log_posterior())
            itr[0] = itr[0] + 1

        for k in xrange(self.K):
            print "Optimizing process ", k
            itr[0] = 0
            x0 = self.weights[k,:]
            res = minimize(objective,           # Objective function
                           x0,                  # Initial value
                           jac=gradient,        # Gradient of the objective
                           args=(k,),           # Arguments to the objective and gradient fns
                           bounds=bnds,         # Bounds on x
                           callback=callback)
            self.weights[k,:] = res.x
Fit the model with BFGS
dataset/ETHPy150Open slinderman/pyhawkes/pyhawkes/models.py/DiscreteTimeStandardHawkesModel.fit_with_bfgs