mutual_information.py 6.71 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():
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
22
23
24
25
    model_name = 'xxz'
    number_spins = 10
    periodic = False
    spin_inversion = None
    param = 1.0
mgassner's avatar
mgassner committed
26
    hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    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])
    sub_dim = 4
    first_trace_spin = 4
    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)
    MI = entropies[0] + entropies[1] - entropies[2]
    print(MI)
    print(entropies)
    print('--------------------Test-----------------------')
    rhos4 = reduced_dm(4, number_spins, hamming_weight, gs, basis_states)
mgassner's avatar
mgassner committed
44
45
46
    rhos6 = reduced_dm(6, number_spins, hamming_weight, gs, basis_states)
    print(compute_entropy(rhos4), compute_entropy(rhos6))

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
    sub_dim = 4
    first_trace_spin = 4
mgassner's avatar
mgassner committed
56
57
    MIs = []
    Entropies = []
mgassner's avatar
mgassner committed
58
    Entropies4 = []
mgassner's avatar
mgassner committed
59
    hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
60
    print('Number Spins: ', number_spins)
mgassner's avatar
mgassner committed
61
62
    print('Sub Dimension is ', sub_dim)
    for param in params:
mgassner's avatar
mgassner committed
63
        model = spin_model(model_name=model_name, number_spins=number_spins, periodic=periodic, 
mgassner's avatar
minor    
mgassner committed
64
                            param=param, hamming_weight=hamming_weight)
mgassner's avatar
mgassner committed
65
66
67
        model.compute_ew_and_ev()
        basis_states = model.basis.states
        gs = model.eigenstates[:,0]
mgassner's avatar
mgassner committed
68
69
        half_dim = number_spins // 2
        rho_half = reduced_dm(half_dim, number_spins, hamming_weight, gs, basis_states)
mgassner's avatar
mgassner committed
70
        Entropies.append(compute_entropy(rho_half))
mgassner's avatar
mgassner committed
71
72
        rho_4spin = reduced_dm(4, number_spins, hamming_weight, gs, basis_states)
        Entropies4.append(compute_entropy(rho_4spin))
mgassner's avatar
mgassner committed
73
74
        MI = compute_MI(sub_dim, number_spins, hamming_weight, gs, basis_states, spin_inversion=None, first_trace_spin=first_trace_spin)
        MIs.append(MI)
mgassner's avatar
mgassner committed
75
        del model
mgassner's avatar
mgassner committed
76
        print(Entropies)
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
        'Entropies half chain': np.array(Entropies).tolist(),
        'Entropies 4 spin': np.array(Entropies4).tolist(),
        'Mutual Informations': np.array(MIs).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, Entropies, label='Half-chain Entropy')
mgassner's avatar
mgassner committed
98
    plt.plot(params, Entropies4, label='4 spin entropy')
mgassner's avatar
mgassner committed
99
100
101
    plt.plot(params, MIs, label='Mutual Information')
    plt.grid(True)
    plt.legend()
mgassner's avatar
mgassner committed
102
103
    plt.savefig('output/' + filename + '.png')

mgassner's avatar
mgassner committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
118
        if param < -1.0 or model_name == 'tfim': 
mgassner's avatar
mgassner committed
119
            hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
120
        else: 
mgassner's avatar
mgassner committed
121
            hamming_weight = number_spins // 2
mgassner's avatar
mgassner committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

        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
142
143
        'Entropies': np.array(Entropies).tolist(),
        'Mutual Informations': np.array(MIs).tolist()
mgassner's avatar
mgassner committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    }

    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
162
163
164
165
if __name__ == "__main__":
    model_name = args.model_name
    param_range = args.param_range
    number_spins = args.number_spins
mgassner's avatar
mgassner committed
166
167
    spin_range = args.spin_range
    param = args.param
mgassner's avatar
mgassner committed
168
169
    MI_vs_Entropy(model_name, number_spins, param_range)
    #MutInf(model_name, param, spin_range)