Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: non-boolean (SymbolicUtils.BasicSymbolic{Bool}) #227

Closed
DerElec opened this issue Nov 28, 2024 · 4 comments
Closed

TypeError: non-boolean (SymbolicUtils.BasicSymbolic{Bool}) #227

DerElec opened this issue Nov 28, 2024 · 4 comments

Comments

@DerElec
Copy link

DerElec commented Nov 28, 2024

I am Using Julia Version 1.11.1 (2024-10-16) with Windows 11 and QuantumCumulants v0.3.7.

I have written a code which should display the mean field equations for a complex Hamiltonian (Coupling 5 ground states to 7 excited states) with dual cavity mode driving. This worked well when ignoring summations over atoms. However, I wanted to implement the Sums, I basically replaced all Transitions with IndexedOperator(Transition). After doing so the code works well until eqs=complete(eqs); This is the last working step. Afterwards I want to use scale(eqs). If I only do this for the cavity Equations, it works and I get the correct cavity equations. If I try to use scale(eqs,h=h_atom) on the total equations of my system I get:

 TypeError: non-boolean (SymbolicUtils.BasicSymbolic{Bool}) used in boolean context
Stacktrace:
 [1] in(x::SymbolicUtils.BasicSymbolic{CNumber}, itr::Vector{SymbolicUtils.BasicSymbolic{QuantumCumulants.AvgSym}})
   @ Base .\operators.jl:1309
[2] scaleME(me::QuantumCumulants.IndexedMeanfieldEquations; kwargs::@Kwargs{h::Nothing})

.

The same error appears for scale(eqs_atom,h=h_atom).

An example Equation for the atom would be

equation

An example before scale for the cavity would be

equation_a_before_scale

and after scale:
equation_a_after_scale

This appears to be correct according to my hand calculations. But I cant get the atomic Equations to work.

The Objects I use :

const F = 2        
const F_prime =3   

function create_atomic_levels_symbolic(F::Int, state_label::Symbol)
    return [(state_label, m) for m in collect(-F:F)]
end

ground_levels_symbolic = create_atomic_levels_symbolic(F, :g)
excited_levels_symbolic = create_atomic_levels_symbolic(F_prime, :e)

levels_symbolic = vcat(ground_levels_symbolic, excited_levels_symbolic)

h_cav_p = FockSpace(:cavity_p)  # Hilbert space for mode a₊
h_cav_m = FockSpace(:cavity_m)  # Hilbert space for mode a₋
h_atom = NLevelSpace(:atom,levels_symbolic)

h = tensor(h_cav_p,h_cav_m,h_atom)

sigma(α, β, k) = IndexedOperator(Transition(h,:σ,α,β,3), k)

i = Index(h,:i, N, h_atom)
j = Index(h,:j, N, h_atom)
k = Index(h,:k, N, h_atom)


@qnumbers a::Destroy(h,1)
@qnumbers b::Destroy(h,2)

