-
Notifications
You must be signed in to change notification settings - Fork 32
/
GeomUtils.py
73 lines (68 loc) · 2.57 KB
/
GeomUtils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import numpy as np
def getSSM(X):
"""
Compute a Euclidean self-similarity image between a set of points
:param X: An Nxd matrix holding the d coordinates of N points
:return: An NxN self-similarity matrix
"""
D = np.sum(X**2, 1)[:, None]
D = D + D.T - 2*X.dot(X.T)
D[D < 0] = 0
D = 0.5*(D + D.T)
D = np.sqrt(D)
return D
def getW(D, K, Mu = 0.5):
"""
Return affinity matrix
[1] Wang, Bo, et al. "Similarity network fusion for aggregating data types on a genomic scale."
Nature methods 11.3 (2014): 333-337.
:param D: Self-similarity matrix
:param K: Number of nearest neighbors
"""
#W(i, j) = exp(-Dij^2/(mu*epsij))
DSym = 0.5*(D + D.T)
np.fill_diagonal(DSym, 0)
Neighbs = np.partition(DSym, K+1, 1)[:, 0:K+1]
MeanDist = np.mean(Neighbs, 1)*float(K+1)/float(K) #Need this scaling
#to exclude diagonal element in mean
#Equation 1 in SNF paper [1] for estimating local neighborhood radii
#by looking at k nearest neighbors, not including point itself
Eps = MeanDist[:, None] + MeanDist[None, :] + DSym
Eps = Eps/3
W = np.exp(-DSym**2/(2*(Mu*Eps)**2))
return W
def getCSM(X, Y):
"""
Return the Euclidean cross-similarity matrix between the M points
in the Mxd matrix X and the N points in the Nxd matrix Y.
:param X: An Mxd matrix holding the coordinates of M points
:param Y: An Nxd matrix holding the coordinates of N points
:return D: An MxN Euclidean cross-similarity matrix
"""
C = np.sum(X**2, 1)[:, None] + np.sum(Y**2, 1)[None, :] - 2*X.dot(Y.T)
C[C < 0] = 0
return np.sqrt(C)
def getGreedyPerm(X, M, Verbose = False):
"""
Purpose: Naive O(NM) algorithm to do the greedy permutation
:param X: Nxd array of Euclidean points
:param M: Number of points in returned permutation
:returns: (permutation (N-length array of indices), \
lambdas (N-length array of insertion radii))
"""
#By default, takes the first point in the list to be the
#first point in the permutation, but could be random
perm = np.zeros(M, dtype=np.int64)
lambdas = np.zeros(M)
ds = getCSM(X[0, :][None, :], X).flatten()
for i in range(1, M):
idx = np.argmax(ds)
perm[i] = idx
lambdas[i] = ds[idx]
ds = np.minimum(ds, getCSM(X[idx, :][None, :], X).flatten())
if Verbose:
interval = int(0.05*M)
if i%interval == 0:
print("Greedy perm %i%s done..."%(int(100.0*i/float(M)), "%"))
Y = X[perm, :]
return {'Y':Y, 'perm':perm, 'lambdas':lambdas}