-
Notifications
You must be signed in to change notification settings - Fork 0
/
som_topol_struct
executable file
·81 lines (62 loc) · 2.1 KB
/
som_topol_struct
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
74
75
76
77
78
79
80
81
class som_topol_struct:
def __init__(self, dlen=[], data=[], munits=[], msize=mat(""),lattice="",mapshape="", topol=[]):
self.type="som_topol"
self.msize=msize #needs to be a 2x1 matrix
self.lattice=lattice
self.mapshape=mapshape
if data==[]:
D=mat("")
dim=2
else:
D=data.data #elements must be formatted as float, or this won't work right
dlen=D.shape[0]
dim=D.shape[1]
if lattice=="":
self.lattice="hexa"
if mapshape=="":
self.mapshape="sheet"
#if necessary determine the number of map units
if munits==[]:
if dlen!=[]:
munits=ceil(5 * sqrt(dlen) )
else:
munits=100.0
#then determine the map size
if msize.shape[1]==0:
self.msize=mat("0 0")
if dim==1: #one dimensional data
self.msize[0,0]=1
self.msize[0,1]=ceil(munits)
elif D.shape[0] < 2: #no data provided, determine msize using munits
self.msize[0,0]=round(sqrt(munits))
self.msize[0,1]=round(munits/self.msize[0,0])
else: #determine a map size based on eigenvalues.
#initialize xdim/ydim ratio using principal components of the input space;
#the ratio is the square root of two largest eigenvalues
A=zeros((dim,dim))+Inf #autocorrelation matrix
for i in range(0,dim):
mean= D[:,i].sum(0)/D[:,i].shape[0]
D[:,i]=D[:,i]-mean
for i in range(0,dim):
for j in range(i,dim):
c=multiply(D[:,i],D[:,j] )
A[i,j]=float(sum(c))/c.shape[0]
A[j,i]=A[i,j]
S,V=linalg.eig(A)
I=argsort(S)
eigval=S[I,:]
if eigval[-1]==0 or eigval[-2]*munits<eigval[-1]:
ratio=1.0
else:
ratio = sqrt(eigval[-1]/eigval[-2]) #ratio between xdim and ydim
if self.lattice=="hexa":
self.msize[0,1]=min(munits, round( sqrt(munits/ratio * sqrt(0.75))) )
else:
self.msize[0,1]=min(munits, round(sqrt(munits/ratio)))
self.msize[0,0]=round(munits/self.msize[0,1])
if min(self.msize)==1:
self.msize[0,0]=1
self.msize[0,1]=max(self.msize)
if self.lattice=="hexa" and self.mapshape=="toroid":
if self.msize[0,0]%2 ==1:
self.msize[0,0]=self.msize[0,0]+1