H=(-δ*(a′*a)+-δ*(b′*b)+(0 + 1im)*η_p*(a′)+(0 - 1im)*η_p*(a)+(0 + 1im)*η_m*(b′)+(0 - 1im)*η_m*(b)+Σ(k=1:N)-δ*(sigma(:e, -1)(:e, -1)k)+Σ(k=1:N)-δ*(sigma(:e, -3)(:e, -3)k)+Σ(k=1:N)-δ*(sigma(:e, 0)(:e, 0)k)+Σ(k=1:N)-δ*(sigma(:e, -2)(:e, -2)k)+Σ(k=1:N)-δ*(sigma(:e, 1)(:e, 1)k)+Σ(k=1:N)-δ*(sigma(:e, -1)(:e, -1)k)+Σ(k=1:N)-δ*(sigma(:e, 2)(:e, 2)k)+Σ(k=1:N)-δ*(sigma(:e, 0)(:e, 0)k)+Σ(k=1:N)-δ*(sigma(:e, 3)(:e, 3)k)+Σ(k=1:N)-δ*(sigma(:e, 1)(:e, 1)k)+Σ(k=1:N)(0.0 + 0.3779644730092272im)*g0*(a′*sigma(:g, -2)(:e, -1)k)+Σ(k=1:N)(0.0 - 0.3779644730092272im)*g0*(a*sigma(:e, -1)(:g, -2)k)+Σ(k=1:N)(0.0 + 0.5345224838248488im)*g0*(a′*sigma(:g, -1)(:e, 0)k)+Σ(k=1:N)(0.0 - 0.5345224838248488im)*g0*(a*sigma(:e, 0)(:g, -1)k)+Σ(k=1:N)(0.0 + 0.3779644730092272im)*g0*(b′*sigma(:g, -1)(:e, -2)k)+Σ(k=1:N)(0.0 - 0.3779644730092272im)*g0*(b*sigma(:e, -2)(:g, -1)k)+Σ(k=1:N)(0.0 + 0.6546536707079771im)*g0*(a′*sigma(:g, 0)(:e, 1)k)+Σ(k=1:N)(0.0 - 0.6546536707079771im)*g0*(a*sigma(:e, 1)(:g, 0)k)+Σ(k=1:N)(0.0 + 0.5345224838248488im)*g0*(b′*sigma(:g, 0)(:e, -1)k)+Σ(k=1:N)(0.0 - 0.5345224838248488im)*g0*(b*sigma(:e, -1)(:g, 0)k)+Σ(k=1:N)(0.0 + 0.6546536707079771im)*g0*(a′*sigma(:g, 1)(:e, 2)k)+Σ(k=1:N)(0.0 - 0.6546536707079771im)*g0*(a*sigma(:e, 2)(:g, 1)k)+Σ(k=1:N)(0.0 + 0.6546536707079771im)*g0*(b′*sigma(:g, 1)(:e, 0)k)+Σ(k=1:N)(0.0 - 0.6546536707079771im)*g0*(b*sigma(:e, 0)(:g, 1)k)+Σ(k=1:N)(0.0 + 0.3779644730092272im)*g0*(a′*sigma(:g, 2)(:e, 3)k)+Σ(k=1:N)(0.0 - 0.3779644730092272im)*g0*(a*sigma(:e, 3)(:g, 2)k)+Σ(k=1:N)(0.0 + 0.6546536707079771im)*g0*(b′*sigma(:g, 2)(:e, 1)k)+Σ(k=1:N)(0.0 - 0.6546536707079771im)*g0*(b*sigma(:e, 1)(:g, 2)k))
L =[a, b, sigma(:g, -2)(:e, -3)k, sigma(:g, -2)(:e, -2)k, sigma(:g, -1)(:e, -2)k, sigma(:g, -2)(:e, -1)k, sigma(:g, -1)(:e, -1)k, sigma(:g, 0)(:e, -1)k, sigma(:g, -1)(:e, 0)k, sigma(:g, 0)(:e, 0)k, sigma(:g, 1)(:e, 0)k, sigma(:g, 0)(:e, 1)k, sigma(:g, 1)(:e, 1)k, sigma(:g, 2)(:e, 1)k, sigma(:g, 1)(:e, 2)k, sigma(:g, 2)(:e, 2)k, sigma(:g, 2)(:e, 3)k]
rates = [2κ_p, 2κ_m, Γ, 0.3333333333333333Γ, 0.6666666666666666Γ, 0.06666666666666667Γ, 0.5333333333333333Γ, 0.4Γ, 0.2Γ, 0.6Γ, 0.2Γ, 0.4Γ, 0.5333333333333333Γ, 0.06666666666666667Γ, 0.6666666666666666Γ, 0.3333333333333333Γ, Γ]
ops =[a, b, sigma(:e, -3)(:e, -3)j, sigma(:e, -3)(:e, -1)j, sigma(:e, -3)(:e, 1)j, sigma(:e, -3)(:e, 3)j, sigma(:e, -2)(:e, -2)j, sigma(:e, -2)(:e, 0)j, sigma(:e, -2)(:e, 2)j, sigma(:e, -1)(:e, -1)j, sigma(:e, -1)(:e, 1)j, sigma(:e, -1)(:e, 3)j, sigma(:e, 0)(:e, 0)j, sigma(:e, 0)(:e, 2)j, sigma(:e, 1)(:e, 1)j, sigma(:e, 1)(:e, 3)j, sigma(:e, 2)(:e, 2)j, sigma(:e, 3)(:e, 3)j, (1+-1*(sigma(:g, -1)(:g, -1)j)+-1*(sigma(:g, 0)(:g, 0)j)+-1*(sigma(:g, 1)(:g, 1)j)+-1*(sigma(:g, 2)(:g, 2)j)+-1*(sigma(:e, -3)(:e, -3)j)+-1*(sigma(:e, -2)(:e, -2)j)+-1*(sigma(:e, -1)(:e, -1)j)+-1*(sigma(:e, 0)(:e, 0)j)+-1*(sigma(:e, 1)(:e, 1)j)+-1*(sigma(:e, 2)(:e, 2)j)+-1*(sigma(:e, 3)(:e, 3)j)), sigma(:g, -2)(:g, 0)j, sigma(:g, -2)(:g, 2)j, sigma(:g, -1)(:g, -1)j, sigma(:g, -1)(:g, 1)j, sigma(:g, 0)(:g, 0)j, sigma(:g, 0)(:g, 2)j, sigma(:g, 1)(:g, 1)j, sigma(:g, 2)(:g, 2)j, sigma(:g, -2)(:e, -3)j, sigma(:g, -2)(:e, -1)j, sigma(:g, -2)(:e, 1)j, sigma(:g, -2)(:e, 3)j, sigma(:g, -1)(:e, -2)j, sigma(:g, -1)(:e, 0)j, sigma(:g, -1)(:e, 2)j, sigma(:g, 0)(:e, -3)j, sigma(:g, 0)(:e, -1)j, sigma(:g, 0)(:e, 1)j, sigma(:g, 0)(:e, 3)j, sigma(:g, 1)(:e, -2)j, sigma(:g, 1)(:e, 0)j, sigma(:g, 1)(:e, 2)j, sigma(:g, 2)(:e, -3)j, sigma(:g, 2)(:e, -1)j, sigma(:g, 2)(:e, 1)j, sigma(:g, 2)(:e, 3)j]
eqs = meanfield(ops,H,L;rates=rates,order=1)

