Revisão | 3a9fb5caa578dbd583d5c63ef9c2ec4f347dd921 (tree) |
---|---|
Hora | 2011-03-04 09:23:51 |
Autor | lorenzo |
Commiter | lorenzo |
This code combines two clusters into a new one.
@@ -0,0 +1,302 @@ | ||
1 | +#! /usr/bin/env python | |
2 | + | |
3 | +from enthought.mayavi import mlab | |
4 | + | |
5 | +import scipy as s | |
6 | +import numpy as n | |
7 | +import scipy.spatial as sp | |
8 | + | |
9 | +import scipy.linalg as sl | |
10 | + | |
11 | + | |
12 | +import sys | |
13 | + | |
14 | + | |
15 | +def random_rot(): | |
16 | + theta=s.arccos(1.-2.*s.random.uniform(0.,1.,1)[0])-s.pi/2. | |
17 | + phi=s.random.uniform(-s.pi,s.pi,1)[0] | |
18 | + psi=s.random.uniform(-s.pi,s.pi,1)[0] | |
19 | + | |
20 | + | |
21 | + oneone=s.cos(theta)*s.cos(psi) | |
22 | + onetwo=-s.cos(phi)*s.sin(psi)+s.sin(phi)*s.sin(theta)*s.cos(psi) | |
23 | + onethree=s.sin(phi)*s.sin(psi)+s.cos(phi)*s.sin(theta)*s.cos(psi) | |
24 | + | |
25 | + twoone= s.cos(theta)*s.sin(psi) | |
26 | + twotwo=s.cos(phi)*s.cos(psi)+s.sin(phi)*s.sin(theta)*s.sin(psi) | |
27 | + twothree=-s.sin(phi)*s.cos(psi)+s.cos(phi)*s.sin(theta)*s.sin(psi) | |
28 | + | |
29 | + threeone=-s.sin(theta) | |
30 | + threetwo=s.sin(phi)*s.cos(theta) | |
31 | + threethree=s.cos(phi)*s.cos(theta) | |
32 | + | |
33 | + | |
34 | + my_mat=s.zeros(9).reshape((3,3)) | |
35 | + | |
36 | + my_mat[0,0]=oneone | |
37 | + my_mat[0,1]=onetwo | |
38 | + my_mat[0,2]=onethree | |
39 | + | |
40 | + my_mat[1,0]=twoone | |
41 | + my_mat[1,1]=twotwo | |
42 | + my_mat[1,2]=twothree | |
43 | + | |
44 | + my_mat[2,0]=threeone | |
45 | + my_mat[2,1]=threetwo | |
46 | + my_mat[2,2]=threethree | |
47 | + | |
48 | + return my_mat | |
49 | + | |
50 | + | |
51 | + | |
52 | +def accept_reject_rotation(cluster_1, cluster_2, epsi): | |
53 | + | |
54 | + while(True): | |
55 | + random_rot_mat= random_rot() | |
56 | + n_row_col=s.shape(cluster_1) | |
57 | + | |
58 | + cluster_rot=s.zeros(s.prod(n_row_col)).reshape((n_row_col[0],\ | |
59 | + n_row_col[1])) | |
60 | + | |
61 | + for i in s.arange(n_row_col[0]): | |
62 | + | |
63 | + cluster_rot[i,:]=s.dot(random_rot_mat, cluster_1[i,:]) | |
64 | + | |
65 | + | |
66 | + dist_list = euclidean_distances(cluster_rot, cluster_2) | |
67 | + | |
68 | + | |
69 | + | |
70 | + # print "dist_list is, ", dist_list | |
71 | + | |
72 | + | |
73 | + # if (not (dist_list < (2.-epsi)).any()) and \ | |
74 | + if (not (dist_list < 2.).any()) and \ | |
75 | + (dist_list<=(2.+epsi)).any(): | |
76 | + cluster_new=s.vstack((cluster_rot, cluster_2)) | |
77 | + | |
78 | + return cluster_new | |
79 | + | |
80 | + | |
81 | + | |
82 | + | |
83 | + | |
84 | + | |
85 | + | |
86 | + | |
87 | + | |
88 | + | |
89 | +def euclidean_distances(X, Y, Y_norm_squared=None, squared=False): | |
90 | + """ | |
91 | +Considering the rows of X (and Y=X) as vectors, compute the | |
92 | +distance matrix between each pair of vectors. | |
93 | + | |
94 | +Parameters | |
95 | +---------- | |
96 | +X: array of shape (n_samples_1, n_features) | |
97 | + | |
98 | +Y: array of shape (n_samples_2, n_features) | |
99 | + | |
100 | +Y_norm_squared: array [n_samples_2], optional | |
101 | +pre-computed (Y**2).sum(axis=1) | |
102 | + | |
103 | +squared: boolean, optional | |
104 | +This routine will return squared Euclidean distances instead. | |
105 | + | |
106 | +Returns | |
107 | +------- | |
108 | +distances: array of shape (n_samples_1, n_samples_2) | |
109 | + | |
110 | +Examples | |
111 | +-------- | |
112 | +>>> from scikits.learn.metrics.pairwise import euclidean_distances | |
113 | +>>> X = [[0, 1], [1, 1]] | |
114 | +>>> # distrance between rows of X | |
115 | +>>> euclidean_distances(X, X) | |
116 | +array([[ 0., 1.], | |
117 | +[ 1., 0.]]) | |
118 | +>>> # get distance to origin | |
119 | +>>> euclidean_distances(X, [[0, 0]]) | |
120 | +array([[ 1. ], | |
121 | +[ 1.41421356]]) | |
122 | +""" | |
123 | + # should not need X_norm_squared because if you could precompute that as | |
124 | + # well as Y, then you should just pre-compute the output and not even | |
125 | + # call this function. | |
126 | + if X is Y: | |
127 | + X = Y = n.asanyarray(X) | |
128 | + else: | |
129 | + X = n.asanyarray(X) | |
130 | + Y = n.asanyarray(Y) | |
131 | + | |
132 | + if X.shape[1] != Y.shape[1]: | |
133 | + raise ValueError("Incompatible dimension for X and Y matrices") | |
134 | + | |
135 | + XX = n.sum(X * X, axis=1)[:, n.newaxis] | |
136 | + if X is Y: # shortcut in the common case euclidean_distances(X, X) | |
137 | + YY = XX.T | |
138 | + elif Y_norm_squared is None: | |
139 | + YY = Y.copy() | |
140 | + YY **= 2 | |
141 | + YY = n.sum(YY, axis=1)[n.newaxis, :] | |
142 | + else: | |
143 | + YY = n.asanyarray(Y_norm_squared) | |
144 | + if YY.shape != (Y.shape[0],): | |
145 | + raise ValueError("Incompatible dimension for Y and Y_norm_squared") | |
146 | + YY = YY[n.newaxis, :] | |
147 | + | |
148 | + # TODO: | |
149 | + # a faster cython implementation would do the dot product first, | |
150 | + # and then add XX, add YY, and do the clipping of negative values in | |
151 | + # a single pass over the output matrix. | |
152 | + distances = XX + YY # Using broadcasting | |
153 | + distances -= 2 * n.dot(X, Y.T) | |
154 | + distances = n.maximum(distances, 0) | |
155 | + if squared: | |
156 | + return distances | |
157 | + else: | |
158 | + return n.sqrt(distances) | |
159 | + | |
160 | +euclidian_distances = euclidean_distances # both spelling for backward compat | |
161 | + | |
162 | + | |
163 | +def find_CM(cluster): | |
164 | + CM=s.mean(cluster, axis=0) | |
165 | + return CM | |
166 | + | |
167 | + | |
168 | +def relocate_cluster(cluster): | |
169 | + cluster_shift=find_CM(cluster) | |
170 | + cluster[:,0]=cluster[:,0]-cluster_shift[0] | |
171 | + cluster[:,1]=cluster[:,1]-cluster_shift[1] | |
172 | + cluster[:,2]=cluster[:,2]-cluster_shift[2] | |
173 | + | |
174 | + return cluster | |
175 | + | |
176 | +def dist_gamma_clusters(cluster_1, cluster_2, kf, df): | |
177 | + N1=s.shape(cluster_1)[0]*1. | |
178 | + N2=s.shape(cluster_2)[0]*1. | |
179 | + | |
180 | + print "N1 and N2 are, ", N1, N2 | |
181 | + | |
182 | + R1sq=s.var(cluster_1[:,0])+s.var(cluster_1[:,1])+\ | |
183 | + s.var(cluster_1[:,2]) +1. | |
184 | + R2sq=s.var(cluster_2[:,0])+s.var(cluster_2[:,1])+\ | |
185 | + s.var(cluster_2[:,2]) +1. | |
186 | + R1=s.sqrt(R1sq) | |
187 | + R2=s.sqrt(R2sq) | |
188 | + | |
189 | + print "R1 is, ", R1 | |
190 | + print "R2 is, ", R2 | |
191 | + | |
192 | + gamma_sq=((N1+N2)**2.)/(N1*N2)*((N1+N2)/kf)**(2./df)\ | |
193 | + -(N1+N2)/N2*(R1**2.)-(N1+N2)/N1*(R2**2.) | |
194 | + | |
195 | + a=((N1+N2)**2.)/(N1*N2)*((N1+N2)/kf)**(2./df) | |
196 | + b=(N1+N2)/N2*R1**2. | |
197 | + c=(N1+N2)/N1*R2**2. | |
198 | + | |
199 | + print "a,b,c are, ", a,b,c | |
200 | + | |
201 | + print "gamma_sq is, ", gamma_sq | |
202 | + | |
203 | + my_gamma=s.sqrt(gamma_sq) | |
204 | + return my_gamma | |
205 | + | |
206 | + | |
207 | + | |
208 | +kf=1.3 | |
209 | +df= 1.8 # 1.8 | |
210 | +epsi=0.01 | |
211 | + | |
212 | + | |
213 | +cluster_1=n.loadtxt("aggregate_number_21_.dat") | |
214 | + | |
215 | +cluster_1=relocate_cluster(cluster_1) | |
216 | + | |
217 | +cm1=find_CM(cluster_1) | |
218 | + | |
219 | +print "cm1 is, ", cm1 | |
220 | + | |
221 | +print "cluster_1 is, ", cluster_1 | |
222 | + | |
223 | +cluster_2=n.loadtxt("aggregate_number_87_.dat") | |
224 | + | |
225 | + | |
226 | +cluster_2=relocate_cluster(cluster_2) | |
227 | + | |
228 | + | |
229 | +print "cluster_2 is, ", cluster_2 | |
230 | + | |
231 | + | |
232 | +gamma=dist_gamma_clusters(cluster_1, cluster_2, kf, df) | |
233 | + | |
234 | +print "gamma is, ", gamma | |
235 | + | |
236 | + | |
237 | +cluster_2[:,0]=cluster_2[:,0]+gamma | |
238 | + | |
239 | + | |
240 | +cm2=find_CM(cluster_2) | |
241 | + | |
242 | +print "cm2 is, ", cm2 | |
243 | + | |
244 | + | |
245 | +list_dist=euclidean_distances(cluster_1, cluster_2) | |
246 | + | |
247 | +print "len(list_dist) is, ", s.prod(s.shape(list_dist)) | |
248 | + | |
249 | +print "list_dist is, ", list_dist | |
250 | + | |
251 | + | |
252 | +# x=cluster_2[:,0] | |
253 | +# y=cluster_2[:,1] | |
254 | +# z=cluster_2[:,2] | |
255 | + | |
256 | + | |
257 | +# mlab.clf() | |
258 | +# pts = mlab.points3d(x, y, z, scale_mode='none', resolution=20,\ | |
259 | +# color=(0,0,1),scale_factor=2.) | |
260 | +# #mlab.axes(pts) | |
261 | + | |
262 | +# mlab.show() | |
263 | + | |
264 | + | |
265 | +my_rot=random_rot() | |
266 | + | |
267 | +mat_calc=s.dot( my_rot,s.transpose(my_rot)) | |
268 | + | |
269 | +my_det=sl.det(my_rot) | |
270 | + | |
271 | +print "mat_calc is, ", mat_calc | |
272 | + | |
273 | +print "my_det is, ", my_det | |
274 | + | |
275 | +cluster_agglomerate=accept_reject_rotation(cluster_1, cluster_2, epsi) | |
276 | + | |
277 | +n.savetxt("aggregate_agglomerate.dat", cluster_agglomerate) | |
278 | + | |
279 | + | |
280 | +x=cluster_agglomerate[:,0] | |
281 | +y=cluster_agglomerate[:,1] | |
282 | +z=cluster_agglomerate[:,2] | |
283 | + | |
284 | + | |
285 | +mlab.clf() | |
286 | +pts = mlab.points3d(x, y, z, scale_mode='none', resolution=20,\ | |
287 | + color=(0,0,1),scale_factor=2.) | |
288 | +#mlab.axes(pts) | |
289 | + | |
290 | +mlab.show() | |
291 | + | |
292 | + | |
293 | +R1_agg_sq=s.var(cluster_agglomerate[:,0])+s.var(cluster_agglomerate[:,1])+\ | |
294 | + s.var(cluster_agglomerate[:,2]) +1. | |
295 | + | |
296 | +R1_agg=s.sqrt(R1_agg_sq) | |
297 | + | |
298 | +print "R1agg is, ", R1_agg | |
299 | + | |
300 | + | |
301 | + | |
302 | +print "So far so good" |