mirror of
https://github.com/vale981/Looping.jl
synced 2025-03-05 09:21:37 -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
|
||||
export hi
|
||||
|
||||
# Write your package code here.
|
||||
hi() = print("hi")
|
||||
|
||||
include("Utilities.jl")
|
||||
include("FloquetUtils.jl")
|
||||
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