Skip to content

Commit

Permalink
Merge pull request #94 from chrhansk/feature-mps-solver
Browse files Browse the repository at this point in the history
Add solver for MPS-encoded LPs
  • Loading branch information
chrhansk authored May 27, 2024
2 parents cfafc46 + 31e798c commit da7ce5e
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
project = "pygradflow"
copyright = "2023, Christoph Hansknecht"
author = "Christoph Hansknecht"
release = "0.5.1"
release = "0.5.2"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
91 changes: 91 additions & 0 deletions pygradflow/runners/mps_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import os

import mpspy
import numpy as np

from pygradflow.problem import Problem
from pygradflow.util import sparse_zero

from .instance import Instance
from .runner import Runner


class LinearProblem(Problem):
def __init__(self, instance):
self.instance = instance

super().__init__(
var_lb=instance.var_lb,
var_ub=instance.var_ub,
cons_lb=instance.cons_lb,
cons_ub=instance.cons_ub,
)

def obj(self, x):
instance = self.instance
return np.dot(instance.obj, x)

def obj_grad(self, x):
instance = self.instance
return instance.obj

def cons(self, x):
instance = self.instance
coeffs = instance.coeffs
return coeffs.dot(x)

def cons_jac(self, x):
instance = self.instance
return instance.coeffs

def lag_hess(self, x, y):
num_vars = self.num_vars
return sparse_zero(shape=(num_vars, num_vars))


class MPSInstance(Instance):
def __init__(self, instance):
self.instance = instance

num_vars = instance.num_vars
num_cons = instance.num_cons
name = instance.name

super().__init__(name, num_vars, num_cons)

def problem(self):
return LinearProblem(self.instance)

def x0(self):
instance = self.instance
num_vars = instance.num_vars

x0 = np.zeros((num_vars,))

return np.clip(x0, instance.var_lb, instance.var_ub)


class MPSRunner(Runner):
def __init__(self):
super().__init__(name="mps")

def get_instances(self, args):
instances = []
for file in os.listdir(args.directory):
is_qplib = file.endswith(".mps") or file.endswith(".mps.gz")

if is_qplib:
filename = os.path.join(args.directory, file)
description = mpspy.read_mps(filename)
instances.append(MPSInstance(description))

return instances

def parser(self):
parser = super().parser()
parser.add_argument("directory")
return parser


if __name__ == "__main__":
MPSRunner().main()
4 changes: 2 additions & 2 deletions pygradflow/runners/qplib_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ def lag_hess(self, x, y):
return self.problem.lag_hess(x, y)

def x0(self):
return self.problem.x0()
return self.problem.x0

def y0(self):
return self.problem.y0()
return self.problem.y0


class QPLIBInstance(Instance):
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pygradflow"
version = "0.5.1"
version = "0.5.2"
description = "PyGradFlow is a simple implementation of the sequential homotopy method to be used to solve general nonlinear programs."
authors = ["Christoph Hansknecht <[email protected]>"]
readme = "README.md"
Expand All @@ -25,6 +25,7 @@ mypy = "^1.7.1"
types-pyyaml = "^6.0.12"
pytest-timeout = "^2.3.1"
pyflakes = "^3.2.0"
mpspy = "^0.1.3"

[tool.poetry.group.docs.dependencies]
sphinx = "^7.2.6"
Expand Down

0 comments on commit da7ce5e

Please sign in to comment.