nystrom-ncut 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nystrom_ncut/distance_utils.py +2 -2
- nystrom_ncut/nystrom/distance_realization.py +5 -5
- nystrom_ncut/nystrom/normalized_cut.py +22 -10
- nystrom_ncut/nystrom/nystrom_utils.py +38 -39
- {nystrom_ncut-0.1.4.dist-info → nystrom_ncut-0.1.6.dist-info}/METADATA +1 -1
- nystrom_ncut-0.1.6.dist-info/RECORD +15 -0
- nystrom_ncut-0.1.4.dist-info/RECORD +0 -15
- {nystrom_ncut-0.1.4.dist-info → nystrom_ncut-0.1.6.dist-info}/LICENSE +0 -0
- {nystrom_ncut-0.1.4.dist-info → nystrom_ncut-0.1.6.dist-info}/WHEEL +0 -0
- {nystrom_ncut-0.1.4.dist-info → nystrom_ncut-0.1.6.dist-info}/top_level.txt +0 -0
nystrom_ncut/distance_utils.py
CHANGED
@@ -38,14 +38,14 @@ def distance_from_features(
|
|
38
38
|
elif distance == "euclidean":
|
39
39
|
D = torch.cdist(features, features_B, p=2)
|
40
40
|
elif distance == "rbf":
|
41
|
-
D = torch.cdist(features, features_B, p=2) ** 2
|
41
|
+
D = 0.5 * torch.cdist(features, features_B, p=2) ** 2
|
42
42
|
|
43
43
|
# Outlier-robust scale invariance using quantiles to estimate standard deviation
|
44
44
|
c = 2.0
|
45
45
|
p = torch.erf(torch.tensor((-c, c), device=features.device) * (2 ** -0.5))
|
46
46
|
stds = torch.quantile(features, q=(p + 1) / 2, dim=0)
|
47
47
|
stds = (stds[1] - stds[0]) / (2 * c)
|
48
|
-
D = D / (
|
48
|
+
D = D / (torch.linalg.norm(stds) ** 2)
|
49
49
|
else:
|
50
50
|
raise ValueError("distance should be 'cosine' or 'euclidean', 'rbf'")
|
51
51
|
return D
|
@@ -98,8 +98,8 @@ class DistanceRealization(OnlineNystromSubsampleFit):
|
|
98
98
|
def __init__(
|
99
99
|
self,
|
100
100
|
n_components: int = 100,
|
101
|
-
sample_config: SampleConfig = SampleConfig(),
|
102
101
|
distance: DistanceOptions = "cosine",
|
102
|
+
sample_config: SampleConfig = SampleConfig(),
|
103
103
|
eig_solver: EigSolverOptions = "svd_lowrank",
|
104
104
|
chunk_size: int = 8192,
|
105
105
|
):
|
@@ -128,9 +128,9 @@ class DistanceRealization(OnlineNystromSubsampleFit):
|
|
128
128
|
features: torch.Tensor,
|
129
129
|
precomputed_sampled_indices: torch.Tensor = None,
|
130
130
|
) -> torch.Tensor:
|
131
|
-
V
|
132
|
-
return V * (
|
131
|
+
V = OnlineNystromSubsampleFit.fit_transform(self, features, precomputed_sampled_indices)
|
132
|
+
return V * (self.eigenvalues_ ** 0.5)
|
133
133
|
|
134
134
|
def transform(self, features: torch.Tensor = None) -> torch.Tensor:
|
135
|
-
V
|
136
|
-
return V * (
|
135
|
+
V = OnlineNystromSubsampleFit.transform(self, features)
|
136
|
+
return V * (self.eigenvalues_ ** 0.5)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import einops
|
1
2
|
import torch
|
2
3
|
import torch.nn.functional as Fn
|
3
4
|
|
@@ -21,10 +22,12 @@ class LaplacianKernel(OnlineKernel):
|
|
21
22
|
self,
|
22
23
|
affinity_focal_gamma: float,
|
23
24
|
distance: DistanceOptions,
|
25
|
+
adaptive_scaling: bool,
|
24
26
|
eig_solver: EigSolverOptions,
|
25
27
|
):
|
26
28
|
self.affinity_focal_gamma = affinity_focal_gamma
|
27
29
|
self.distance: DistanceOptions = distance
|
30
|
+
self.adaptive_scaling: bool = adaptive_scaling
|
28
31
|
self.eig_solver: EigSolverOptions = eig_solver
|
29
32
|
|
30
33
|
# Anchor matrices
|
@@ -53,13 +56,25 @@ class LaplacianKernel(OnlineKernel):
|
|
53
56
|
self.a_r = torch.sum(self.A, dim=-1) # [n]
|
54
57
|
self.b_r = torch.zeros_like(self.a_r) # [n]
|
55
58
|
|
56
|
-
def
|
59
|
+
def _affinity(self, features: torch.Tensor) -> torch.Tensor:
|
57
60
|
B = affinity_from_features(
|
58
61
|
self.anchor_features, # [n x d]
|
59
62
|
features, # [m x d]
|
60
63
|
affinity_focal_gamma=self.affinity_focal_gamma,
|
61
64
|
distance=self.distance,
|
62
65
|
) # [n x m]
|
66
|
+
if self.adaptive_scaling:
|
67
|
+
diagonal = (
|
68
|
+
einops.rearrange(B, "n m -> m 1 n") # [m x 1 x n]
|
69
|
+
@ self.Ainv # [n x n]
|
70
|
+
@ einops.rearrange(B, "n m -> m n 1") # [m x n x 1]
|
71
|
+
).squeeze(1, 2) # [m]
|
72
|
+
adaptive_scale = diagonal ** -0.5 # [m]
|
73
|
+
B = B * adaptive_scale
|
74
|
+
return B # [n x m]
|
75
|
+
|
76
|
+
def update(self, features: torch.Tensor) -> torch.Tensor:
|
77
|
+
B = self._affinity(features) # [n x m]
|
63
78
|
b_r = torch.sum(B, dim=-1) # [n]
|
64
79
|
b_c = torch.sum(B, dim=-2) # [m]
|
65
80
|
self.b_r = self.b_r + b_r # [n]
|
@@ -75,12 +90,7 @@ class LaplacianKernel(OnlineKernel):
|
|
75
90
|
B = self.A # [n x n]
|
76
91
|
col_sum = row_sum # [n]
|
77
92
|
else:
|
78
|
-
B =
|
79
|
-
self.anchor_features, # [n x d]
|
80
|
-
features, # [m x d]
|
81
|
-
affinity_focal_gamma=self.affinity_focal_gamma,
|
82
|
-
distance=self.distance,
|
83
|
-
) # [n x m]
|
93
|
+
B = self._affinity(features)
|
84
94
|
b_c = torch.sum(B, dim=-2) # [m]
|
85
95
|
col_sum = b_c + B.mT @ self.Ainv @ self.b_r # [m]
|
86
96
|
scale = (row_sum[:, None] * col_sum) ** -0.5 # [n x m]
|
@@ -94,8 +104,9 @@ class NCut(OnlineNystromSubsampleFit):
|
|
94
104
|
self,
|
95
105
|
n_components: int = 100,
|
96
106
|
affinity_focal_gamma: float = 1.0,
|
97
|
-
sample_config: SampleConfig = SampleConfig(),
|
98
107
|
distance: DistanceOptions = "cosine",
|
108
|
+
adaptive_scaling: bool = True,
|
109
|
+
sample_config: SampleConfig = SampleConfig(),
|
99
110
|
eig_solver: EigSolverOptions = "svd_lowrank",
|
100
111
|
chunk_size: int = 8192,
|
101
112
|
):
|
@@ -104,16 +115,17 @@ class NCut(OnlineNystromSubsampleFit):
|
|
104
115
|
n_components (int): number of top eigenvectors to return
|
105
116
|
affinity_focal_gamma (float): affinity matrix temperature, lower t reduce the not-so-connected edge weights,
|
106
117
|
smaller t result in more sharp eigenvectors.
|
118
|
+
distance (str): distance metric for affinity matrix, ['cosine', 'euclidean', 'rbf'].
|
119
|
+
adaptive_scaling (bool): whether to scale off-diagonal affinity vectors so extended diagonal equals 1
|
107
120
|
sample_config (str): subgraph sampling, ['farthest', 'random'].
|
108
121
|
farthest point sampling is recommended for better Nystrom-approximation accuracy
|
109
|
-
distance (str): distance metric for affinity matrix, ['cosine', 'euclidean', 'rbf'].
|
110
122
|
eig_solver (str): eigen decompose solver, ['svd_lowrank', 'lobpcg', 'svd', 'eigh'].
|
111
123
|
chunk_size (int): chunk size for large-scale matrix multiplication
|
112
124
|
"""
|
113
125
|
OnlineNystromSubsampleFit.__init__(
|
114
126
|
self,
|
115
127
|
n_components=n_components,
|
116
|
-
kernel=LaplacianKernel(affinity_focal_gamma, distance, eig_solver),
|
128
|
+
kernel=LaplacianKernel(affinity_focal_gamma, distance, adaptive_scaling, eig_solver),
|
117
129
|
distance=distance,
|
118
130
|
sample_config=sample_config,
|
119
131
|
eig_solver=eig_solver,
|
@@ -20,7 +20,7 @@ EigSolverOptions = Literal["svd_lowrank", "lobpcg", "svd", "eigh"]
|
|
20
20
|
|
21
21
|
|
22
22
|
class OnlineKernel:
|
23
|
-
def fit(self, features: torch.Tensor) ->
|
23
|
+
def fit(self, features: torch.Tensor) -> "OnlineKernel": # [n x d]
|
24
24
|
raise NotImplementedError()
|
25
25
|
|
26
26
|
def update(self, features: torch.Tensor) -> torch.Tensor: # [m x d] -> [m x n]
|
@@ -47,7 +47,6 @@ class OnlineNystrom:
|
|
47
47
|
self.n_components: int = n_components
|
48
48
|
self.kernel: OnlineKernel = kernel
|
49
49
|
self.eig_solver: EigSolverOptions = eig_solver
|
50
|
-
self.inverse_approximation_dim: int = None
|
51
50
|
|
52
51
|
self.chunk_size = chunk_size
|
53
52
|
|
@@ -61,13 +60,13 @@ class OnlineNystrom:
|
|
61
60
|
# Updated matrices
|
62
61
|
self.S: torch.Tensor = None # [n x n]
|
63
62
|
self.transform_matrix: torch.Tensor = None # [n x n_components]
|
64
|
-
self.
|
63
|
+
self.eigenvalues_: torch.Tensor = None # [n]
|
65
64
|
|
66
|
-
def _update_to_kernel(self) -> Tuple[torch.Tensor, torch.Tensor]:
|
65
|
+
def _update_to_kernel(self, d: int) -> Tuple[torch.Tensor, torch.Tensor]:
|
67
66
|
self.A = self.S = self.kernel.transform()
|
68
67
|
U, L = solve_eig(
|
69
68
|
self.A,
|
70
|
-
num_eig=
|
69
|
+
num_eig=d + 1, # d * (d + 3) // 2 + 1,
|
71
70
|
eig_solver=self.eig_solver,
|
72
71
|
) # [n x (? + 1)], [? + 1]
|
73
72
|
self.Ahinv_UL = U * (L ** -0.5) # [n x (? + 1)]
|
@@ -75,57 +74,57 @@ class OnlineNystrom:
|
|
75
74
|
self.Ahinv = self.Ahinv_UL @ self.Ahinv_VT # [n x n]
|
76
75
|
return U, L
|
77
76
|
|
78
|
-
def fit(self, features: torch.Tensor):
|
77
|
+
def fit(self, features: torch.Tensor) -> "OnlineNystrom":
|
79
78
|
OnlineNystrom.fit_transform(self, features)
|
80
79
|
return self
|
81
80
|
|
82
|
-
def fit_transform(self, features: torch.Tensor) ->
|
81
|
+
def fit_transform(self, features: torch.Tensor) -> torch.Tensor:
|
83
82
|
self.anchor_features = features
|
84
83
|
|
85
84
|
self.kernel.fit(self.anchor_features)
|
86
|
-
|
87
|
-
U, L = self._update_to_kernel() # [n x (? + 1)], [? + 1]
|
85
|
+
U, L = self._update_to_kernel(features.shape[-1]) # [n x (d + 1)], [d + 1]
|
88
86
|
|
89
87
|
self.transform_matrix = (U / L)[:, :self.n_components] # [n x n_components]
|
90
|
-
self.
|
91
|
-
return U[:, :self.n_components]
|
88
|
+
self.eigenvalues_ = L[:self.n_components] # [n_components]
|
89
|
+
return U[:, :self.n_components] # [n x n_components]
|
92
90
|
|
93
|
-
def update(self, features: torch.Tensor) ->
|
91
|
+
def update(self, features: torch.Tensor) -> torch.Tensor:
|
92
|
+
d = features.shape[-1]
|
94
93
|
n_chunks = ceildiv(len(features), self.chunk_size)
|
95
94
|
if n_chunks > 1:
|
96
95
|
""" Chunked version """
|
97
96
|
chunks = torch.chunk(features, n_chunks, dim=0)
|
98
97
|
for chunk in chunks:
|
99
98
|
self.kernel.update(chunk)
|
100
|
-
self._update_to_kernel()
|
99
|
+
self._update_to_kernel(d)
|
101
100
|
|
102
|
-
compressed_BBT =
|
103
|
-
for
|
104
|
-
_B = self.kernel.transform(chunk).mT
|
105
|
-
_compressed_B = self.Ahinv_VT @ _B
|
106
|
-
compressed_BBT = compressed_BBT + _compressed_B @ _compressed_B.mT
|
107
|
-
self.S = self.S + self.Ahinv_UL @ compressed_BBT @ self.Ahinv_UL.mT
|
108
|
-
US, self.
|
109
|
-
self.transform_matrix = self.Ahinv @ US * (self.
|
101
|
+
compressed_BBT = 0.0 # [(? + 1) x (? + 1))]
|
102
|
+
for chunk in chunks:
|
103
|
+
_B = self.kernel.transform(chunk).mT # [n x _m]
|
104
|
+
_compressed_B = self.Ahinv_VT @ _B # [(? + 1) x _m]
|
105
|
+
compressed_BBT = compressed_BBT + _compressed_B @ _compressed_B.mT # [(? + 1) x (? + 1)]
|
106
|
+
self.S = self.S + self.Ahinv_UL @ compressed_BBT @ self.Ahinv_UL.mT # [n x n]
|
107
|
+
US, self.eigenvalues_ = solve_eig(self.S, self.n_components, self.eig_solver) # [n x n_components], [n_components]
|
108
|
+
self.transform_matrix = self.Ahinv @ US * (self.eigenvalues_ ** -0.5) # [n x n_components]
|
110
109
|
|
111
110
|
VS = []
|
112
111
|
for chunk in chunks:
|
113
|
-
VS.append(self.kernel.transform(chunk) @ self.transform_matrix)
|
112
|
+
VS.append(self.kernel.transform(chunk) @ self.transform_matrix) # [_m x n_components]
|
114
113
|
VS = torch.cat(VS, dim=0)
|
115
|
-
return VS
|
114
|
+
return VS # [m x n_components]
|
116
115
|
else:
|
117
116
|
""" Unchunked version """
|
118
|
-
B = self.kernel.update(features).mT
|
119
|
-
self._update_to_kernel()
|
120
|
-
compressed_B = self.Ahinv_VT @ B
|
117
|
+
B = self.kernel.update(features).mT # [n x m]
|
118
|
+
self._update_to_kernel(d)
|
119
|
+
compressed_B = self.Ahinv_VT @ B # [indirect_pca_dim x m]
|
121
120
|
|
122
|
-
self.S = self.S + self.Ahinv_UL @ (compressed_B @ compressed_B.mT) @ self.Ahinv_UL.mT
|
123
|
-
US, self.
|
124
|
-
self.transform_matrix = self.Ahinv @ US * (self.
|
121
|
+
self.S = self.S + self.Ahinv_UL @ (compressed_B @ compressed_B.mT) @ self.Ahinv_UL.mT # [n x n]
|
122
|
+
US, self.eigenvalues_ = solve_eig(self.S, self.n_components, self.eig_solver) # [n x n_components], [n_components]
|
123
|
+
self.transform_matrix = self.Ahinv @ US * (self.eigenvalues_ ** -0.5) # [n x n_components]
|
125
124
|
|
126
|
-
return B.mT @ self.transform_matrix
|
125
|
+
return B.mT @ self.transform_matrix # [m x n_components]
|
127
126
|
|
128
|
-
def transform(self, features: torch.Tensor = None) ->
|
127
|
+
def transform(self, features: torch.Tensor = None) -> torch.Tensor:
|
129
128
|
if features is None:
|
130
129
|
VS = self.A @ self.transform_matrix # [n x n_components]
|
131
130
|
else:
|
@@ -135,12 +134,12 @@ class OnlineNystrom:
|
|
135
134
|
chunks = torch.chunk(features, n_chunks, dim=0)
|
136
135
|
VS = []
|
137
136
|
for chunk in chunks:
|
138
|
-
VS.append(self.kernel.transform(chunk) @ self.transform_matrix)
|
137
|
+
VS.append(self.kernel.transform(chunk) @ self.transform_matrix) # [_m x n_components]
|
139
138
|
VS = torch.cat(VS, dim=0)
|
140
139
|
else:
|
141
140
|
""" Unchunked version """
|
142
|
-
VS = self.kernel.transform(features) @ self.transform_matrix
|
143
|
-
return VS
|
141
|
+
VS = self.kernel.transform(features) @ self.transform_matrix # [m x n_components]
|
142
|
+
return VS # [m x n_components]
|
144
143
|
|
145
144
|
|
146
145
|
class OnlineNystromSubsampleFit(OnlineNystrom):
|
@@ -192,7 +191,7 @@ class OnlineNystromSubsampleFit(OnlineNystrom):
|
|
192
191
|
if _n_not_sampled > 0:
|
193
192
|
unsampled_indices = torch.full((_n,), True, device=features.device).scatter_(0, self.anchor_indices, False)
|
194
193
|
unsampled_features = features[unsampled_indices]
|
195
|
-
V_unsampled
|
194
|
+
V_unsampled = OnlineNystrom.update(self, unsampled_features)
|
196
195
|
else:
|
197
196
|
unsampled_indices = V_unsampled = None
|
198
197
|
return unsampled_indices, V_unsampled
|
@@ -201,7 +200,7 @@ class OnlineNystromSubsampleFit(OnlineNystrom):
|
|
201
200
|
self,
|
202
201
|
features: torch.Tensor,
|
203
202
|
precomputed_sampled_indices: torch.Tensor = None,
|
204
|
-
):
|
203
|
+
) -> "OnlineNystromSubsampleFit":
|
205
204
|
"""Fit Nystrom Normalized Cut on the input features.
|
206
205
|
Args:
|
207
206
|
features (torch.Tensor): input features, shape (n_samples, n_features)
|
@@ -217,7 +216,7 @@ class OnlineNystromSubsampleFit(OnlineNystrom):
|
|
217
216
|
self,
|
218
217
|
features: torch.Tensor,
|
219
218
|
precomputed_sampled_indices: torch.Tensor = None,
|
220
|
-
) ->
|
219
|
+
) -> torch.Tensor:
|
221
220
|
"""
|
222
221
|
Args:
|
223
222
|
features (torch.Tensor): input features, shape (n_samples, n_features)
|
@@ -229,7 +228,7 @@ class OnlineNystromSubsampleFit(OnlineNystrom):
|
|
229
228
|
(torch.Tensor): eigen_values, sorted in descending order, shape (num_eig,)
|
230
229
|
"""
|
231
230
|
unsampled_indices, V_unsampled = OnlineNystromSubsampleFit._fit_helper(self, features, precomputed_sampled_indices)
|
232
|
-
V_sampled
|
231
|
+
V_sampled = OnlineNystrom.transform(self)
|
233
232
|
|
234
233
|
if unsampled_indices is not None:
|
235
234
|
V = torch.zeros((len(unsampled_indices), self.n_components), device=features.device)
|
@@ -237,7 +236,7 @@ class OnlineNystromSubsampleFit(OnlineNystrom):
|
|
237
236
|
V[unsampled_indices] = V_unsampled
|
238
237
|
else:
|
239
238
|
V = V_sampled
|
240
|
-
return V
|
239
|
+
return V
|
241
240
|
|
242
241
|
|
243
242
|
def solve_eig(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: nystrom_ncut
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: Normalized Cut and Nyström Approximation
|
5
5
|
Author-email: Huzheng Yang <huze.yann@gmail.com>, Wentinn Liao <wentinn.liao@gmail.com>
|
6
6
|
Project-URL: Documentation, https://github.com/JophiArcana/Nystrom-NCUT/
|
@@ -0,0 +1,15 @@
|
|
1
|
+
__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
nystrom_ncut/__init__.py,sha256=HifrTcqX2-hYjBDe6xIThHvuIBYMPBA3EzjR8-qPMUM,512
|
3
|
+
nystrom_ncut/common.py,sha256=_PGJoImSk_Fb_5Ri-e_IsFoCcSfbGS8CxYUUHVoNM50,2036
|
4
|
+
nystrom_ncut/distance_utils.py,sha256=p-pYdpRrJsIhzxM_IxUqja7N8okngx52WGXD9pu_Aec,3129
|
5
|
+
nystrom_ncut/sampling_utils.py,sha256=oMmhFcd_N_D15Ht7F0rCGPSgLeitJszAKMD3ICKwHNU,3105
|
6
|
+
nystrom_ncut/visualize_utils.py,sha256=RsQVjPhxoIdxDOQ2PI7ifFDuEL23YXpZBdJ0wjjafek,22970
|
7
|
+
nystrom_ncut/nystrom/__init__.py,sha256=4EpxD3Cmc8Fif4vo8DG-6FpTfCnNanD5zCZxK3WrMwQ,121
|
8
|
+
nystrom_ncut/nystrom/distance_realization.py,sha256=InajllGtRVnLVlZoipZNbHFTGHaTs3zxizKe3kI2Los,5815
|
9
|
+
nystrom_ncut/nystrom/normalized_cut.py,sha256=N-M5wkTo59vpbBfIx8evkSQBxlo4j80qCtuoifxQa_A,7578
|
10
|
+
nystrom_ncut/nystrom/nystrom_utils.py,sha256=UVs1tC7vnVq2mWSTpcrP4C19x9wDJ77ACht0EltOO2E,12698
|
11
|
+
nystrom_ncut-0.1.6.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
|
12
|
+
nystrom_ncut-0.1.6.dist-info/METADATA,sha256=DfH6Ylr79RYc0JiYkDpz0kv08RxSP73dBhK8TVJSUfE,6058
|
13
|
+
nystrom_ncut-0.1.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
14
|
+
nystrom_ncut-0.1.6.dist-info/top_level.txt,sha256=gM8IWWHYysIRTCvCTcdS4RShOyl9pxpylgSwPUZR2XM,22
|
15
|
+
nystrom_ncut-0.1.6.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
nystrom_ncut/__init__.py,sha256=HifrTcqX2-hYjBDe6xIThHvuIBYMPBA3EzjR8-qPMUM,512
|
3
|
-
nystrom_ncut/common.py,sha256=_PGJoImSk_Fb_5Ri-e_IsFoCcSfbGS8CxYUUHVoNM50,2036
|
4
|
-
nystrom_ncut/distance_utils.py,sha256=wEXyKxkLv9VvF5xn42ypiwUAAq9xTh3RmMvdHhFuPms,3127
|
5
|
-
nystrom_ncut/sampling_utils.py,sha256=oMmhFcd_N_D15Ht7F0rCGPSgLeitJszAKMD3ICKwHNU,3105
|
6
|
-
nystrom_ncut/visualize_utils.py,sha256=RsQVjPhxoIdxDOQ2PI7ifFDuEL23YXpZBdJ0wjjafek,22970
|
7
|
-
nystrom_ncut/nystrom/__init__.py,sha256=4EpxD3Cmc8Fif4vo8DG-6FpTfCnNanD5zCZxK3WrMwQ,121
|
8
|
-
nystrom_ncut/nystrom/distance_realization.py,sha256=9GX_XSISTvsEWUu8bG5AxtlkYYNItFspcH5wXiwSOKY,5789
|
9
|
-
nystrom_ncut/nystrom/normalized_cut.py,sha256=ZxFV8Sckp6wtpNyoA15DS7Vfu9QLvzNpwrwY0n9_GNs,6953
|
10
|
-
nystrom_ncut/nystrom/nystrom_utils.py,sha256=Wq364xlxBhr74lqyCkPWLBxq5YSt2zr-DSfYUHpYfgE,12989
|
11
|
-
nystrom_ncut-0.1.4.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
|
12
|
-
nystrom_ncut-0.1.4.dist-info/METADATA,sha256=lVURVQRK6krrpu6iUvDdX0-I5FD7mHFIK_uQjzHlxhU,6058
|
13
|
-
nystrom_ncut-0.1.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
14
|
-
nystrom_ncut-0.1.4.dist-info/top_level.txt,sha256=gM8IWWHYysIRTCvCTcdS4RShOyl9pxpylgSwPUZR2XM,22
|
15
|
-
nystrom_ncut-0.1.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|