Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change csc/csr_matrix to array #121

Merged
merged 4 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/source/mods/min-cost-flow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ An example of these inputs with their respective requirements is shown below.
>>> from gurobi_optimods import datasets
>>> G, capacities, cost, demands = datasets.simple_graph_scipy()
>>> G
<5x6 sparse matrix of type '<class 'numpy.int64'>'
<5x6 sparse array of type '<class 'numpy.int64'>'
with 7 stored elements in COOrdinate format>
>>> print(G)
(0, 1) 1
Expand Down Expand Up @@ -207,7 +207,7 @@ formats.
>>> obj
31.0
>>> sol
<5x6 sparse matrix of type '<class 'numpy.float64'>'
<5x6 sparse array of type '<class 'numpy.float64'>'
with 5 stored elements in COOrdinate format>
>>> print(sol)
(0, 1) 1.0
Expand Down
2 changes: 1 addition & 1 deletion docs/source/mods/qubo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ definition as a SciPy sparse matrix in a comment).
# weights = [-3, 2, -1, -2, 3]
# row = [1, 2, 0, 0, 1]
# col = [1, 2, 1, 2, 2]
# Q = sp.coo_matrix((weights, (row, col)), shape=(3, 3))
# Q = sp.coo_array((weights, (row, col)), shape=(3, 3))

result = solve_qubo(Q)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"gurobipy>=10.0.1",
"gurobipy>=10.0.3",
"gurobipy-pandas>=1.0.0",
"numpy",
"pandas",
Expand Down
4 changes: 2 additions & 2 deletions src/gurobi_optimods/bipartite_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def _maximum_bipartite_matching_scipy(adjacency, nodes1, nodes2, create_env):
indptr = np.arange(0, 2 * from_arc.shape[0] + 2, 2)
ones = np.ones(from_arc.shape)
data = np.column_stack((ones * -1.0, ones)).reshape(-1, order="C")
A = sp.csc_matrix((data, indices, indptr))
A = sp.csc_array((data, indices, indptr))

# Solve model with gurobi, return cost and flows
x = model.addMVar(A.shape[1], lb=0, ub=capacity)
Expand All @@ -215,5 +215,5 @@ def _maximum_bipartite_matching_scipy(adjacency, nodes1, nodes2, create_env):

# Return undirected, unweighted adjacency matrix
arg = (np.ones(from_arc_result.shape), (from_arc_result, to_arc_result))
matching = sp.coo_matrix(arg, dtype=float, shape=G.shape)
matching = sp.coo_array(arg, dtype=float, shape=G.shape)
return matching + matching.T
8 changes: 4 additions & 4 deletions src/gurobi_optimods/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def _convert_pandas_to_scipy(
edge_data, node_data, capacity=True, cost=True, demand=True
):
"""
Convert from a pandas DataFrame to several scipy.sparse.coo_matrix contain
Convert from a pandas DataFrame to several scipy.sparse.coo_array contain
the graph structure, the capacity and cost values per edge, and the demand
values per node.
"""
Expand All @@ -116,17 +116,17 @@ def _convert_pandas_to_scipy(
a1 = np.array([c[1] for c in coords])

data = np.ones(len(coords), dtype=np.int64)
G = sp.coo_matrix((data, (a0, a1)))
G = sp.coo_array((data, (a0, a1)))

costs = None
if cost:
data = edge_data["cost"].values
costs = sp.coo_matrix((data, (a0, a1)))
costs = sp.coo_array((data, (a0, a1)))

cap = None
if capacity:
data = edge_data["capacity"].values
cap = sp.coo_matrix((data, (a0, a1)))
cap = sp.coo_array((data, (a0, a1)))

dem = None
if demand:
Expand Down
4 changes: 2 additions & 2 deletions src/gurobi_optimods/min_cost_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def min_cost_flow_scipy(
ones = np.ones(edge_source.shape)
data = np.column_stack((ones * -1.0, ones)).reshape(-1, order="C")

A = sp.csc_matrix((data, indices, indptr))
A = sp.csc_array((data, indices, indptr))

logger.info("Solving min-cost flow with {0} nodes and {1} edges".format(*A.shape))

Expand All @@ -149,7 +149,7 @@ def min_cost_flow_scipy(
edge_source_result = edge_source[select]
edge_target_result = edge_target[select]
arg = (x.X[select], (edge_source_result, edge_target_result))
return model.ObjVal, sp.coo_matrix(arg, dtype=float, shape=G.shape)
return model.ObjVal, sp.coo_array(arg, dtype=float, shape=G.shape)


@optimod()
Expand Down
11 changes: 11 additions & 0 deletions tests/test_bipartite_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@ def test_random_csr_matrix(self):
self.assertEqual(matching.shape, adjacency.shape)
self.assert_is_unweighted_matching(matching)

def test_random_csr_array(self):
# Property test for matchings on random graphs
adjacency, nodes1, nodes2 = random_bipartite(n1=8, n2=7, p=0.5, seed=98634)

matching = maximum_bipartite_matching(sp.csr_array(adjacency), nodes1, nodes2)

self.assertIsInstance(matching, sp.spmatrix)
self.assertIsNot(matching, adjacency)
self.assertEqual(matching.shape, adjacency.shape)
self.assert_is_unweighted_matching(matching)

def test_random_csc_array(self):
# Property test for matchings on random graphs
adjacency, nodes1, nodes2 = random_bipartite(n1=5, n2=2, p=0.5, seed=34687)
Expand Down