I would be greatful for some help. Thanks.

PS:

  • for me There was a problem using Jupyter Notebooks with Complete(eqs) because of some Parsing error (ParseError: KaTeX parse error)- incase someone runs into the same problem - just use a .jl
@david-pl
Copy link
Member

Could you provide a complete code snippet that reproduces this error? That should make it easier to debug. Thanks!

@DerElec
Copy link
Author

DerElec commented Nov 29, 2024

Sure Thing !

Actually, while preparing the code snippet, I found the error source. The scale(eqs) function seems to be working just fine for given operators like this

 ops_cav=[a,b];ops_at_examples=[sigma((:g, 2), (:e, 3),j)];ops=vcat(ops_cav,ops_at_examples);
eqs = meanfield(ops,H,L;rates=rates,order=1); eqs=complete(eqs);eqs=scale(eqs,h=h_atom) #working

But as soon as I hand it the ground state to ground state transition sigma((:g, -2), (:g, -2),j) the Error appears. I'm not sure if I just didn't check the documentation properly, but this should causees the problem. (Error is at the very bottom of the snippet)

Here is the code snippet I prepared


using QuantumCumulants
hbar,kappa_p,kappa_m, Gamma,delta_p,delta_a,delta_b, eta_p,eta_m,N,g0= cnumbers("ℏ κ_p κ_m Γ δ A B η_p η_m N g0")

const F = 2        
const F_prime =3   

hbar=1

#creates array of sublevels
function create_atomic_array(F::Int)
    return collect(-F:F)
end

ground_levels=create_atomic_array(F)           
excited_levels=create_atomic_array(F_prime)    
levels = vcat(ground_levels, excited_levels)




function create_atomic_levels_symbolic(F::Int, state_label::Symbol)
    return [(state_label, m) for m in collect(-F:F)]
end

ground_levels_symbolic = create_atomic_levels_symbolic(F, :g)
excited_levels_symbolic = create_atomic_levels_symbolic(F_prime, :e)

levels_symbolic = vcat(ground_levels_symbolic, excited_levels_symbolic)

h_cav_p = FockSpace(:cavity_p)  # Hilbert space for mode a₊
h_cav_m = FockSpace(:cavity_m)  # Hilbert space for mode a₋
h_atom = NLevelSpace(:atom,levels_symbolic)


h = tensor(h_cav_p,h_cav_m,h_atom)

sigma(α, β, k) = IndexedOperator(Transition(h,:σ,α,β,3), k)

j = Index(h,:j, N, h_atom)
k = Index(h,:k, N, h_atom)

@qnumbers a::Destroy(h,1)
@qnumbers b::Destroy(h,2)


H_cav = -hbar *(delta_p*a'*a+delta_p*b'*b)

H_pump=  hbar *1im*(eta_p*(a'-a) +eta_m*(b'-b))#*sqrt(N)

