I added GreensMatrix and dagger to make it easier to deal with c^\dagger c and c c^\dagger with various indices, but it's still not very intuitive.
First of all dagger doesn't do what the name implies - it doesn't generate G[i, j]^\dagger = c_j c_i^\dagger = \delta_{i, j} - c_i^\dagger c_j but c_i^\dagger c_j.
While GreensMatrix and dagger keep track of time slice indices and take them into account, the order of them switches between the two. They also can't be used as indices.
I think it would be much more intuitive if we had a Notion of Operator pairs, i.e. a create(site_index, time_slice) and a annihilate(site_index, time_slice). I think dealing creation vs annihilation operators and site indices should be relatively easy. Time slices may be more difficult since they are either both 0 (though they could be any legal integer as long as they're the same), or one is free (l) and the other is 0. Which time slice indices are legal needs to somehow be declared by the iterator.
Implementation wise operators like these could essentially act as indices. It might be good to have a macro to keep the notation clean and avoid run-time work, e.g.
src, trg = packed_indices
l = Var(l)
@operator_expr packed_greens begin
create(src, l) annihilate(trg, 0) - annihilate(trg, l) create(src, 0)
end
I added
GreensMatrix
anddagger
to make it easier to deal withc^\dagger c
andc c^\dagger
with various indices, but it's still not very intuitive.First of all
dagger
doesn't do what the name implies - it doesn't generateG[i, j]^\dagger = c_j c_i^\dagger = \delta_{i, j} - c_i^\dagger c_j
butc_i^\dagger c_j
.While
GreensMatrix
anddagger
keep track of time slice indices and take them into account, the order of them switches between the two. They also can't be used as indices.I think it would be much more intuitive if we had a Notion of Operator pairs, i.e. a
create(site_index, time_slice)
and aannihilate(site_index, time_slice)
. I think dealing creation vs annihilation operators and site indices should be relatively easy. Time slices may be more difficult since they are either both 0 (though they could be any legal integer as long as they're the same), or one is free (l) and the other is 0. Which time slice indices are legal needs to somehow be declared by the iterator.Implementation wise operators like these could essentially act as indices. It might be good to have a macro to keep the notation clean and avoid run-time work, e.g.