Example #1
0
    def get_rhs(self, row_indices=None):
        '''get the rhs vector of the constraints

        row_indices - a list of requested indices (None=all)

        this returns an np.array of rhs values for the requested indices
        '''

        rv = []

        if row_indices is None:
            lp_rows = glpk.glp_get_num_rows(self.lp)
            row_indices = range(lp_rows)

        for row in row_indices:
            row_type = glpk.glp_get_row_type(self.lp, row + 1)

            if row_type in [glpk.GLP_FX, glpk.GLP_UP]:
                limit = glpk.glp_get_row_ub(self.lp, row + 1)
            elif row_type == glpk.GLP_LO:
                limit = glpk.glp_get_row_ub(self.lp, row + 1)
            else:
                raise RuntimeError(
                    "Error: Unsupported type ({}) in getRhs() in row {}".
                    format(row_type, row))

            rv.append(limit)

        return np.array(rv, dtype=float)
 def test_change_constraint_bounds(self):
     inner_prob = self.model.problem
     inner_problem_bounds = [(glp_get_row_lb(inner_prob, i), glp_get_row_ub(inner_prob, i)) for i in
                             range(1, glp_get_num_rows(inner_prob) + 1)]
     bounds = [(constr.lb, constr.ub) for constr in self.model.constraints]
     self.assertEqual(bounds, inner_problem_bounds)
     for constr in self.model.constraints:
         constr.lb = random.uniform(-1000, constr.ub)
         constr.ub = random.uniform(constr.lb, 1000)
     inner_problem_bounds_new = [(glp_get_row_lb(inner_prob, i), glp_get_row_ub(inner_prob, i)) for i in
                                 range(1, glp_get_num_rows(inner_prob) + 1)]
     bounds_new = [(constr.lb, constr.ub) for constr in self.model.constraints]
     self.assertNotEqual(bounds, bounds_new)
     self.assertNotEqual(inner_problem_bounds, inner_problem_bounds_new)
     self.assertEqual(bounds_new, inner_problem_bounds_new)
 def test_change_constraint_bounds(self):
     inner_prob = self.model.problem
     inner_problem_bounds = [
         (glp_get_row_lb(inner_prob, i), glp_get_row_ub(inner_prob, i))
         for i in range(1,
                        glp_get_num_rows(inner_prob) + 1)
     ]
     bounds = [(constr.lb, constr.ub) for constr in self.model.constraints]
     self.assertEqual(bounds, inner_problem_bounds)
     for constr in self.model.constraints:
         constr.lb = random.uniform(-1000, constr.ub)
         constr.ub = random.uniform(constr.lb, 1000)
     inner_problem_bounds_new = [
         (glp_get_row_lb(inner_prob, i), glp_get_row_ub(inner_prob, i))
         for i in range(1,
                        glp_get_num_rows(inner_prob) + 1)
     ]
     bounds_new = [(constr.lb, constr.ub)
                   for constr in self.model.constraints]
     self.assertNotEqual(bounds, bounds_new)
     self.assertNotEqual(inner_problem_bounds, inner_problem_bounds_new)
     self.assertEqual(bounds_new, inner_problem_bounds_new)
Example #4
0
    def _constraints_str(self, zero_print):
        'get the constraints matrix lines for __str__'

        rv = ""
        lp = self.lp
        rows = self.get_num_rows()
        cols = self.get_num_cols()

        stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS"]
        inds = SwigArray.get_int_array(cols + 1)
        vals = SwigArray.get_double_array(cols + 1)

        for row in range(1, rows + 1):
            stat = glpk.glp_get_row_stat(lp, row)
            assert 0 <= stat <= len(stat_labels)
            rv += "{:2}: {} ".format(row, stat_labels[stat])

            num_inds = glpk.glp_get_mat_row(lp, row, inds, vals)

            for col in range(1, cols + 1):
                val = 0

                for index in range(1, num_inds + 1):
                    if inds[index] == col:
                        val = vals[index]
                        break

                num = str(val)
                num = num.rjust(6)[:6]  # fix width to exactly 6

                rv += (zero_print(num) if val == 0 else num) + " "

            row_type = glpk.glp_get_row_type(lp, row)

            assert row_type == glpk.GLP_UP
            val = glpk.glp_get_row_ub(lp, row)
            rv += " <= "

            num = str(val)
            num = num.rjust(6)[:6]  # fix width to exactly 6

            rv += (zero_print(num) if val == 0 else num) + " "

            rv += "\n"

        return rv
