1 # this code is really a mess ...
5 from RandomArray
import *
6 from LinearAlgebra
import *
8 from functools
import reduce
15 return math
.sqrt(reduce(lambda x
, y
: x
+y
*y
, v
, 0))
17 def blochvector(l
, k
):
18 assert k
>= 0 and k
<= l
/2
19 v
= cos(2*math
.pi
/l
*(k
)*arange(l
))
22 def localvector(l
, pos
):
27 def local2vector(l
, pos1
, pos2
):
35 def diag_anderson(l
, w
):
37 """diagonalize the anderson model"""
41 ham
= zeros((l
, l
), Float
)
46 evalues
, evectors
= eigenvectors(ham
)
47 sorter
= argsort(evalues
)
48 return take(evalues
, sorter
), take(evectors
, sorter
)
52 def diag_harper_full(l
, lam
):
54 """diagonalize the harper model by full diagonalization"""
58 while result
[-1] < tonumber
:
59 result
.append(result
[-2]+result
[-1])
62 l2
, ltest
= fibs(l
)[-2:]
63 if ltest
!= l
: raise ValueError("l isn't a fibonacci number")
65 pot
=lam
*cos((2*pi
*l2
*arange(l
))/l
)
66 ham
= zeros((l
, l
), Float
)
71 evalues
, evectors
= eigenvectors(ham
)
72 sorter
= argsort(evalues
)
73 return take(evalues
, sorter
), take(evectors
, sorter
)
77 def diag_harper(l
, lam
):
79 """diagonalize the harper model by diagonalizing the symmetric and antisymmetic parts"""
83 while result
[-1] < tonumber
:
84 result
.append(result
[-2]+result
[-1])
87 def createsymm(dest
, source
):
91 for i
in range(1, (l
+1)/2):
92 dest
[i
] = dest
[l
-i
] = source
[i
] / sqrt2
95 dest
[l
/2] = source
[l
/2]
96 for i
in range(1, l
/2):
97 dest
[i
] = dest
[l
-i
] = source
[i
] / sqrt2
99 def createasymm(dest
, source
):
103 for i
in range(1, (l
+1)/2):
104 dest
[i
] = source
[i
-1] / sqrt2
105 dest
[l
-i
] = -source
[i
-1] / sqrt2
107 dest
[0] = dest
[l
/2] = 0
108 for i
in range(1, l
/2):
109 dest
[i
] = -source
[i
-1] / sqrt2
110 dest
[l
-i
] = source
[i
-1] / sqrt2
112 l2
, ltest
= fibs(l
)[-2:]
113 if ltest
!= l
: raise ValueError("l isn't a fibonacci number")
115 # symmetric and antisymmetric diagonalization
118 symmsize
= (l
-1)/2 + 1
119 pot
= lam
*cos((2*pi
*l2
*arange(symmsize
))/l
)
120 pot
[symmsize
- 1] += 1
121 symmham
= zeros((symmsize
, symmsize
), Float
)
122 for i
in range(symmsize
):
123 symmham
[i
, i
] = pot
[i
]
125 symmham
[i
, i
-1] = symmham
[i
-1, i
] = 1
127 symmham
[i
, i
-1] = symmham
[i
-1, i
] = sqrt2
131 pot
= lam
*cos((2*pi
*l2
*arange(symmsize
))/l
)
132 symmham
= zeros((symmsize
, symmsize
), Float
)
133 for i
in range(symmsize
):
134 symmham
[i
, i
] = pot
[i
]
135 if i
> 1 and i
< symmsize
- 1:
136 symmham
[i
, i
-1] = symmham
[i
-1, i
] = 1
138 symmham
[i
, i
-1] = symmham
[i
-1, i
] = sqrt2
139 symmevalues
, symmevectors
= eigenvectors(symmham
)
144 pot
= lam
*cos((2*pi
*l2
*(arange(asymmsize
)+1))/l
)
145 pot
[asymmsize
-1] -= 1
146 asymmham
= zeros((asymmsize
, asymmsize
), Float
)
147 for i
in range(asymmsize
):
148 asymmham
[i
, i
] = pot
[i
]
150 asymmham
[i
, i
-1] = asymmham
[i
-1, i
] = 1
154 pot
= lam
*cos((2*pi
*l2
*(arange(asymmsize
)+1))/l
)
155 asymmham
= zeros((asymmsize
, asymmsize
), Float
)
156 for i
in range(asymmsize
):
157 asymmham
[i
, i
] = pot
[i
]
159 asymmham
[i
, i
-1] = asymmham
[i
-1, i
] = 1
160 asymmevalues
, asymmevectors
= eigenvectors(asymmham
)
162 # build complete solution
163 symmsort
= argsort(symmevalues
)
164 asymmsort
= argsort(asymmevalues
)
166 evalues
= zeros((l
,), Float
)
167 evectors
= zeros((l
, l
), Float
)
169 if j
!= symmsize
and (k
== asymmsize
or
170 symmevalues
[symmsort
[j
]] < asymmevalues
[asymmsort
[k
]]):
171 evalues
[i
] = symmevalues
[symmsort
[j
]]
172 createsymm(evectors
[i
], symmevectors
[symmsort
[j
]])
175 evalues
[i
] = asymmevalues
[asymmsort
[k
]]
176 createasymm(evectors
[i
], asymmevectors
[asymmsort
[k
]])
178 return evalues
, evectors
182 def test_harper(l
, lam
):
184 """compare diag_harper and diag_harper_full"""
186 res1
= diag_harper(l
, lam
)
187 res2
= diag_harper_full(l
, lam
)
188 for x1
, x2
in zip(res1
[0], res2
[0]):
189 assert math
.fabs(x1
-x2
) < 1e-8, "eigenvalues differ"
190 for v1
, v2
in zip(res1
[1], res2
[1]):
192 for x1
, x2
in zip(v1
, v2
):
195 for x1
, x2
in zip(v1
, v2
):
196 assert math
.fabs(x1
-x2
) < 1e-8, "eigenvectors differ\n%s\n%s" % (v1
, v2
)
198 for x1
, x2
in zip(v1
, v2
):
199 assert math
.fabs(x1
+x2
) < 1e-8, "eigenvectors differ\n%s\n%s" % (v1
, -v2
)
205 def wigner_slow(vector
):
207 """create wigner function of a state (direct way)"""
210 wig
= zeros((l
, l
), Float
)
212 # wigner function (direct way)
213 for x0loop
in range(l
):
215 for k0loop
in range(l
):
217 k0
= (k0loop
-0.5*l
+0.5)*2*pi
/l
219 k0
= (k0loop
-0.5*l
+1)*2*pi
/l
221 for yloop
in range(l
):
222 y
= yloop
- l
/2 + 1 - l
%2
223 v
= lambda x
: vector
[(x
+10*l
)%l
]
225 v1
= 0.5*(v(x0
-(y
-1)/2) + v(x0
-(y
+1)/2))
226 v2
= 0.5*(v(x0
+(y
-1)/2) + v(x0
+(y
+1)/2))
232 sum += v1
* v2
* exp(1j
*k0
*y
)
233 assert abs(sum.imag
) < 1e-10, "imaginary part should be zero"
234 wig
[x0loop
, k0loop
] = sum.real
242 """create wigner function of a state (fft)"""
245 wig
= zeros((l
, l
), Float
)
247 fftarray
= zeros(l
, Float
)
248 fftresult
= zeros(l
, Complex
)
249 wig
= zeros((l
, l
), Float
)
250 for x0loop
in range(l
):
252 for yloop
in range(l
):
253 y
= yloop
- l
/2 + 1 - l
%2
254 v
= lambda x
: vector
[(x
+10*l
)%l
]
256 v1
= 0.5*(v(x0
-(y
-1)/2) + v(x0
-(y
+1)/2))
257 v2
= 0.5*(v(x0
+(y
-1)/2) + v(x0
+(y
+1)/2))
263 fftarray
[(y
+10*l
)%l
] = v1
* v2
264 fftresult
= real_fft(fftarray
)
265 for k0loop
in range(l
):
267 index
= int(abs(k0loop
-0.5*l
+0.5))
269 index
= int(abs(k0loop
-0.5*l
+1))
270 wig
[x0loop
, k0loop
] = fftresult
[index
].real
276 def test_wigner(vector
):
278 """compare wigner_slow and wigner"""
280 res1
= wigner_slow(vector
)
281 res2
= wigner(vector
)
282 for v1
, v2
in zip(res1
, res2
):
283 for x1
, x2
in zip(v1
, v2
):
284 assert math
.fabs(x1
-x2
) < 1e-8, "wigner function differs\n%s\n%s" % (res1
, res2
)
286 # test_wigner(diag_anderson(10, 1)[1][5])
287 # test_wigner(diag_anderson(11, 1)[1][5])
290 def husimi_from_wigner(wig
):
292 """calculate the husimi function out of the wigner function"""
297 hus
= zeros((l
, l
), Float
)
300 sys
.stderr
.write("wigner -> husimi (very slow) ...%6.2f%%\r" % ((100.0*(x1
*l
+k1
))/l
/l
))
305 if dx
< -l
/2: dx
+= l
308 if dk
< -l
/2: dk
+= l
311 hus
[x1
, k1
] += 2.0/l
/l
* wig
[x2
, k2
] * exp(-0.5*dx
*dx
/sigma
/sigma
-2*sigma
*sigma
*dk
*dk
)
312 sys
.stderr
.write("wigner -> husimi (very slow) ... done. \n")
318 def husimi_slow(vector
):
321 hus
= zeros((l
, l
), Float
)
322 phases
= zeros((l
, l
), Float
)
324 factor
=1/sqrt(sqrt(2*pi
)*sigma
*l
)
326 for x0loop
in range(l
):
328 for k0loop
in range(l
):
330 k0
= (k0loop
-0.5*l
+0.5)*2*pi
/l
332 k0
= (k0loop
-0.5*l
+1)*2*pi
/l
336 sum += vector
[x
] * factor
* exp(-(x
-x0
-l
)*(x
-x0
-l
)/(4*sigma
*sigma
)) * phase
337 sum += vector
[x
] * factor
* exp(-(x
-x0
)*(x
-x0
)/(4*sigma
*sigma
)) * phase
338 sum += vector
[x
] * factor
* exp(-(x
-x0
+l
)*(x
-x0
+l
)/(4*sigma
*sigma
)) * phase
339 hus
[x0loop
, k0loop
] = abs(sum)*abs(sum)
340 phases
[x0loop
, k0loop
] = math
.atan2(sum.imag
, sum.real
)
349 hus
= zeros((l
, l
), Float
)
351 factor
=1/sqrt(sqrt(2*pi
)*sigma
*l
)
353 fftarray
= zeros(l
, Complex
)
354 fftresult
= zeros(l
, Complex
)
355 heights
= zeros((l
, l
), Float
)
356 phases
= zeros((l
, l
), Float
)
357 for x0loop
in range(l
):
359 for xloop
in range(l
):
361 while (x
-x0
< -0.5*l
): x
+= l
362 while (x
-x0
> 0.5*l
): x
-=l
363 fftarray
[xloop
] = vector
[xloop
] * factor
* exp(-(x
-x0
)*(x
-x0
)/(4*sigma
*sigma
))
364 #fftresult = real_fft(fftarray)
365 fftresult
= fft(fftarray
)
366 for k0loop
in range(l
):
368 index
= (int(k0loop
-0.5*l
+0.5) + 10*l
)%l
369 #index = int(abs(k0loop-0.5*l+0.5))
372 index
= int(abs(k0loop
-0.5*l
+1))
373 heights
[x0loop
, k0loop
] = abs(fftresult
[index
])*abs(fftresult
[index
])
374 phases
[x0loop
, k0loop
] = math
.atan2(fftresult
[index
].imag
, fftresult
[index
].real
)
375 # if 2*x0loop > l: phases[x0loop, k0loop] = -phases[x0loop, k0loop] + math.pi
376 # if 2*k0loop > l: phases[x0loop, k0loop] = -phases[x0loop, k0loop]
378 return heights
, phases
382 def test_husimi(vector
):
384 """compare husimi_slow and husimi"""
386 res1
= husimi_slow(vector
)
387 res2
= husimi(vector
)
388 for v1
, v2
in zip(res1
, res2
):
389 for x1
, x2
in zip(v1
, v2
):
390 assert math
.fabs(x1
-x2
) < 1e-8, "husimi function differs\n%s\n%s" % (res1
, res2
)
392 # test_husimi(diag_anderson(10, 1)[1][5])
393 # test_husimi(diag_anderson(11, 1)[1][5])
396 values
, vectors
= diag_anderson(l
, 0.5)
398 heights
, phases
= husimi(vector
)
400 f
= open("example.dat", "w")
403 f
.write("%i %i %+20.15e %+20.15e\n" % (x
, y
, heights
[x
, y
], phases
[x
, y
]))