H_atom=0;
for m in ground_levels
    mp=m+1
    global H_atom-=hbar*delta_p*Σ(sigma((:g, m), (:e, mp),k)'*sigma((:g, m), (:e, mp),k),k)
    mp=m-1
    global H_atom-=hbar*delta_p*Σ(sigma((:g, m), (:e, mp),k)'*sigma((:g, m), (:e, mp),k),k)
end

H_0=H_cav+H_pump+H_atom;


H_int = 0
for m in ground_levels
    mp = m + 1
    if mp in excited_levels
        global H_int += 1im * hbar * Σ(a' * sigma((:g, m), (:e, mp),k) - a * sigma((:g, m), (:e, mp),k)',k)
    end
    mp = m - 1
    if mp in excited_levels
        global H_int += 1im * hbar * Σ(b' * sigma((:g, m), (:e, mp),k) - b * sigma((:g, m), (:e, mp),k)',k)
    end
end
H = H_0+H_int;

L_cav=[a,b];
rates_cav=[2*kappa_p,2*kappa_m];

L_at= [];
rates_at=[];

for a in excited_levels
    for b in ground_levels
        if (abs(a-b)==1 || abs(a-b)==0)
            push!(L_at,sigma((:g, b), (:e, a),k))
            push!(rates_at,Gamma)
        end
    end
end

#correct
function tupel_existiert_unordered(arr, tup)
    return any(t -> (t[1] == tup[1] && t[2] == tup[2]) || (t[1] == tup[2] && t[2] == tup[1]), arr)

end

function tupel_existiert_ordered(arr, tup)
    # Überprüft, ob das geordnete Tupel existiert
    return any(t -> t[1] == tup[1] && t[2] == tup[2], arr)
end



#ops_cav=[a,b,a'a,b'b]
ops_cav=[a,b]
ops_at=[]
known_transitions_ee = []
known_transitions_gg = []
known_transitions_ge = []
known_transitions_eg = []

u0=Complex{Float64}[0.0 + 0im ,0.0 + 0im ]

#transitions from excited to excited
for e1 in excited_levels
    for e2 in excited_levels
        if (abs(e1-e2)==0 || iseven(abs(e1-e2))) && !tupel_existiert_unordered(known_transitions_ee, [e1, e2]) 
            push!(ops_at,sigma((:e, e1), (:e, e2),j))
            push!(known_transitions_ee,[e1,e2])

            if e1==e2 && e1==2
                push!(u0,1.0 + 0im)
            else
                push!(u0,0.0 + 0im)
            end
        end
    end
end

#transitions from ground to ground
for e1 in ground_levels
    for e2 in ground_levels
        if (abs(e1-e2)==0 || iseven(abs(e1-e2))) && !tupel_existiert_unordered(known_transitions_gg, [e1, e2]) 
            if e1==e2 && e2==-2
                print("catch") # catch block for the case ground to ground transition because the error appears with it 
            else
                push!(ops_at,sigma((:g, e1), (:g, e2),j))
                push!(known_transitions_gg,[e1,e2])
            end
            push!(u0,0.0 + 0im)
        end
    end
end


#transitions from ground to excited
for e1 in ground_levels
    for e2 in excited_levels
        if  isodd(abs(e1-e2))  && !tupel_existiert_ordered(known_transitions_ge, [e1, e2]) 
            push!(ops_at,sigma((:g, e1), (:e, e2),j))
            push!(known_transitions_ge,[e1,e2])
            push!(u0,0.0 + 0im)
        end    
    end
end


ops=vcat(ops_cav,ops_at) # problematic conditions appear if sigma(:g,-2,:g,-2,j) is added to this object
#ops=vcat(ops_cav,ops_at,sigma((:g, -2), (:g, -2),j)) <----------- causes error
L=vcat(L_cav,L_at);
rates=vcat(rates_cav,rates_at);

eqs = meanfield(ops,H,L;rates=rates,order=1); #working
eqs = complete(eqs);

###############################
eqs = scale(eqs,h=h_atom)

@david-pl
Copy link
Member

I'm not at a computer right now, so I can't say for sure, but that statement has me suspicious:

But as soon as I hand it the ground state to ground state transition sigma((:g, -2), (:g, -2),j) the Error appears.

You don't need to include the ground state projector as it can simply be computed as 1 - sigma(:e, :e) due to the conservation of probability. In fact, that's what QuantumCumulants.jl rewrites ground state projectors to since it allows you to eliminate the equation of motion for the ground state of every atom.

So here's what I think happens: when you add the ground state projector to the list of operators, it gets written as the above expression. That means you end up trying to derive an equation for an addition, which it can't deal with properly. And then you end up with this completely unhelpful error message (sorry about that).

To fix it, have a look at the ground state sigmas to verify whether it gets rewritten as sum of other projectors. If that's the case, then exclude them from the list of operators, they shouldn't be required in order to complete the set of equations and compute the dynamics. You can then compute the ground state expectation values afterwards from the sum over all other level projectors (see also https://qojulia.github.io/QuantumCumulants.jl/dev/implementation/#Operator-expressions-and-commutation-relations).

I hope that fixes the issue.

@DerElec
Copy link
Author

DerElec commented Nov 29, 2024

Yes it does. Thanks!

@DerElec DerElec closed this as completed Nov 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants