I am trying to implement a Laplacian custom map algorithm, which consists of:
1) plot the graph (I use kNN and say that there is an edge to k closest neighbors)
2) tie each rib to the weight
3) determine the diagonal (which is the sum of the line located diagonally)
4) perform the generalized eigendecomposition function (which should be Lv = lambdaDv, where L and D are calculated in the code below)
I think that this can be somehow solved with scipy.linalg.eig (vals), but I don’t understand how to correctly enter my two matrices. Can someone help me in understanding how to perform the generalized eigendecomposition step?
import numpy as np
import random as r
from math import exp as exp
from scipy.spatial import distance
def rweights((vectors,features)):
return 1 * np.random.random_sample((vectors,features)) - 0
def vEuclidean(v, m):
return np.apply_along_axis(lambda x: distance.euclidean(v,x), 1, m)
def mEuclideans(m):
return np.apply_along_axis(lambda v: vEuclidean(v,m), 1, m)
def neighbours(vector, neigh):
size = (vector.shape[0] - neigh)
for i in range(1,size):
vector[np.argmax(vector)] = 0.0
return vector
def kNN(m, k):
me = mEuclideans(m)
return np.array(map(lambda v: neighbours(v, k), me))
def diag(m):
sums = np.sum(m,1)
(vectors,features) = m.shape
zeros = np.zeros(vectors*features).reshape((vectors,features))
for i in range(features):
zeros[i][i] = sums[i]
return zeros
def vectorWeight(v, sigma):
f = lambda x: exp((-(x)/(sigma**2)))
size = v.shape[0]
for i in range(size):
v[i] = f(v[i])
return v
def weight(m):
return np.array(np.apply_along_axis(lambda v: vectorWeight(v,0.5), 1, m))
if __name__ == "__main__":
np.random.seed(666)
m = rweights((5,3))
w = weight(kNN(m, 2))
D = diag(w)
L = D-w