Skip to content

Commit c9b4c1d

Browse files
committed
Some doc updates and minor cleanup.
1 parent 7e14b6b commit c9b4c1d

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

mac/solvers/mac.py

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
from dataclasses import dataclass
66
from typing import Optional
7-
from scipy.sparse import csc_matrix, csr_matrix
87
from timeit import default_timer as timer
98

109
from mac.utils.graphs import *
@@ -41,13 +40,23 @@ def __init__(self, fixed_edges, candidate_edges, num_nodes,
4140
min_edge_selection_tol : float, optional
4241
Tolerance for the minimum edge selection weight. Default is 1e-10.
4342
"""
44-
if (num_nodes == 0):
45-
assert(len(fixed_edges) == len(candidate_edges) == 0)
43+
# Check that we at least *could* have a spanning tree in the set
44+
# {fixed_edges U candidate_edges} This does not guarantee that a
45+
# spanning tree exists, but it's a good basic test.
46+
num_edges = len(fixed_edges) + len(candidate_edges)
47+
assert (num_nodes - 1) <= num_edges
48+
49+
# We also check that there aren't "too many" edges. The number of edges
50+
# in the complete graph K(n) is equal to n * (n - 1) / 2, so we cannot
51+
# possibly have more edges than this.
52+
assert num_edges <= 0.5 * num_nodes * (num_nodes - 1)
53+
54+
# Pre-compute the Laplacian for the subgraph comprised of the "fixed edges".
4655
self.L_fixed = weight_graph_lap_from_edge_list(fixed_edges, num_nodes)
4756
self.num_nodes = num_nodes
57+
4858
self.weights = []
4959
self.edge_list = []
50-
5160
for edge in candidate_edges:
5261
self.weights.append(edge.weight)
5362
self.edge_list.append((edge.i, edge.j))
@@ -63,15 +72,15 @@ def __init__(self, fixed_edges, candidate_edges, num_nodes,
6372
self.min_selection_weight_tol = min_selection_weight_tol
6473

6574
def laplacian(self, x):
66-
"""
67-
Construct the combined Laplacian (fixed edges plus candidate edges weighted by x).
68-
75+
"""Construct the combined Laplacian (fixed edges plus candidate edges weighted by x).
6976
x: An element of [0,1]^m; this is the edge selection to use
70-
tol: Tolerance for edges that are numerically zero. This improves speed
71-
in situations where edges are not *exactly* zero, but close enough that
72-
they have almost no influence on the graph.
7377
74-
returns the matrix L(w)
78+
The tolerance parameter `min_selection_weight_tol` is used to prune out
79+
edges that are numerically zero. This improves speed in situations
80+
where edges are not *exactly* zero, but close enough that they have
81+
almost no influence on the graph.
82+
83+
returns the matrix L(x)
7584
"""
7685
idx = np.where(x > self.min_selection_weight_tol)
7786
prod = x[idx]*self.weights[idx]
@@ -89,11 +98,16 @@ def evaluate_objective(self, x):
8998
9099
returns F(x) = lambda_2(L(x)).
91100
"""
92-
return fiedler.find_fiedler_pair(L=self.laplacian(x), method=self.fiedler_method, tol=self.fiedler_tol)[0]
101+
return fiedler.find_fiedler_pair(L=self.laplacian(x),
102+
method=self.fiedler_method, tol=self.fiedler_tol)[0]
93103

94104
def problem(self, x, cache=None):
95-
"""
96-
Compute the algebraic connectivity of L(x) and a (super)gradient of the algebraic connectivity with respect to x.
105+
"""Compute the algebraic connectivity of L(x) and a (super)gradient of the
106+
algebraic connectivity with respect to x.
107+
108+
x: Weights for each candidate edge (does not include fixed edges)
109+
cache: Mutable `Cache` object. If a `Cache` object is provided in the `cache` field, it will be used
110+
and updated, but not explicitly returned. Rather, it will be updated directly.
97111
98112
returns x, grad F(x).
99113
"""
@@ -114,17 +128,18 @@ def problem(self, x, cache=None):
114128
return f, gradf
115129

116130
def solve(self, k, x_init=None, rounding="nearest", fallback=False,
117-
max_iters=5, relative_duality_gap_tol=1e-4,
118-
grad_norm_tol=1e-8, random_rounding_max_iters=1, verbose=False, return_rounding_time=False, use_cache=False):
131+
max_iters=5, relative_duality_gap_tol=1e-4,
132+
grad_norm_tol=1e-8, random_rounding_max_iters=1,
133+
verbose=False, return_rounding_time=False, use_cache=False):
119134
"""Use the Frank-Wolfe method to solve the subset selection problem,.
120135
121136
Parameters
122137
----------
123-
x_init : Array-like
124-
Initial weights for the candidate edges, must satisfy 0 <= w_i <= 1, |w| <= k. This
125-
is the starting point for the Frank-Wolfe algorithm. TODO(kevin): make optional
126138
k : int
127139
Number of edges to select.
140+
x_init : optional, array-like
141+
Initial weights for the candidate edges, must satisfy 0 <= w_i <= 1, |w| <= k. This
142+
is the starting point for the Frank-Wolfe algorithm. TODO(kevin): make optional
128143
rounding : str, optional
129144
Rounding method to use. Options are "nearest" (default) and "madow"
130145
(a random rounding procedure).

0 commit comments

Comments
 (0)