EPG implementation that mimics the regular implementation from Julien Lamy in Sycomore

# Short description

Regular implementation use a constant positive or negative gradient dephasing. We use a vector Fp, Fn and Z to store the states.

# Initialization

EPG states are stored as a structure :

mutable struct EPGStates{T <: Real}
Fp::Vector{Complex{T}}
Fn::Vector{Complex{T}}
Z::Vector{Complex{T}}
end

which can be initialized with default parameters Fp = 0, Fn = 0 and Z = 1 states using :

using EPGsim
E = EPGStates()
EPGStates struct with fields : Fp, Fn, Z


or by :

E = EPGStates(0,0,1)
EPGStates struct with fields : Fp, Fn, Z


which convert any numbers of the same types in Vector{ComplexF64}

or directly by passing Vector{Complex{T}} where {T <: Real} which means it can accept a complex{dual} type :

T = ComplexF32
E = EPGStates(T.([0.5+0.5im,1]),T.([0.5-0.5im,0]),T.([1,0]))
EPGStates struct with fields : Fp, Fn, Z


!!! Note Julia is a one based indexing language. Fp[1]/Fn[1]/Z[1] store the echo and correspond to the states commonly named $F_0^+$ / $F_0^-$ $Z_0$

Warning

the F+[1] and F-[1] states should be complex conjugate and imag(Z[1])=0

# EPG simulation

3 functions are used to simulate a sequence :

• epgDephasing
• epgRelaxation
• epgRotation

They take an EPGStates struct as first parameter.

E = EPGStates()
E = epgDephasing(E,1)
E = epgRotation(E,deg2rad(60),deg2rad(117))
Note

Currently, all the EPGstates are stored and used for calculation. The states equal or really close to zero are not deleted

# Accessing states

States can seen directly as a vector :

E.Fp
1-element Vector{ComplexF64}:
0.0 + 0.0im

or by elements :

E.Fp[2]

getStates is also available to create a 3xN matrix where 3 corresponds to Fp,Fn,Z and N is the number of states.

getStates(E)
3×1 Matrix{ComplexF64}:
0.0 + 0.0im
0.0 + 0.0im
1.0 + 0.0im