To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

mutual_information.py 6.43 KB
Newer Older
mgassner's avatar
mgassner committed
1
from ast import parse
mgassner's avatar
mgassner committed
2
3
4
5
6
7
8
9
import numpy as np
import yaml
import time
import matplotlib.pyplot as plt

from create_model import spin_model
from entropy_new import compute_MI, compute_entropy, reduced_dm

mgassner's avatar
mgassner committed
10
11
import argparse
parser = argparse.ArgumentParser()
mgassner's avatar
mgassner committed
12
13
parser.add_argument("--set_number_spins", "-d", dest='number_spins',type=int, required=False)
parser.add_argument("--set_param_range_and_steps", '-pr', dest='param_range', nargs='+', type=float)
mgassner's avatar
mgassner committed
14
parser.add_argument("--model_name", "-m", dest='model_name' ,type=str, required=True)
mgassner's avatar
mgassner committed
15
16
parser.add_argument("--set_spin_range", "-sr", dest='spin_range', nargs='+', type=int)
parser.add_argument("--set_param", "-p", dest='param',type=float, required=False)
mgassner's avatar
mgassner committed
17
18
args = parser.parse_args()

mgassner's avatar
mgassner committed
19
def test_mutual_information(param=0.5):
mgassner's avatar
mgassner committed
20
    # change return in compute_MI to run this function [S_A, S_B, S_AB] instead of S_A + S_B - S_AB
mgassner's avatar
mgassner committed
21
    model_name = 'xxz'
mgassner's avatar
mgassner committed
22
    number_spins = 8
mgassner's avatar
mgassner committed
23
24
    periodic = False
    spin_inversion = None
mgassner's avatar
mgassner committed
25
    hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
26
27
28
29
    model = spin_model(model_name=model_name, number_spins=number_spins, periodic=periodic, 
                            param=param, hamming_weight=hamming_weight ,spin_inversion=spin_inversion)
    model.compute_ew_and_ev()
    print('EIGENSTATE at h/J = ', param, 'is: ', model.eigenstates[:,0])
mgassner's avatar
mgassner committed
30
31
    sub_dim = 2
    first_trace_spin = 2
mgassner's avatar
mgassner committed
32
33
34
35
36
37
    basis_states = model.basis.states
    gs = model.eigenstates[:,0]
    print('Number Spins: ', model.basis.number_spins)
    print('States', model.basis.states)
    print('Sub Dimension is ', sub_dim)
    entropies = compute_MI(sub_dim, number_spins, hamming_weight, gs, basis_states, spin_inversion=None, first_trace_spin=first_trace_spin)
mgassner's avatar
mgassner committed
38
    """MI = entropies[0] + entropies[1] - entropies[2]
mgassner's avatar
mgassner committed
39
40
41
42
    print(MI)
    print(entropies)
    print('--------------------Test-----------------------')
    rhos4 = reduced_dm(4, number_spins, hamming_weight, gs, basis_states)
mgassner's avatar
mgassner committed
43
    rhos6 = reduced_dm(6, number_spins, hamming_weight, gs, basis_states)
mgassner's avatar
mgassner committed
44
45
    print(compute_entropy(rhos4), compute_entropy(rhos6))"""
    print(entropies[2])
mgassner's avatar
mgassner committed
46

mgassner's avatar
mgassner committed
47
def MI_vs_Entropy(model_name, number_spins, param_range):
mgassner's avatar
mgassner committed
48

mgassner's avatar
mgassner committed
49
    model_name = model_name
mgassner's avatar
mgassner committed
50
    number_spins = number_spins
mgassner's avatar
mgassner committed
51
    periodic = False
mgassner's avatar
mgassner committed
52
    params = np.linspace(param_range[0], param_range[1], int(param_range[2]))
mgassner's avatar
mgassner committed
53

mgassner's avatar
mgassner committed
54
55
56
57
    sub_dim = 2
    first_trace_spin = 2
    S_As = []
    S_ABs = []
mgassner's avatar
mgassner committed
58
    MIs = []
mgassner's avatar
mgassner committed
59
    print('Number Spins: ', number_spins)
mgassner's avatar
mgassner committed
60
61
    print('Sub Dimension is ', sub_dim)
    for param in params:
mgassner's avatar
mgassner committed
62
63
64
65
        if param < -1.0:
            hamming_weight = None
        else: 
            hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
66
        model = spin_model(model_name=model_name, number_spins=number_spins, periodic=periodic, 
mgassner's avatar
minor    
mgassner committed
67
                            param=param, hamming_weight=hamming_weight)
mgassner's avatar
mgassner committed
68
69
70
        model.compute_ew_and_ev()
        basis_states = model.basis.states
        gs = model.eigenstates[:,0]
mgassner's avatar
mgassner committed
71
72
73
74
        S_A, S_B, S_AB = compute_MI(sub_dim, number_spins, hamming_weight, gs, basis_states, spin_inversion=None, first_trace_spin=first_trace_spin)
        S_As.append(S_A)
        S_ABs.append(S_AB)
        MIs.append(S_A+S_B-S_AB)