Example #5
0
    def serialize(self):
        'serialize self.lp from a glpk instance into a tuple'

        Timers.tic('serialize')

        # get constraints as csr matrix
        lp_rows = self.get_num_rows()
        lp_cols = self.get_num_cols()

        inds_row = SwigArray.get_int_array(lp_cols + 1)
        vals_row = SwigArray.get_double_array(lp_cols + 1)

        data = []
        glpk_indices = []
        indptr = [0]

        for row in range(lp_rows):
            got_len = glpk.glp_get_mat_row(self.lp, row + 1, inds_row,
                                           vals_row)

            for i in range(1, got_len + 1):
                data.append(vals_row[i])
                glpk_indices.append(inds_row[i])

            indptr.append(len(data))

        # rhs
        rhs = []

        for row in range(lp_rows):
            assert glpk.glp_get_row_type(self.lp, row + 1) == glpk.GLP_UP

            rhs.append(glpk.glp_get_row_ub(self.lp, row + 1))

        col_bounds = self.get_col_bounds()

        # remember to free lp object before overwriting with tuple
        glpk.glp_delete_prob(self.lp)
        self.lp = (data, glpk_indices, indptr, rhs, col_bounds)

        Timers.toc('serialize')
Example #6
0
    def _initialize_model_from_problem(self, problem):
        try:
            self.problem = problem
            glp_create_index(self.problem)
        except TypeError:
            raise TypeError("Provided problem is not a valid GLPK model.")
        row_num = glp_get_num_rows(self.problem)
        col_num = glp_get_num_cols(self.problem)
        for i in range(1, col_num + 1):
            var = Variable(
                glp_get_col_name(self.problem, i),
                lb=glp_get_col_lb(self.problem, i),
                ub=glp_get_col_ub(self.problem, i),
                problem=self,
                type=_GLPK_VTYPE_TO_VTYPE[
                    glp_get_col_kind(self.problem, i)]
            )
            # This avoids adding the variable to the glpk problem
            super(Model, self)._add_variables([var])
        variables = self.variables

        for j in range(1, row_num + 1):
            ia = intArray(col_num + 1)
            da = doubleArray(col_num + 1)
            nnz = glp_get_mat_row(self.problem, j, ia, da)
            constraint_variables = [variables[ia[i] - 1] for i in range(1, nnz + 1)]

            # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
            # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1]
            #                         for i in range(1, nnz + 1)])
            lhs = 0

            glpk_row_type = glp_get_row_type(self.problem, j)
            if glpk_row_type == GLP_FX:
                row_lb = glp_get_row_lb(self.problem, j)
                row_ub = row_lb
            elif glpk_row_type == GLP_LO:
                row_lb = glp_get_row_lb(self.problem, j)
                row_ub = None
            elif glpk_row_type == GLP_UP:
                row_lb = None
                row_ub = glp_get_row_ub(self.problem, j)
            elif glpk_row_type == GLP_DB:
                row_lb = glp_get_row_lb(self.problem, j)
                row_ub = glp_get_row_ub(self.problem, j)
            elif glpk_row_type == GLP_FR:
                row_lb = None
                row_ub = None
            else:
                raise Exception(
                    "Currently, optlang does not support glpk row type %s"
                    % str(glpk_row_type)
                )
                log.exception()
            if isinstance(lhs, int):
                lhs = symbolics.Integer(lhs)
            elif isinstance(lhs, float):
                lhs = symbolics.Real(lhs)
            constraint_id = glp_get_row_name(self.problem, j)
            for variable in constraint_variables:
                try:
                    self._variables_to_constraints_mapping[variable.name].add(constraint_id)
                except KeyError:
                    self._variables_to_constraints_mapping[variable.name] = set([constraint_id])

            super(Model, self)._add_constraints(
                [Constraint(lhs, lb=row_lb, ub=row_ub, name=constraint_id, problem=self, sloppy=True)],
                sloppy=True
            )

        term_generator = (
            (glp_get_obj_coef(self.problem, index), variables[index - 1])
            for index in range(1, glp_get_num_cols(problem) + 1)
        )
        self._objective = Objective(
            symbolics.add(
                [symbolics.mul((symbolics.Real(term[0]), term[1])) for term in term_generator if
                 term[0] != 0.]
            ),
            problem=self,
            direction={GLP_MIN: 'min', GLP_MAX: 'max'}[glp_get_obj_dir(self.problem)])
        glp_scale_prob(self.problem, GLP_SF_AUTO)
    def test_add_constraints(self):
        x = Variable('x', lb=0, ub=1, type='binary')
        y = Variable('y', lb=-181133.3, ub=12000., type='continuous')
        z = Variable('z', lb=0., ub=10., type='integer')
        constr1 = Constraint(0.3 * x + 0.4 * y + 66. * z,
                             lb=-100,
                             ub=0.,
                             name='test')
        constr2 = Constraint(2.333 * x + y + 3.333, ub=100.33, name='test2')
        constr3 = Constraint(2.333 * x + y + z, lb=-300)
        constr4 = Constraint(x, lb=-300, ub=-300)
        constr5 = Constraint(3 * x)
        self.model.add(constr1)
        self.model.add(constr2)
        self.model.add(constr3)
        self.model.add([constr4, constr5])
        self.assertIn(constr1.name, self.model.constraints)
        self.assertIn(constr2.name, self.model.constraints)
        self.assertIn(constr3.name, self.model.constraints)
        self.assertIn(constr4.name, self.model.constraints)
        self.assertIn(constr5.name, self.model.constraints)
        # constr1
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr1._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 0.3, 'y': 0.4, 'z': 66.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr1._index),
                         GLP_DB)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr1._index),
                         -100)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr1._index), 0)
        # constr2
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr2._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr2._index),
                         GLP_UP)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr2._index),
                         -1.7976931348623157e+308)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr2._index),
                         96.997)
        # constr3
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr3._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1., 'z': 1.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr3._index),
                         GLP_LO)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr3._index),
                         -300)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr3._index),
                         1.7976931348623157e+308)
        # constr4
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr4._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 1})
        self.assertEqual(glp_get_row_type(self.model.problem, constr4._index),
                         GLP_FX)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr4._index),
                         -300)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr4._index),
                         -300)

        # constr5
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr5._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 3})
        self.assertEqual(glp_get_row_type(self.model.problem, constr5._index),
                         GLP_FR)
        self.assertLess(glp_get_row_lb(self.model.problem, constr5._index),
                        -1e30)
        self.assertGreater(glp_get_row_ub(self.model.problem, constr5._index),
                           1e30)
    def test_add_constraints(self):
        x = self.interface.Variable('x', lb=0, ub=1, type='binary')
        y = self.interface.Variable('y', lb=-181133.3, ub=12000., type='continuous')
        z = self.interface.Variable('z', lb=0., ub=10., type='integer')
        constr1 = self.interface.Constraint(0.3 * x + 0.4 * y + 66. * z, lb=-100, ub=0., name='test')
        constr2 = self.interface.Constraint(2.333 * x + y + 3.333, ub=100.33, name='test2')
        constr3 = self.interface.Constraint(2.333 * x + y + z, lb=-300)
        constr4 = self.interface.Constraint(x, lb=-300, ub=-300)
        constr5 = self.interface.Constraint(3 * x)
        self.model.add(constr1)
        self.model.add(constr2)
        self.model.add(constr3)
        self.model.add([constr4, constr5])
        self.assertIn(constr1.name, self.model.constraints)
        self.assertIn(constr2.name, self.model.constraints)
        self.assertIn(constr3.name, self.model.constraints)
        self.assertIn(constr4.name, self.model.constraints)
        self.assertIn(constr5.name, self.model.constraints)
        # constr1
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr1._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 0.3, 'y': 0.4, 'z': 66.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr1._index), GLP_DB)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr1._index), -100)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr1._index), 0)
        # constr2
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr2._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr2._index), GLP_UP)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr2._index), -1.7976931348623157e+308)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr2._index), 96.997)
        # constr3
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr3._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1., 'z': 1.})
        self.assertEqual(glp_get_row_type(self.model.problem, constr3._index), GLP_LO)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr3._index), -300)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr3._index), 1.7976931348623157e+308)
        # constr4
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr4._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 1})
        self.assertEqual(glp_get_row_type(self.model.problem, constr4._index), GLP_FX)
        self.assertEqual(glp_get_row_lb(self.model.problem, constr4._index), -300)
        self.assertEqual(glp_get_row_ub(self.model.problem, constr4._index), -300)

        # constr5
        ia = intArray(glp_get_num_rows(self.model.problem) + 1)
        da = doubleArray(glp_get_num_rows(self.model.problem) + 1)
        nnz = glp_get_mat_row(self.model.problem, constr5._index, ia, da)
        coeff_dict = dict()
        for i in range(1, nnz + 1):
            coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i]
        self.assertDictEqual(coeff_dict, {'x': 3})
        self.assertEqual(glp_get_row_type(self.model.problem, constr5._index), GLP_FR)
        self.assertLess(glp_get_row_lb(self.model.problem, constr5._index), -1e30)
        self.assertGreater(glp_get_row_ub(self.model.problem, constr5._index), 1e30)
