11export spectrum, spectrum_correlation_fft
2- export SpectrumSolver, ExponentialSeries# , PseudoInverse
2+ export SpectrumSolver, ExponentialSeries, PseudoInverse
33
44abstract type SpectrumSolver end
55
1515
1616ExponentialSeries (; tol = 1e-14 , calc_steadystate = false ) = ExponentialSeries (tol, calc_steadystate)
1717
18+ @doc raw """
19+ PseudoInverse(; alg::SciMLLinearSolveAlgorithm = KrylovJL_GMRES())
20+
21+ A solver which solves [`spectrum`](@ref) by finding the inverse of Liouvillian [`SuperOperator`](@ref) using the `alg`orithms given in [`LinearSolve.jl`](https://docs.sciml.ai/LinearSolve/stable/).
22+ """
23+ struct PseudoInverse{MT<: SciMLLinearSolveAlgorithm } <: SpectrumSolver
24+ alg:: MT
25+ end
26+
27+ PseudoInverse (; alg:: SciMLLinearSolveAlgorithm = KrylovJL_GMRES ()) = PseudoInverse (alg)
28+
1829@doc raw """
1930 spectrum(H::QuantumObject,
2031 ωlist::AbstractVector,
@@ -32,6 +43,7 @@ S(\omega) = \int_{-\infty}^\infty \lim_{t \rightarrow \infty} \left\langle \hat{
3243
3344See also the following list for `SpectrumSolver` docstrings:
3445- [`ExponentialSeries`](@ref)
46+ - [`PseudoInverse`](@ref)
3547"""
3648function spectrum (
3749 H:: QuantumObject{MT1,HOpType} ,
@@ -91,18 +103,47 @@ function _spectrum(
91103 return spec
92104end
93105
94- #= function _spectrum(
106+ function _spectrum (
95107 L:: QuantumObject{<:AbstractArray{T1},SuperOperatorQuantumObject} ,
96108 ωlist:: AbstractVector ,
97109 A:: QuantumObject{<:AbstractArray{T2},OperatorQuantumObject} ,
98110 B:: QuantumObject{<:AbstractArray{T3},OperatorQuantumObject} ,
99111 solver:: PseudoInverse ;
100112 kwargs... ,
101113) where {T1,T2,T3}
102- allequal((L.dims, A.dims, B.dims)) || throw(DimensionMismatch("The quantum objects are not of the same Hilbert dimension."))
114+ allequal ((L. dims, A. dims, B. dims)) ||
115+ throw (DimensionMismatch (" The quantum objects are not of the same Hilbert dimension." ))
116+
117+ ωList = convert (Vector{_FType (L)}, ωlist) # Convert it to support GPUs and avoid type instabilities
118+ Length = length (ωList)
119+ spec = Vector {_FType(L)} (undef, Length)
120+
121+ # calculate vectorized steadystate, multiply by operator B on the left (spre)
122+ ρss = mat2vec (steadystate (L))
123+ b = (spre (B) * ρss). data
124+
125+ # multiply by operator A on the left (spre) and then perform trace operation
126+ D = prod (L. dims)
127+ _tr = SparseVector (D^ 2 , [1 + n * (D + 1 ) for n in 0 : (D- 1 )], ones (_CType (L), D)) # same as vec(system_identity_matrix)
128+ _tr_A = transpose (_tr) * spre (A). data
129+
130+ cache = nothing
131+ I_cache = I (D^ 2 )
132+ for (idx, ω) in enumerate (ωList)
133+ if idx == 1
134+ cache = init (LinearProblem (L. data - 1im * ω * I_cache, b), solver. alg, kwargs... )
135+ sol = solve! (cache)
136+ else
137+ cache. A = L. data - 1im * ω * I_cache
138+ sol = solve! (cache)
139+ end
140+
141+ # trace over the Hilbert space of system (expectation value)
142+ spec[idx] = - 2 * real (dot (_tr_A, sol. u))
143+ end
103144
104145 return spec
105- end =#
146+ end
106147
107148@doc raw """
108149 spectrum_correlation_fft(tlist, corr; inverse=false)
0 commit comments