1 # this code is really a mess ...
5 from RandomArray
import *
6 from LinearAlgebra
import *
14 return math
.sqrt(reduce(lambda x
, y
: x
+y
*y
, v
, 0))
16 def blochvector(l
, k
):
17 assert k
>= 0 and k
<= l
/2
18 v
= cos(2*math
.pi
/l
*(k
)*arange(l
))
21 def localvector(l
, pos
):
26 def local2vector(l
, pos1
, pos2
):
34 def diag_anderson(l
, w
):
36 """diagonalize the anderson model"""
40 ham
= zeros((l
, l
), Float
)
45 evalues
, evectors
= eigenvectors(ham
)
46 sorter
= argsort(evalues
)
47 return take(evalues
, sorter
), take(evectors
, sorter
)
51 def diag_harper_full(l
, lam
):
53 """diagonalize the harper model by full diagonalization"""
57 while result
[-1] < tonumber
:
58 result
.append(result
[-2]+result
[-1])
61 l2
, ltest
= fibs(l
)[-2:]
62 if ltest
!= l
: raise ValueError("l isn't a fibonacci number")
64 pot
=lam
*cos((2*pi
*l2
*arange(l
))/l
)
65 ham
= zeros((l
, l
), Float
)
70 evalues
, evectors
= eigenvectors(ham
)
71 sorter
= argsort(evalues
)
72 return take(evalues
, sorter
), take(evectors
, sorter
)
76 def diag_harper(l
, lam
):
78 """diagonalize the harper model by diagonalizing the symmetric and antisymmetic parts"""
82 while result
[-1] < tonumber
:
83 result
.append(result
[-2]+result
[-1])
86 def createsymm(dest
, source
):
90 for i
in xrange(1, (l
+1)/2):
91 dest
[i
] = dest
[l
-i
] = source
[i
] / sqrt2
94 dest
[l
/2] = source
[l
/2]
95 for i
in xrange(1, l
/2):
96 dest
[i
] = dest
[l
-i
] = source
[i
] / sqrt2
98 def createasymm(dest
, source
):
102 for i
in xrange(1, (l
+1)/2):
103 dest
[i
] = source
[i
-1] / sqrt2
104 dest
[l
-i
] = -source
[i
-1] / sqrt2
106 dest
[0] = dest
[l
/2] = 0
107 for i
in xrange(1, l
/2):
108 dest
[i
] = -source
[i
-1] / sqrt2
109 dest
[l
-i
] = source
[i
-1] / sqrt2
111 l2
, ltest
= fibs(l
)[-2:]
112 if ltest
!= l
: raise ValueError("l isn't a fibonacci number")
114 # symmetric and antisymmetric diagonalization
117 symmsize
= (l
-1)/2 + 1
118 pot
= lam
*cos((2*pi
*l2
*arange(symmsize
))/l
)
119 pot
[symmsize
- 1] += 1
120 symmham
= zeros((symmsize
, symmsize
), Float
)
121 for i
in xrange(symmsize
):
122 symmham
[i
, i
] = pot
[i
]
124 symmham
[i
, i
-1] = symmham
[i
-1, i
] = 1
126 symmham
[i
, i
-1] = symmham
[i
-1, i
] = sqrt2
130 pot
= lam
*cos((2*pi
*l2
*arange(symmsize
))/l
)
131 symmham
= zeros((symmsize
, symmsize
), Float
)
132 for i
in xrange(symmsize
):
133 symmham
[i
, i
] = pot
[i
]
134 if i
> 1 and i
< symmsize
- 1:
135 symmham
[i
, i
-1] = symmham
[i
-1, i
] = 1
137 symmham
[i
, i
-1] = symmham
[i
-1, i
] = sqrt2
138 symmevalues
, symmevectors
= eigenvectors(symmham
)
143 pot
= lam
*cos((2*pi
*l2
*(arange(asymmsize
)+1))/l
)
144 pot
[asymmsize
-1] -= 1
145 asymmham
= zeros((asymmsize
, asymmsize
), Float
)
146 for i
in xrange(asymmsize
):
147 asymmham
[i
, i
] = pot
[i
]
149 asymmham
[i
, i
-1] = asymmham
[i
-1, i
] = 1
153 pot
= lam
*cos((2*pi
*l2
*(arange(asymmsize
)+1))/l
)
154 asymmham
= zeros((asymmsize
, asymmsize
), Float
)
155 for i
in xrange(asymmsize
):
156 asymmham
[i
, i
] = pot
[i
]
158 asymmham
[i
, i
-1] = asymmham
[i
-1, i
] = 1
159 asymmevalues
, asymmevectors
= eigenvectors(asymmham
)
161 # build complete solution
162 symmsort
= argsort(symmevalues
)
163 asymmsort
= argsort(asymmevalues
)
165 evalues
= zeros((l
,), Float
)
166 evectors
= zeros((l
, l
), Float
)
168 if j
!= symmsize
and (k
== asymmsize
or
169 symmevalues
[symmsort
[j
]] < asymmevalues
[asymmsort
[k
]]):
170 evalues
[i
] = symmevalues
[symmsort
[j
]]
171 createsymm(evectors
[i
], symmevectors
[symmsort
[j
]])
174 evalues
[i
] = asymmevalues
[asymmsort
[k
]]
175 createasymm(evectors
[i
], asymmevectors
[asymmsort
[k
]])
177 return evalues
, evectors
181 def test_harper(l
, lam
):
183 """compare diag_harper and diag_harper_full"""
185 res1
= diag_harper(l
, lam
)
186 res2
= diag_harper_full(l
, lam
)
187 for x1
, x2
in zip(res1
[0], res2
[0]):
188 assert math
.fabs(x1
-x2
) < 1e-8, "eigenvalues differ"
189 for v1
, v2
in zip(res1
[1], res2
[1]):
191 for x1
, x2
in zip(v1
, v2
):
194 for x1
, x2
in zip(v1
, v2
):
195 assert math
.fabs(x1
-x2
) < 1e-8, "eigenvectors differ\n%s\n%s" % (v1
, v2
)
197 for x1
, x2
in zip(v1
, v2
):
198 assert math
.fabs(x1
+x2
) < 1e-8, "eigenvectors differ\n%s\n%s" % (v1
, -v2
)
204 def wigner_slow(vector
):
206 """create wigner function of a state (direct way)"""
209 wig
= zeros((l
, l
), Float
)
211 # wigner function (direct way)
212 for x0loop
in xrange(l
):
214 for k0loop
in xrange(l
):
216 k0
= (k0loop
-0.5*l
+0.5)*2*pi
/l
218 k0
= (k0loop
-0.5*l
+1)*2*pi
/l
220 for yloop
in xrange(l
):
221 y
= yloop
- l
/2 + 1 - l
%2
222 v
= lambda x
: vector
[(x
+10*l
)%l
]
224 v1
= 0.5*(v(x0
-(y
-1)/2) + v(x0
-(y
+1)/2))
225 v2
= 0.5*(v(x0
+(y
-1)/2) + v(x0
+(y
+1)/2))
231 sum += v1
* v2
* exp(1j
*k0
*y
)
232 assert abs(sum.imag
) < 1e-10, "imaginary part should be zero"
233 wig
[x0loop
, k0loop
] = sum.real
241 """create wigner function of a state (fft)"""
244 wig
= zeros((l
, l
), Float
)
246 fftarray
= zeros(l
, Float
)
247 fftresult
= zeros(l
, Complex
)
248 wig
= zeros((l
, l
), Float
)
249 for x0loop
in xrange(l
):
251 for yloop
in xrange(l
):
252 y
= yloop
- l
/2 + 1 - l
%2
253 v
= lambda x
: vector
[(x
+10*l
)%l
]
255 v1
= 0.5*(v(x0
-(y
-1)/2) + v(x0
-(y
+1)/2))
256 v2
= 0.5*(v(x0
+(y
-1)/2) + v(x0
+(y
+1)/2))
262 fftarray
[(y
+10*l
)%l
] = v1
* v2
263 fftresult
= real_fft(fftarray
)
264 for k0loop
in xrange(l
):
266 index
= int(abs(k0loop
-0.5*l
+0.5))
268 index
= int(abs(k0loop
-0.5*l
+1))
269 wig
[x0loop
, k0loop
] = fftresult
[index
].real
275 def test_wigner(vector
):
277 """compare wigner_slow and wigner"""
279 res1
= wigner_slow(vector
)
280 res2
= wigner(vector
)
281 for v1
, v2
in zip(res1
, res2
):
282 for x1
, x2
in zip(v1
, v2
):
283 assert math
.fabs(x1
-x2
) < 1e-8, "wigner function differs\n%s\n%s" % (res1
, res2
)
285 # test_wigner(diag_anderson(10, 1)[1][5])
286 # test_wigner(diag_anderson(11, 1)[1][5])
289 def husimi_from_wigner(wig
):
291 """calculate the husimi function out of the wigner function"""
296 hus
= zeros((l
, l
), Float
)
299 sys
.stderr
.write("wigner -> husimi (very slow) ...%6.2f%%\r" % ((100.0*(x1
*l
+k1
))/l
/l
))
304 if dx
< -l
/2: dx
+= l
307 if dk
< -l
/2: dk
+= l
310 hus
[x1
, k1
] += 2.0/l
/l
* wig
[x2
, k2
] * exp(-0.5*dx
*dx
/sigma
/sigma
-2*sigma
*sigma
*dk
*dk
)
311 sys
.stderr
.write("wigner -> husimi (very slow) ... done. \n")
317 def husimi_slow(vector
):
320 hus
= zeros((l
, l
), Float
)
321 phases
= zeros((l
, l
), Float
)
323 factor
=1/sqrt(sqrt(2*pi
)*sigma
*l
)
325 for x0loop
in xrange(l
):
327 for k0loop
in xrange(l
):
329 k0
= (k0loop
-0.5*l
+0.5)*2*pi
/l
331 k0
= (k0loop
-0.5*l
+1)*2*pi
/l
335 sum += vector
[x
] * factor
* exp(-(x
-x0
-l
)*(x
-x0
-l
)/(4*sigma
*sigma
)) * phase
336 sum += vector
[x
] * factor
* exp(-(x
-x0
)*(x
-x0
)/(4*sigma
*sigma
)) * phase
337 sum += vector
[x
] * factor
* exp(-(x
-x0
+l
)*(x
-x0
+l
)/(4*sigma
*sigma
)) * phase
338 hus
[x0loop
, k0loop
] = abs(sum)*abs(sum)
339 phases
[x0loop
, k0loop
] = math
.atan2(sum.imag
, sum.real
)
348 hus
= zeros((l
, l
), Float
)
350 factor
=1/sqrt(sqrt(2*pi
)*sigma
*l
)
352 fftarray
= zeros(l
, Complex
)
353 fftresult
= zeros(l
, Complex
)
354 heights
= zeros((l
, l
), Float
)
355 phases
= zeros((l
, l
), Float
)
356 for x0loop
in xrange(l
):
358 for xloop
in xrange(l
):
360 while (x
-x0
< -0.5*l
): x
+= l
361 while (x
-x0
> 0.5*l
): x
-=l
362 fftarray
[xloop
] = vector
[xloop
] * factor
* exp(-(x
-x0
)*(x
-x0
)/(4*sigma
*sigma
))
363 #fftresult = real_fft(fftarray)
364 fftresult
= fft(fftarray
)
365 for k0loop
in xrange(l
):
367 index
= (int(k0loop
-0.5*l
+0.5) + 10*l
)%l
368 #index = int(abs(k0loop-0.5*l+0.5))
371 index
= int(abs(k0loop
-0.5*l
+1))
372 heights
[x0loop
, k0loop
] = abs(fftresult
[index
])*abs(fftresult
[index
])
373 phases
[x0loop
, k0loop
] = math
.atan2(fftresult
[index
].imag
, fftresult
[index
].real
)
374 # if 2*x0loop > l: phases[x0loop, k0loop] = -phases[x0loop, k0loop] + math.pi
375 # if 2*k0loop > l: phases[x0loop, k0loop] = -phases[x0loop, k0loop]
377 return heights
, phases
381 def test_husimi(vector
):
383 """compare husimi_slow and husimi"""
385 res1
= husimi_slow(vector
)
386 res2
= husimi(vector
)
387 for v1
, v2
in zip(res1
, res2
):
388 for x1
, x2
in zip(v1
, v2
):
389 assert math
.fabs(x1
-x2
) < 1e-8, "husimi function differs\n%s\n%s" % (res1
, res2
)
391 # test_husimi(diag_anderson(10, 1)[1][5])
392 # test_husimi(diag_anderson(11, 1)[1][5])
395 values
, vectors
= diag_anderson(l
, 0.5)
397 heights
, phases
= husimi(vector
)
399 f
= open("example.dat", "w")
402 f
.write("%i %i %+20.15e %+20.15e\n" % (x
, y
, heights
[x
, y
], phases
[x
, y
]))