Example #9
0
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        self.configuration = Configuration()

        if problem is None:
            self.problem = glp_create_prob()
            glp_create_index(self.problem)
            if self.name is not None:
                glp_set_prob_name(self.problem, str(self.name))

        else:
            try:
                self.problem = problem
                glp_create_index(self.problem)
            except TypeError:
                raise TypeError("Provided problem is not a valid GLPK model.")
            row_num = glp_get_num_rows(self.problem)
            col_num = glp_get_num_cols(self.problem)
            for i in range(1, col_num + 1):
                var = Variable(
                    glp_get_col_name(self.problem, i),
                    lb=glp_get_col_lb(self.problem, i),
                    ub=glp_get_col_ub(self.problem, i),
                    problem=self,
                    type=_GLPK_VTYPE_TO_VTYPE[
                        glp_get_col_kind(self.problem, i)]
                )
                # This avoids adding the variable to the glpk problem
                super(Model, self)._add_variables([var])
            variables = self.variables

            for j in range(1, row_num + 1):
                ia = intArray(col_num + 1)
                da = doubleArray(col_num + 1)
                nnz = glp_get_mat_row(self.problem, j, ia, da)
                constraint_variables = [variables[ia[i] - 1] for i in range(1, nnz + 1)]

                # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
                # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1]
                #                         for i in range(1, nnz + 1)])
                lhs = 0

                glpk_row_type = glp_get_row_type(self.problem, j)
                if glpk_row_type == GLP_FX:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = row_lb
                elif glpk_row_type == GLP_LO:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = None
                elif glpk_row_type == GLP_UP:
                    row_lb = None
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_DB:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_FR:
                    row_lb = None
                    row_ub = None
                else:
                    raise Exception(
                        "Currently, optlang does not support glpk row type %s"
                        % str(glpk_row_type)
                    )
                    log.exception()
                if isinstance(lhs, int):
                    lhs = sympy.Integer(lhs)
                elif isinstance(lhs, float):
                    lhs = sympy.RealNumber(lhs)
                constraint_id = glp_get_row_name(self.problem, j)
                for variable in constraint_variables:
                    try:
                        self._variables_to_constraints_mapping[variable.name].add(constraint_id)
                    except KeyError:
                        self._variables_to_constraints_mapping[variable.name] = set([constraint_id])

                super(Model, self)._add_constraints(
                    [Constraint(lhs, lb=row_lb, ub=row_ub, name=constraint_id, problem=self, sloppy=True)],
                    sloppy=True
                )

            term_generator = (
                (glp_get_obj_coef(self.problem, index), variables[index - 1])
                for index in range(1, glp_get_num_cols(problem) + 1)
            )
            self._objective = Objective(
                _unevaluated_Add(
                    *[_unevaluated_Mul(sympy.RealNumber(term[0]), term[1]) for term in term_generator if
                      term[0] != 0.]),
                problem=self,
                direction={GLP_MIN: 'min', GLP_MAX: 'max'}[glp_get_obj_dir(self.problem)])
        glp_scale_prob(self.problem, GLP_SF_AUTO)
