TRIQS / triqs

a Toolbox for Research on Interacting Quantum Systems
https://triqs.github.io
GNU General Public License v3.0
141 stars 72 forks source link

Access of Block Green's functions #773

Closed chuffa closed 4 years ago

chuffa commented 4 years ago

I am currently trying to symmetrize a Block Green's function, where the symmetrization is a little more complicated than just up-down. In failing to do so for quite some time, I realized that the access and modification of Greens functions are in my opinion very unintuitive when paired with iteration over the blocks (see example below). Most possibilities of how to modify a Green's function I could come up with do not work and it is very unclear to me why this is the case.

I also compared to numpy arrays and dicts and found that most of what is so unintuitive work with these objects.


import matplotlib.pyplot as plt
import numpy as np
from pytriqs.gf import *

Norbs = 2

# initialize some GFs "dup", "ddn" and a BlockGf "Delta"
wmin = -8
wmax = 8
nw = 1001
dup = GfReFreq(indices = [0,1], window = (wmin, wmax), n_points =  nw, name = "up")
ddn = GfReFreq(indices = [0,1], window = (wmin, wmax), n_points =  nw, name = "dn")
dup['0','0'] << SemiCircular(half_bandwidth = 6)*3./2.
ddn['0','0'] << SemiCircular(half_bandwidth = 6)*3./2.
dup['1','1'] << SemiCircular(half_bandwidth = 0.3, chem_potential=5)*0.001
ddn['1','1'] << SemiCircular(half_bandwidth = 0.3, chem_potential=5)*0.001
Delta = BlockGf(name_list = ('up','dn'), block_list = (dup,ddn), make_copies = True)

# plot gf before trying the change
plt.figure()
plt.subplot(1,2,1)
for i in range(Norbs):
    for j in range(Norbs):
        plt.plot(Delta['up'][i,j].imag.data)

# here are most of the possibilities how to change the GF I could come up with
for name, delta in Delta:
    delta = ddn # does not work ...  I dont like it but thats python (as far as I understand). Out of curiosity would it be possible to make this work?
    # delta[:] = dup[:] # does not work and fails with error, possible with numpy arrays though, i.e.: "x[:] = y[:]", but I personaly would never use it anyways.

    # delta << dup # does not work, I do not understand why.
    # delta[:,:] = dup[:,:] # does not work, I do not understand why. This should definetly work imho because of how test1 works + element wise it does do the correct thing (see below).
    # delta[:,:] << dup[:,:] # does not work, I do not understand why. Simliar to above, imho it should work.

    #delta[0,0] << dup[1,1] # this does work
    #delta[0,0] = dup[1,1]  # this does work

# plot gf after change
plt.subplot(1,2,2)
for i in range(Norbs):
    for j in range(Norbs):
        plt.plot(Delta['up'][i,j].imag.data)

def test1():
    # checks how iteration and array access work for dicts and numpy arrays.
    fill =  [555,555] 
    fillArr = np.array( [[7,7],[7,7]] )

    # dict iteration shows that accessing elements allows to change content
    mydict = { 'a' : [0,1], 'b' : [2,3] }
    for key, val in mydict.items():
        val[:] = fill[:]
    print(mydict)

    # array iteration, shows that accessing elements allows to change content
    myarray = np.zeros( (2,2) )
    for vec in myarray:
        vec[:] = fill[:]
    print(myarray)

    # array single-colon access allows to change content
    myarray = np.zeros( (2,2) )
    myarray[:] = fillArr[:]
    print(myarray)

    # array double-colon access allows to change content
    myarray = np.zeros( (2,2) )
    myarray[:,:] = fillArr[:,:]
    print(myarray)
Wentzell commented 4 years ago

Dear @chuffa,

The syntax delta << dup should already work now. I have tried your example and it works for me using triqs@2.2.x

I have further fixed the g[:] = ... syntax and added a test in ddb1f8b. These changes are available on triqs/unstable.

chuffa commented 4 years ago

Oh... that's weird, you are right most of them actually work. I made sure they don't do what I expect, but that does not help much when my expectations are wrong from the start ...

Sorry about that.

Wentzell commented 4 years ago

@chuffa can we close this?