• R/O
  • SSH

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisão87b2db1ac449e67ede14031d16585d6d8ab11659 (tree)
Hora2012-10-12 07:31:32
AutorLorenzo Isella <lorenzo.isella@gmai...>
CommiterLorenzo Isella

Mensagem de Log

A code to compare analytical and numerical calculation of the projected area of a linear chain with k monomers.

Mudança Sumário

Diff

diff -r 80c68ec48ffe -r 87b2db1ac449 Python-codes/analytic-rotation-linear-chain.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Python-codes/analytic-rotation-linear-chain.py Fri Oct 12 00:31:32 2012 +0200
@@ -0,0 +1,321 @@
1+#!/usr/bin/env python
2+import scipy as s
3+# import pylab as p
4+import numpy as n
5+import sys
6+import string
7+import scipy.linalg as sl
8+
9+
10+def generate_chain(k,radius):
11+
12+ my_mat=s.zeros(3*k).reshape((k,3))
13+ mon_pos=s.arange(k)*radius*2.
14+ my_mat[:,0]=mon_pos
15+ return my_mat
16+
17+
18+def analytical_area(cluster_pro, R):
19+ d=s.sqrt((cluster_pro[0,0]-cluster_pro[1,0])**2.+\
20+ (cluster_pro[0,1]-cluster_pro[1,1])**2.)
21+
22+ # print "d is, ", d
23+
24+ intersection=2.*R**2.*s.arccos(d/(2.*R))-0.5*d*s.sqrt(4.*R**2-d**2.)
25+
26+ res=2.*s.pi*R**2-intersection
27+
28+ return res
29+
30+
31+
32+def analytical_area_chain(cluster_pro, R,k):
33+ d=s.sqrt((cluster_pro[0,0]-cluster_pro[1,0])**2.+\
34+ (cluster_pro[0,1]-cluster_pro[1,1])**2.)
35+
36+ # print "d is, ", d
37+
38+ intersection=2.*R**2.*s.arccos(d/(2.*R))-0.5*d*s.sqrt(4.*R**2-d**2.)
39+
40+ res=k*s.pi*R**2-(k-1)*intersection
41+
42+ return res
43+
44+
45+
46+
47+def montecarlo_calc_rect(N,cluster, radius):
48+
49+ rect=build_rect(cluster, radius)
50+
51+ print "rect is, ", rect
52+
53+ counter=0
54+ for i in xrange(N):
55+ pt=random_in_rect(rect)
56+ counter=counter+accept_reject_point(pt, cluster, radius)
57+
58+ area=rect[2,0]*rect[2,1]
59+ projected_area=area*counter/N
60+ # print "the projected area is, ", projected_area
61+ return projected_area
62+
63+
64+
65+def build_rect(cluster, rmon):
66+ extreme_left_x=min(cluster[:,0])-rmon
67+ extreme_right_x=max(cluster[:,0])+rmon
68+
69+ extreme_lower_y=min(cluster[:,1])-rmon
70+ extreme_upper_y=max(cluster[:,1])+rmon
71+
72+ Lx=abs(extreme_right_x-extreme_left_x)
73+ Ly=abs(extreme_upper_y-extreme_lower_y)
74+
75+ res=s.array([[extreme_left_x, extreme_right_x],\
76+ [extreme_lower_y, extreme_upper_y],\
77+ [Lx,Ly]])
78+ return res
79+
80+
81+
82+
83+def random_in_rect(rect):
84+
85+ x=s.random.uniform(rect[0,0],rect[0,1],1)[0]
86+ y=s.random.uniform(rect[1,0],rect[1,1],1)[0]
87+ res=s.array([[x, y]])
88+ # res=s.vstack((x,y))
89+ return(res)
90+
91+
92+
93+
94+def accept_reject_point(pt, cluster, radius):
95+ distmin=min(s.ravel(euclidean_distances(pt,cluster)))
96+ res=distmin<=radius
97+ return (res)
98+
99+
100+
101+def rotate_cluster(cluster):
102+ random_rot_mat= random_rot()
103+ n_row_col=s.shape(cluster)
104+
105+ cluster_rot=s.zeros(s.prod(n_row_col)).reshape((n_row_col[0],\
106+ n_row_col[1]))
107+
108+ for i in s.arange(n_row_col[0]):
109+
110+ cluster_rot[i,:]=s.dot(random_rot_mat, cluster[i,:])
111+
112+ return cluster_rot
113+
114+
115+def random_rot():
116+ theta=s.arccos(1.-2.*s.random.uniform(0.,1.,1)[0])-s.pi/2.
117+ phi=s.random.uniform(-s.pi,s.pi,1)[0]
118+ psi=s.random.uniform(-s.pi,s.pi,1)[0]
119+
120+
121+ oneone=s.cos(theta)*s.cos(psi)
122+ onetwo=-s.cos(phi)*s.sin(psi)+s.sin(phi)*s.sin(theta)*s.cos(psi)
123+ onethree=s.sin(phi)*s.sin(psi)+s.cos(phi)*s.sin(theta)*s.cos(psi)
124+
125+ twoone= s.cos(theta)*s.sin(psi)
126+ twotwo=s.cos(phi)*s.cos(psi)+s.sin(phi)*s.sin(theta)*s.sin(psi)
127+ twothree=-s.sin(phi)*s.cos(psi)+s.cos(phi)*s.sin(theta)*s.sin(psi)
128+
129+ threeone=-s.sin(theta)
130+ threetwo=s.sin(phi)*s.cos(theta)
131+ threethree=s.cos(phi)*s.cos(theta)
132+
133+
134+ my_mat=s.zeros(9).reshape((3,3))
135+
136+ my_mat[0,0]=oneone
137+ my_mat[0,1]=onetwo
138+ my_mat[0,2]=onethree
139+
140+ my_mat[1,0]=twoone
141+ my_mat[1,1]=twotwo
142+ my_mat[1,2]=twothree
143+
144+ my_mat[2,0]=threeone
145+ my_mat[2,1]=threetwo
146+ my_mat[2,2]=threethree
147+
148+ return my_mat
149+
150+
151+
152+
153+
154+
155+def euclidean_distances(X, Y, Y_norm_squared=None, squared=False):
156+ """
157+Considering the rows of X (and Y=X) as vectors, compute the
158+distance matrix between each pair of vectors.
159+
160+Parameters
161+----------
162+X: array of shape (n_samples_1, n_features)
163+
164+Y: array of shape (n_samples_2, n_features)
165+
166+Y_norm_squared: array [n_samples_2], optional
167+pre-computed (Y**2).sum(axis=1)
168+
169+squared: boolean, optional
170+This routine will return squared Euclidean distances instead.
171+
172+Returns
173+-------
174+distances: array of shape (n_samples_1, n_samples_2)
175+
176+Examples
177+--------
178+>>> from scikits.learn.metrics.pairwise import euclidean_distances
179+>>> X = [[0, 1], [1, 1]]
180+>>> # distrance between rows of X
181+>>> euclidean_distances(X, X)
182+array([[ 0., 1.],
183+[ 1., 0.]])
184+>>> # get distance to origin
185+>>> euclidean_distances(X, [[0, 0]])
186+array([[ 1. ],
187+[ 1.41421356]])
188+"""
189+ # should not need X_norm_squared because if you could precompute that as
190+ # well as Y, then you should just pre-compute the output and not even
191+ # call this function.
192+ if X is Y:
193+ X = Y = n.asanyarray(X)
194+ else:
195+ X = n.asanyarray(X)
196+ Y = n.asanyarray(Y)
197+
198+ if X.shape[1] != Y.shape[1]:
199+ raise ValueError("Incompatible dimension for X and Y matrices")
200+
201+ XX = n.sum(X * X, axis=1)[:, n.newaxis]
202+ if X is Y: # shortcut in the common case euclidean_distances(X, X)
203+ YY = XX.T
204+ elif Y_norm_squared is None:
205+ YY = Y.copy()
206+ YY **= 2
207+ YY = n.sum(YY, axis=1)[n.newaxis, :]
208+ else:
209+ YY = n.asanyarray(Y_norm_squared)
210+ if YY.shape != (Y.shape[0],):
211+ raise ValueError("Incompatible dimension for Y and Y_norm_squared")
212+ YY = YY[n.newaxis, :]
213+
214+ # TODO:
215+ # a faster cython implementation would do the dot product first,
216+ # and then add XX, add YY, and do the clipping of negative values in
217+ # a single pass over the output matrix.
218+ distances = XX + YY # Using broadcasting
219+ distances -= 2 * n.dot(X, Y.T)
220+ distances = n.maximum(distances, 0)
221+ if squared:
222+ return distances
223+ else:
224+ return n.sqrt(distances)
225+
226+euclidian_distances = euclidean_distances # both spelling for backward compat
227+
228+
229+def find_CM(cluster):
230+ CM=s.mean(cluster, axis=0)
231+ return CM
232+
233+
234+def relocate_cluster(cluster):
235+ cluster_shift=find_CM(cluster)
236+ cluster[:,0]=cluster[:,0]-cluster_shift[0]
237+ cluster[:,1]=cluster[:,1]-cluster_shift[1]
238+ cluster[:,2]=cluster[:,2]-cluster_shift[2]
239+
240+ return cluster
241+
242+
243+def project_cluster_xy(cluster):
244+ new_clust=cluster[:,0:2]
245+ return new_clust
246+
247+
248+###################################
249+
250+
251+R=1. #monomer radius
252+k=15 #number of monomers
253+
254+N=50000
255+Nrot=5000
256+
257+ini_cluster=generate_chain(k,R)
258+
259+
260+
261+# ini_cluster=s.arange(6).reshape((2,3))*1.
262+
263+
264+# ini_cluster[0,0]=4.
265+# ini_cluster[0,1]=0.
266+# ini_cluster[0,2]=0.
267+
268+
269+
270+# ini_cluster[1,0]=2.
271+# ini_cluster[1,1]=0.
272+# ini_cluster[1,2]=0.
273+
274+
275+ini_cluster=relocate_cluster(ini_cluster)
276+
277+print "ini_cluster is, ", ini_cluster
278+
279+rotated_clust=rotate_cluster(ini_cluster)
280+
281+print "rotated_clust is, ", rotated_clust
282+
283+projected_clust=project_cluster_xy(rotated_clust)
284+
285+print "projected_clust is, ", projected_clust
286+
287+
288+
289+print "N is, ", N
290+
291+area=montecarlo_calc_rect(N,projected_clust, R)
292+print "area is, ", area
293+
294+# area_exact=analytical_area(projected_clust, R)
295+
296+area_exact=analytical_area_chain(projected_clust, R,k)
297+
298+
299+print "The analytical area of the projected cluster is, ", area_exact
300+
301+rel_err=abs(area-area_exact)/area_exact*100.
302+
303+print "the relative (percentual!) error is, ", rel_err
304+########################################################################
305+
306+# arealist=s.zeros(Nrot)
307+
308+# for i in xrange(Nrot):
309+# rotated_clust=rotate_cluster(ini_cluster)
310+
311+# # print "rotated_clust is, ", rotated_clust
312+
313+# projected_clust=project_cluster_xy(rotated_clust)
314+
315+# # print "projected_clust is, ", projected_clust
316+
317+# arealist[i]=analytical_area(projected_clust, R)
318+
319+# print "the mean area is, ", s.mean(arealist)
320+
321+print "So far so good"