mgassner's avatar
mgassner committed
75
        del model
mgassner's avatar
mgassner committed
76

mgassner's avatar
mgassner committed
77
78
79
80
81
82
    data = {
        'Model': model_name,
        'Number_spins': number_spins,
        'Periodic': periodic,
        'Hamming_weight': hamming_weight,
        'Sub_dim': sub_dim,
mgassner's avatar
mgassner committed
83
        'Delta or h over J': params.tolist(),
mgassner's avatar
mgassner committed
84
85
86
        'Mutual Informations': np.array(MIs).tolist(),
        'Entropy of A': np.array(S_As).tolist(),
        'Entropy of AuB': np.array(S_ABs).tolist()
mgassner's avatar
mgassner committed
87
88
89
90
91
92
93
94
95
    }

    timestr = time.strftime("%Y%m%d-%H%M%S")
    filename = 'MI_fixed_dim' + timestr
    with open('output/' + filename + '.yaml', 'w') as outfile:
        yaml.dump(data, outfile, default_flow_style=False)
    print(filename)

    plt.figure(figsize=(12,12))
mgassner's avatar
mgassner committed
96
    plt.title('MI: ' + model_name + ' ' + str(number_spins) + ' ' + str(periodic))
mgassner's avatar
mgassner committed
97
    plt.plot(params, MIs, label='rho_AB')
mgassner's avatar
mgassner committed
98
99
    plt.grid(True)
    plt.legend()
mgassner's avatar
mgassner committed
100
101
    plt.savefig('output/' + filename + '.png')

mgassner's avatar
mgassner committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def MutInf(model_name, param, spin_range):

    model_name = model_name
    periodic = False
    spin_inversion = None
    sub_dim = 4
    first_trace_spin = 4
    MIs = []
    Entropies = []
    Entropies_div_ns = []
    number_spins_range = [2*i for i in range(spin_range[0]//2, spin_range[1]//2 + 1)]
    for number_spins in number_spins_range:
        print('Number Spins: ', number_spins)
        print('Sub Dimension is ', sub_dim)
mgassner's avatar
mgassner committed
116
        if param < -1.0 or model_name == 'tfim': 
mgassner's avatar
mgassner committed
117
            hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
118
        else: 
mgassner's avatar
mgassner committed
119
            hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

        model = spin_model(model_name=model_name, number_spins=number_spins, periodic=periodic, 
                            param=param, hamming_weight=hamming_weight ,spin_inversion=spin_inversion)
        model.compute_ew_and_ev()
        basis_states = model.basis.states
        gs = model.eigenstates[:,0]
        MI = compute_MI(sub_dim, number_spins, hamming_weight, gs, basis_states, spin_inversion=None, first_trace_spin=first_trace_spin)
        MIs.append(MI/sub_dim)
        rho_half = reduced_dm(number_spins // 2, number_spins, hamming_weight, gs, basis_states)
        Entropies.append(compute_entropy(rho_half))
        Entropies_div_ns.append(Entropies[-1]/number_spins)
        del model

    data = {
        'Model': model_name,
        'Number_spins': number_spins_range,
        'Periodic': periodic,
        'Hamming_weight': hamming_weight,
        'Sub_dim': sub_dim,
        'Delta or h over J': param,
mgassner's avatar
mgassner committed
140
141
        'Entropies': np.array(Entropies).tolist(),
        'Mutual Informations': np.array(MIs).tolist()
mgassner's avatar
mgassner committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    }

    timestr = time.strftime("%Y%m%d-%H%M%S")
    filename = 'MI_fixed_param' + timestr
    with open('output/' + filename + '.yaml', 'w') as outfile:
        yaml.dump(data, outfile, default_flow_style=False)
    print(filename)

    plt.figure(figsize=(12,12))
    plt.title('MI: ' + model_name + ' ' + str(param) + ' ' + str(periodic))
    plt.plot(number_spins_range, Entropies_div_ns, label='Half-chain Entropy / Spin-Chain-Length')
    plt.plot(number_spins_range, MIs, label='Mutual Information / SubDim--Length')
    plt.grid(True)
    plt.xlabel("Number Spins")
    plt.legend()
    plt.savefig('output/' + filename + '.png')


mgassner's avatar
mgassner committed
160
161
162
163
if __name__ == "__main__":
    model_name = args.model_name
    param_range = args.param_range
    number_spins = args.number_spins
mgassner's avatar
mgassner committed
164
165
    spin_range = args.spin_range
    param = args.param
mgassner's avatar
mgassner committed
166
    #test_mutual_information(param)
mgassner's avatar
mgassner committed
167
    MI_vs_Entropy(model_name, number_spins, param_range)
mgassner's avatar
mgassner committed
168
    #MutInf(model_name, param, spin_range)