Example #10
0
    def _constraints_str(self, bm_print, input_print, zero_print):
        'get the constraints matrix lines for __str__'

        rv = ""
        lp = self.lp
        rows = self.get_num_rows()
        cols = self.get_num_cols()

        stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS"]
        inds = glpk.intArray(cols + 1)
        vals = glpk.doubleArray(cols + 1)

        for row in range(1, rows + 1):
            stat = glpk.glp_get_row_stat(lp, row)
            assert 0 <= stat <= len(stat_labels)
            rv += "{:2}: {} ".format(row, stat_labels[stat])

            num_inds = glpk.glp_get_mat_row(lp, row, inds, vals)

            for col in range(1, cols + 1):
                val = 0

                for index in range(1, num_inds + 1):
                    if inds[index] == col:
                        val = vals[index]
                        break

                num = str(val)
                if len(num) < 6:
                    num = (" " * (6 - len(num))) + num
                else:
                    num = num[0:6]

                if self.basis_mat_rect[1] <= row - 1 < self.basis_mat_rect[0] + self.basis_mat_rect[3] and \
                        self.basis_mat_rect[0] <= col - 1 < self.basis_mat_rect[1] + self.basis_mat_rect[2]:
                    rv += bm_print(num) + " "
                else:
                    rv += (zero_print(num) if val == 0 else num) + " "

            row_type = glpk.glp_get_row_type(lp, row)

            if row_type == glpk.GLP_FX:
                val = glpk.glp_get_row_ub(lp, row)
                rv += " == "
            else:
                assert row_type == glpk.GLP_UP

                val = glpk.glp_get_row_ub(lp, row)
                rv += " <= "

            num = str(val)
            if len(num) < 6:
                num = (" " * (6 - len(num))) + num
            else:
                num = num[0:6]

            rv += (zero_print(num) if val == 0 else num) + " "

            rv += "\n"

        return rv
