mirror of
https://github.com/vale981/Looping.jl
synced 2025-03-05 17:21:40 -05:00
add first codes
This commit is contained in:
parent
7e3be80423
commit
8b9b2c9990
3 changed files with 174 additions and 1 deletions
123
src/FloquetUtils.jl
Normal file
123
src/FloquetUtils.jl
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
module FloquetUtils
|
||||||
|
|
||||||
|
import LinearAlgebra: I, eigvecs, eigen, Diagonal
|
||||||
|
import DifferentialEquations as de
|
||||||
|
|
||||||
|
export time_evolution_op
|
||||||
|
export floquet_hamiltonian
|
||||||
|
export KickOperator
|
||||||
|
|
||||||
|
using ..Utilities
|
||||||
|
|
||||||
|
"""
|
||||||
|
time_evolution_op(H, T, args...; kwargs...)
|
||||||
|
|
||||||
|
Calculate the time evolution operator for a Hamiltonian `H` up to a
|
||||||
|
total time `T`. The rest arguments are passed on to
|
||||||
|
`DifferentialEquations.solve`.
|
||||||
|
"""
|
||||||
|
function time_evolution_op(H::Function, T::Real, args...; kwargs...)
|
||||||
|
function u_step!(dU, U, _, t)
|
||||||
|
dU .= -1im * H(t) * U
|
||||||
|
end
|
||||||
|
|
||||||
|
N = size(H(0), 1)
|
||||||
|
u0 = Matrix{ComplexF64}(I, N, N)
|
||||||
|
|
||||||
|
tspan = (0.0, T)
|
||||||
|
prob = de.ODEProblem(u_step!, u0, tspan)
|
||||||
|
de.solve(prob, args...; kwargs...)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
floquet_hamiltonian(U, T)
|
||||||
|
|
||||||
|
Returns the Floquet Hamiltonian given a unitary matrix `U` and a time
|
||||||
|
`T`.
|
||||||
|
"""
|
||||||
|
function floquet_hamiltonian(U::Matrix, T::Real)
|
||||||
|
1im / T * log(U)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
floquet_hamiltonian(H(t), T)
|
||||||
|
|
||||||
|
Returns the Floquet Hamiltonian given a Hamiltionian `H` and a time
|
||||||
|
`T`. The rest arguments are passed on to
|
||||||
|
`DifferentialEquations.solve`.
|
||||||
|
"""
|
||||||
|
function floquet_hamiltonian(H::Function, T::Real, args...; kwargs...)
|
||||||
|
U = time_evolution_op(H, T, args...; kwargs...)
|
||||||
|
floquet_hamiltonian(U(T), T)
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
trivial_floquet_hamiltonian(H, T, restrict_energies=false)
|
||||||
|
|
||||||
|
Returns the Floquet Hamiltonian for a Hamiltonain `H` that commutes
|
||||||
|
with itself at different times.
|
||||||
|
"""
|
||||||
|
function trivial_floquet_hamiltonian(H::Function, T::Real, restrict_energies::Bool=false)
|
||||||
|
function h_step!(dU, _, _, t)
|
||||||
|
dU .= H(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
dimension = size(H(0), 1)
|
||||||
|
u0 = zeros(ComplexF64, dimension, dimension)
|
||||||
|
prob = de.ODEProblem(h_step!, u0, (0.0, T))
|
||||||
|
|
||||||
|
integrated_hamiltonian = de.solve(prob)
|
||||||
|
|
||||||
|
H_F = integrated_hamiltonian(T) / T
|
||||||
|
|
||||||
|
if restrict_energies
|
||||||
|
energies, vecs = eigen(H_F)
|
||||||
|
energies .= restrict_to_range.(energies, π / T)
|
||||||
|
H_F .= vecs * Diagonal(energies) * vecs'
|
||||||
|
end
|
||||||
|
|
||||||
|
H_F
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
struct KickOperator
|
||||||
|
U
|
||||||
|
H_F::Matrix
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
KickOperator(U(t), H_F)
|
||||||
|
|
||||||
|
Return the Kick operator Given the time evolution operator `U(t)` and the Floquet Hamiltonian
|
||||||
|
`H_F`.
|
||||||
|
"""
|
||||||
|
function KickOperator(U, H_F::Matrix)
|
||||||
|
if size(U(0)) != size(H_F)
|
||||||
|
throw(DimensionMismatch("`U` and `H_F` should have the same dimension."))
|
||||||
|
end
|
||||||
|
new(U, H_F)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function KickOperator(H::Function, T::Real)
|
||||||
|
U = time_evolution_op(H, T)
|
||||||
|
H_F = floquet_hamiltonian(U(T), T)
|
||||||
|
KickOperator(U, H_F)
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
K(t)
|
||||||
|
|
||||||
|
Return the Kick operator at time t.
|
||||||
|
"""
|
||||||
|
function (K::KickOperator)(t::Real)
|
||||||
|
K.U(t) * exp(1im * K.H_F * t)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -1,5 +1,8 @@
|
||||||
module Looping
|
module Looping
|
||||||
|
export hi
|
||||||
|
|
||||||
# Write your package code here.
|
hi() = print("hi")
|
||||||
|
|
||||||
|
include("Utilities.jl")
|
||||||
|
include("FloquetUtils.jl")
|
||||||
end
|
end
|
||||||
|
|
47
src/Utilities.jl
Normal file
47
src/Utilities.jl
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
module Utilities
|
||||||
|
|
||||||
|
export periodic_distance
|
||||||
|
export restrict_to_range
|
||||||
|
|
||||||
|
"""
|
||||||
|
periodic_distance(m, n, N)
|
||||||
|
|
||||||
|
Calculate the distance `(m-n)`, but assuming periodic boundary
|
||||||
|
conditions for a chain of length `N`.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> periodic_difference(1,4,5)
|
||||||
|
2
|
||||||
|
julia> periodic_difference(1,3,5)
|
||||||
|
-2
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
function periodic_distance(m::Integer, n::Integer, N::Integer)
|
||||||
|
diff = m - n
|
||||||
|
adiff = abs(diff)
|
||||||
|
if abs(diff + N) < adiff
|
||||||
|
diff + N
|
||||||
|
elseif abs(diff - N) < adiff
|
||||||
|
diff - N
|
||||||
|
else
|
||||||
|
diff
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
restrict_to_range(x, border)
|
||||||
|
|
||||||
|
Returns the value `x` restricted to the range `[-border, border]`.
|
||||||
|
"""
|
||||||
|
function restrict_to_range(x::Real, border::Real)
|
||||||
|
sign = x ≥ border ? -1 : 1
|
||||||
|
|
||||||
|
while abs(x) > border
|
||||||
|
x += sign * border * 2
|
||||||
|
end
|
||||||
|
|
||||||
|
x
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue