def fit(self, X, y, instances):
    test_instances = instances['test']
    validation_instances = instances['validation']
    train_instances = instances['train']
    time_ = 0
    self.model_time = 0
    n_train = X.shape[0]
    if self.validation:
        validation_list = []
    logging.info('training started')
    A_torch = torch.from_numpy(self.A).float()
    Q_torch = (self.gamma * torch.eye(A_torch.shape[1]))
    X_torch = torch.from_numpy(X).float()
    y_torch = torch.from_numpy(y).float()
    G_torch = ((- 1) * torch.eye(A_torch.shape[1]))
    h_torch = torch.zeros(A_torch.shape[1])
    for e in range(self.epochs):
        for i in range(self.num_instance):
            start_time = time.time()
            self.optimizer.zero_grad()
            (source, dest) = train_instances[i]
            b_torch = torch.zeros(len(self.A))
            b_torch[source] = 1
            b_torch[dest] = (- 1)
            model_params_quad = make_gurobi_model(G_torch.detach().numpy(), h_torch.detach().numpy(), A_torch.detach().numpy(), b_torch.detach().numpy(), Q_torch.detach().numpy())
            c_pred = self.net(X_torch)
            if any(torch.isnan(torch.flatten(c_pred)).tolist()):
                logging.info('**Alert** nan in param  c_pred ')
            if any(torch.isinf(torch.flatten(c_pred)).tolist()):
                logging.info('**Alert** inf in param  c_pred ')
            logging.info('shapes c {} A {} b {} G {} h {} Q {}'.format(c_pred.shape, A_torch.shape, b_torch.shape, G_torch.shape, h_torch.shape, Q_torch.shape))
            x = QPFunction(verbose=False, solver=QPSolvers.GUROBI, model_params=model_params_quad)(Q_torch.expand(1, *Q_torch.shape), c_pred.squeeze(), G_torch.expand(1, *G_torch.shape), h_torch.expand(1, *h_torch.shape), A_torch.expand(1, *A_torch.shape), b_torch.expand(1, *b_torch.shape))
            c_pred.retain_grad()
            loss = (y_torch * x).mean()
            loss.backward()
            c_grad = copy.deepcopy(c_pred.grad)
            if any(torch.isnan(torch.flatten(c_grad)).tolist()):
                logging.info('**Alert** nan in param  c_grad ')
            self.optimizer.step()
            end_time = time.time()
            time_ += (end_time - start_time)
            if self.validation:
                if (((i + 1) % 20) == 0):
                    validation_list.append(validation_module(self.net, self.A, X, y, train_instances, validation_instances, test_instances, time_, e, i))
        print('Epoch {} Loss:{} Time: {:%Y-%m-%d %H:%M:%S}'.format((e + 1), loss.sum().item(), datetime.datetime.now()))
    if self.validation:
        dd = defaultdict(list)
        for d in validation_list:
            for (key, value) in d.items():
                dd[key].append(value)
        df = pd.DataFrame.from_dict(dd)
        logging.info(('Completion Time %s \n' % str(datetime.datetime.now())))
        return df
def fit(self, X, y, instances):
    test_instances = instances['test']
    validation_instances = instances['validation']
    train_instances = instances['train']
    time_ = 0
    self.model_time = 0
    n_train = X.shape[0]
    if self.validation:
        validation_list = []
    logging.info('training started')
    A_torch = torch.from_numpy(self.A).float()
    Q_torch = (self.gamma * torch.eye(A_torch.shape[1]))
    X_torch = torch.from_numpy(X).float()
    y_torch = torch.from_numpy(y).float()
    G_torch = ((- 1) * torch.eye(A_torch.shape[1]))
    h_torch = torch.zeros(A_torch.shape[1])
    for e in range(self.epochs):
        for i in range(self.num_instance):
            start_time = time.time()
            self.optimizer.zero_grad()
            (source, dest) = train_instances[i]
            b_torch = torch.zeros(len(self.A))
            b_torch[source] = 1
            b_torch[dest] = (- 1)
            model_params_quad = make_gurobi_model(G_torch.detach().numpy(), h_torch.detach().numpy(), A_torch.detach().numpy(), b_torch.detach().numpy(), Q_torch.detach().numpy())
            c_pred = self.net(X_torch)
            if any(torch.isnan(torch.flatten(c_pred)).tolist()):
                logging.info('**Alert** nan in param  c_pred ')
            if any(torch.isinf(torch.flatten(c_pred)).tolist()):
                logging.info('**Alert** inf in param  c_pred ')
            logging.info('shapes c {} A {} b {} G {} h {} Q {}'.format(c_pred.shape, A_torch.shape, b_torch.shape, G_torch.shape, h_torch.shape, Q_torch.shape))
            x = QPFunction(verbose=False, solver=QPSolvers.GUROBI, model_params=model_params_quad)(Q_torch.expand(1, *Q_torch.shape), c_pred.squeeze(), G_torch.expand(1, *G_torch.shape), h_torch.expand(1, *h_torch.shape), A_torch.expand(1, *A_torch.shape), b_torch.expand(1, *b_torch.shape))
            c_pred.retain_grad()
            loss = (y_torch * x).mean()
            loss.backward()
            c_grad = copy.deepcopy(c_pred.grad)
            if any(torch.isnan(torch.flatten(c_grad)).tolist()):
                logging.info('**Alert** nan in param  c_grad ')
            self.optimizer.step()
            end_time = time.time()
            time_ += (end_time - start_time)
            if self.validation:
                if (((i + 1) % 20) == 0):
                    validation_list.append(validation_module(self.net, self.A, X, y, train_instances, validation_instances, test_instances, time_, e, i))
        print('Epoch {} Loss:{} Time: {:%Y-%m-%d %H:%M:%S}'.format((e + 1), loss.sum().item(), datetime.datetime.now()))
    if self.validation:
        dd = defaultdict(list)
        for d in validation_list:
            for (key, value) in d.items():
                dd[key].append(value)
        df = pd.DataFrame.from_dict(dd)
        logging.info(('Completion Time %s \n' % str(datetime.datetime.now())))
        return df