Example #11
0
    def _constraints_str(self, bm_print, input_print, zero_print):
        'get the constraints matrix lines for __str__'

        rv = ""
        lp = self.lp
        rows = self.get_num_rows()
        cols = self.get_num_cols()
        
        stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS", "?(6)?"]
        inds = glpk.intArray(cols + 1)
        vals = glpk.doubleArray(cols + 1)

        for row in range(1, rows + 1):
            rv += "{:2}: {} ".format(row-1, stat_labels[glpk.glp_get_row_stat(lp, row)])

            num_inds = glpk.glp_get_mat_row(lp, row, inds, vals)

            for col in range(1, cols + 1):
                val = 0

                for index in range(1, num_inds+1):
                    if inds[index] == col:
                        val = vals[index]
                        break

                num = str(val)
                if len(num) < 6:
                    num = (" " * (6 - len(num))) + num
                else:
                    num = num[0:6]

                if self.basis_mat_pos[0] <= row - 1 < self.basis_mat_pos[0] + self.dims and \
                        self.basis_mat_pos[1] <= col - 1 < self.basis_mat_pos[1] + self.dims:
                    rv += bm_print(num) + " "
                elif self.input_effects_offsets is not None and \
                        self.input_effects_offsets[0] <= row - 1 < self.input_effects_offsets[0] + self.dims and \
                        self.input_effects_offsets[1] <= col - 1 < self.input_effects_offsets[1] + self.dims:
                    rv += input_print(num) + " "
                else:
                    rv += (zero_print(num) if val == 0 else num) + " "

            row_type = glpk.glp_get_row_type(lp, row)

            if row_type == glpk.GLP_FX:
                val = glpk.glp_get_row_ub(lp, row)
                rv += " == "
            elif row_type == glpk.GLP_UP:
                val = glpk.glp_get_row_ub(lp, row)
                rv += " <= "
            elif row_type == glpk.GLP_LO:
                val = glpk.glp_get_row_lb(lp, row)
                rv += " >= "
            else:
                rv += " <?> (unknown bounds)"
                val = '?'

            num = str(val)
            if len(num) < 6:
                num = (" " * (6 - len(num))) + num
            else:
                num = num[0:6]

            rv += (zero_print(num) if val == 0 else num) + " "

            rv += "\n"

        return rv