示例#1
0
def GRAPE(param, model: MODEL, init=False):

    n_step = param['n_step']
    n_fid_eval = 0

    if init:
        # Random initialization
        model.update_protocol(
            np.random.uniform(-1.0, 1.0, size=param['n_step']))
        old_fid = model.compute_fidelity(protocol=model.protocol(),
                                         discrete=False)
        best_protocol = np.copy(model.protocol())

    else:
        # So user can feed in data say from a specific protocol
        raise NotImplementedError("yet to be implemented.")
        #old_fid = model.compute_fidelity(discrete=False)
        #best_protocol = np.copy(model.protocol())

    eta = 0.6  # initial learning rate

    n_fid_eval = 0
    fid_diff = 1.0
    while np.abs(fid_diff) > 1E-9 and n_fid_eval < param[
            'n_quench']:  # guaranteed to break but after very long time

        # compute protocol gradient
        protocol_gradient = model.compute_protocol_gradient()

        # normalise gradient
        protocol_gradient /= np.max(np.abs(protocol_gradient))
        # GD update rule
        new_protocol = model.protocol() + eta * protocol_gradient

        # impose boundedness condition
        ind_max = np.where(new_protocol > param['hx_max'])
        new_protocol[ind_max] = param['hx_max']

        ind_min = np.where(new_protocol < param['hx_min'])
        new_protocol[ind_min] = param['hx_min']

        ###
        fid = model.compute_fidelity(protocol=new_protocol, discrete=False)

        # if we overshoot, decrease step size, otherwise update protocol
        fid_diff = fid - old_fid
        if fid_diff < 0:
            eta *= 0.5
            print('overshot minimum:', n_fid_eval, eta, np.abs(fid_diff))
        else:
            # update protocol
            model.update_protocol(new_protocol)

        old_fid = fid.copy()
        n_fid_eval += 1

        print(fid)
        print(n_fid_eval, eta, fid_diff)

    return old_fid, model.protocol(), n_fid_eval
示例#2
0
def run_ES(parameters, model:MODEL, utils):
    
    n_step = parameters['n_step']
    n_protocol = 2**n_step
    exact_data = np.zeros((n_protocol,2), dtype=np.float64) # 15 digits precision

    b2_array = lambda n10 : np.array(list(np.binary_repr(n10, width=n_step)), dtype=np.int)
    st=time.time()
    # ---> measuring estimated time <---
    model.update_protocol(b2_array(0))
    psi = model.compute_evolved_state()
    model.compute_fidelity(psi_evolve=psi)
    model.compute_energy(psi_evolve=psi)
    print("Est. run time : \t %.3f s"%(0.5*n_protocol*(time.time()-st)))
    # ---> Starting real calculation <---

    st=time.time()
    for p in range(n_protocol):
        model.update_protocol(b2_array(p))
        psi = model.compute_evolved_state()
        exact_data[p] = (model.compute_fidelity(psi_evolve=psi), model.compute_energy(psi_evolve=psi))
    
    outfile = utils.make_file_name(parameters,root=parameters['root'])
    with open(outfile,'wb') as f:
        pickle.dump(exact_data, f, protocol=4)
    print("Total run time : \t %.3f s"%(time.time()-st))
    print("\n Thank you and goodbye !")
    f.close()
示例#3
0
def Gibbs_Sampling(param, model:MODEL): 
    # should also measure acceptance rate 

    Ti = param['Ti']
    beta = 1./Ti
    n_step = param['n_step']
    n_equilibrate = 10000
    n_auto_correlate = n_step*10 # should look at auto-correlation time !
    
    # initial random protocol
    model.update_protocol( np.random.randint(0, model.n_h_field, size=n_step) )
    old_fid = model.compute_fidelity()
    best_fid = old_fid

    for i in range(n_equilibrate):
        
        random_time = np.random.randint(0,n_step)
        current_hx = model.protocol_hx(random_time)
        model.update_hx(random_time, model.random_flip(random_time))

        new_fid = model.compute_fidelity()

        d_fid = new_fid - old_fid 

        if d_fid > 0. : # accept move
            old_fid = new_fid
        elif np.exp(beta*d_fid) > np.random.uniform() : # accept move
            old_fid = new_fid
        else: # reject move
            model.update_hx(random_time, current_hx)

    samples = []
    fid_samples = []
    energy_samples = []

    for i in range(n_sample):
        
        for j in range(n_auto_correlate):
            random_time = np.random.randint(0,n_step)
            current_hx = model.protocol_hx(random_time)
            model.update_hx(random_time, model.random_flip(random_time))

            new_fid = model.compute_fidelity()

            d_fid = new_fid - old_fid 

            if d_fid > 0. : # accept move
                old_fid = new_fid
            elif np.exp(beta*d_fid) > np.random.uniform() : # accept move
                old_fid = new_fid
            else: # reject move
                model.update_hx(random_time, current_hx)
        
        samples.append(np.copy(model.protocol()))
        fid_samples.append(model.compute_fidelity())
        energy_samples.append(model.compute_energy())
        
    return samples, fid_samples, energy_samples
示例#4
0
def SD_2SF_M0(param, model: MODEL, init_random=False):
    """Two spin flip stochastic descent in the M=0 sector
    """

    if model.n_h_field > 2:
        assert False, 'This works only for bang-bang protocols'

    n_step = param['n_step']
    n_fid_eval = 0
    n_visit = 1

    if init_random:
        # Random initialization
        tmp = np.ones(n_step, dtype=int)  # m = 0 state ...
        tmp[0:n_step // 2] = 0
        np.random.shuffle(tmp)

        model.update_protocol(tmp)
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())

    else:
        # So user can feed in data say from a specific protocol
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())

    x1_ar, x2_ar = np.triu_indices(n_step, 1)
    order = np.arange(0, x1_ar.shape[0], dtype=np.int)

    while True:  # careful with this. For binary actions, this is guaranteed to break

        np.random.shuffle(order)
        local_minima = True

        for pos in order:
            t1, t2 = (x1_ar[pos], x2_ar[pos])

            if model.protocol_hx(t1) != model.protocol_hx(t2):
                model.swap(t1, t2)
                new_fid = model.compute_fidelity()
                n_fid_eval += 1

                if new_fid > old_fid:  # accept descent
                    #print("%.15f"%new_fid,'\t',n_fid_eval)
                    old_fid = new_fid
                    n_visit += 1
                    #best_protocol = np.copy(model.protocol())
                    local_minima = False  # will exit for loop before it ends ... local update accepted
                    break
                else:
                    model.swap(t1, t2)

        if local_minima:
            break

    return old_fid, np.copy(model.protocol()), n_fid_eval, n_visit
示例#5
0
def SD(param, model: MODEL, init_random=False):
    """ Single spin flip stochastic descent
    """

    n_step = param['n_step']
    n_fid_eval = 1
    n_visit = 1

    if init_random:
        # Random initialization
        model.update_protocol(
            np.random.randint(0, model.n_h_field, size=n_step))
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())
    else:
        # So user can feed in data say from a specific protocol
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())

    random_position = np.arange(n_step, dtype=int)
    fid_series = [old_fid]

    while True:

        np.random.shuffle(random_position)
        local_minima_reached = True  # trick

        for t in random_position:

            model.update_hx(t,
                            model.protocol_hx(t) ^ 1)  # assumes binary fields
            new_fid = model.compute_fidelity()
            n_fid_eval += 1
            fid_series.append(old_fid)

            if new_fid > old_fid:  # accept descent
                old_fid = new_fid
                n_visit += 1
                local_minima_reached = False
                break
            else:
                model.update_hx(t,
                                model.protocol_hx(t)
                                ^ 1)  # assumes binary fields

        if local_minima_reached:
            break

    return old_fid, np.copy(model.protocol()), n_fid_eval, n_visit, fid_series
示例#6
0
def SA(param, model: MODEL):

    Ti = param['Ti']
    n_quench = param['n_quench']
    if n_quench == 0:
        return
    n_step = param['n_step']

    # initial random protocol
    model.update_protocol(np.random.randint(0, model.n_h_field, size=n_step))
    old_fid = model.compute_fidelity()
    best_fid = old_fid
    best_protocol = np.copy(model.protocol())

    T = Ti
    step = 0
    r = 0
    while T > 1e-12:
        beta = 1. / T

        #  --- ---> single spin flip update <--- ---
        random_time = np.random.randint(0, n_step)
        current_hx = model.protocol_hx(random_time)
        model.update_hx(random_time, model.random_flip(random_time))
        #  --- --- --- --- --- --- --- --- --- ---

        new_fid = model.compute_fidelity()

        if new_fid > best_fid:
            best_fid = new_fid
            best_protocol = np.copy(
                model.protocol())  # makes an independent copy !

        d_fid = new_fid - old_fid

        if d_fid > 0.:  # accept move
            old_fid = new_fid
        elif np.exp(beta * d_fid) > np.random.uniform():  # accept move
            old_fid = new_fid
        else:  # reject move
            r += 1
            model.update_hx(random_time, current_hx)

        step += 1
        T = Ti * (1.0 - step / n_quench)

    print(1 - r / n_quench)
    return best_fid, best_protocol, n_quench
示例#7
0
def compute_initial_Ti(param, model:MODEL, n_sample = 100, rate = 0.8):
    # OK how is this acceptable ? >>>>>>> not tested at all <<<<<<<<
    # Estimates the high-temperature limit (where the acceptance rate is 99 the average worst case excitations %) 

    n_step = param['n_step']
    dF_mean = []

    for _ in range(n_sample):
        model.update_protocol( np.random.randint(0, model.n_h_field, size=n_step) )
        old_fid = model.compute_fidelity()
        rand_pos = np.random.randint(n_step)
        model.update_hx(rand_pos, model.random_flip(rand_pos))
        dF = model.compute_fidelity()-old_fid
        if dF < 0: 
            dF_mean.append(dF)
    
    return np.mean(dF_mean)/ np.log(rate)
示例#8
0
def sample_m0(n_sample, n_step, model: MODEL):
    X = np.empty((n_sample, n_step), dtype=int)
    y = np.zeros(n_sample)
    tmp = np.ones(n_step, dtype=int)  # m = 0 state ...
    tmp[0:n_step // 2] = 0
    np.random.shuffle(tmp)
    for i in range(n_sample):
        X[i] = tmp
        model.update_protocol(tmp)
        y[i] = model.compute_fidelity()
        np.random.shuffle(tmp)
    return X, y
示例#9
0
def SD(param, model: MODEL, init=False):

    n_step = param['n_step']
    n_fid_eval = 0

    if init:
        # Random initialization
        model.update_protocol(
            np.random.randint(0, model.n_h_field, size=n_step))
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())
    else:
        # So user can feed in data say from a specific protocol
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())

    while True:  # careful with this. For binary actions, this is guaranteed to break

        random_position = np.arange(n_step, dtype=int)
        np.random.shuffle(random_position)

        local_minima = True
        for t in random_position:
            model.update_hx(t, model.random_flip(t))
            new_fid = model.compute_fidelity()
            n_fid_eval += 1

            if new_fid > old_fid:  # accept descent
                old_fid = new_fid
                best_protocol = np.copy(model.protocol())
                local_minima = False  # will exit for loop before it ends ... local update accepted
                break
            else:
                model.update_hx(t, model.random_flip(t))

        if local_minima:
            break

    return old_fid, best_protocol, n_fid_eval
示例#10
0
def main():

    # Reading parameters from para.dat file
    parameters = utils.read_parameter_file()
    
    # Printing parameters for user
    utils.print_parameters(parameters)

    # Defining Hamiltonian
    H = HAMILTONIAN(**parameters)

    # Defines the model, and precomputes evolution matrices given set of states
    model = MODEL(H, parameters)
    
    L = 6
    T = 0.1
    n_step = 28 
    param = {'L' : L, 'T': T, 'n_step': n_step}
    file_name = make_file_name(param, root= "/projectnb/fheating/SGD/ES/dynamicQL/SA/ES/data/")

    with open(file_name, 'rb') as f:
	    fidelities=pickle.load(f)

    nfid=fidelities.shape[0]
    fid_and_energy=np.empty((nfid,2),dtype=np.float)

    for i,f in zip(range(nfid),fidelity):
        if i%10000 == 0: print(i)
        model.update_protocol(b2_array(i, w = 28))
        psi = model.compute_evolved_state()
        fid_and_energy[i][0]=model.compute_fidelity(psi_evolve = psi)
        fid_and_energy[i][1]=model.compute_energy(psi_evolve = psi)
        print(fid_and_energy[0],'\t',f)
        break

    with open("ES_L-06_T-0.500_n_step-28-test.pkl", ‘wb’) as f:
	    fidelities=pickle.dump(fid_and_energy,f, protocol=4)
示例#11
0
def SD_2SF(param, model:MODEL, init_random=False):
    # 2 spin flip algorithm --> note that scaling is O(N^3) so can only deal with n_step < 500 or so !

    if model.n_h_field > 2:
        assert False, 'This works only for bang-bang protocols'
    
    n_step = param['n_step']
    n_fid_eval = 0
    n_visit = 1

    if init_random:
        # Random initialization
        model.update_protocol( np.random.randint(0, model.n_h_field, size=n_step) )
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())
    else:
        # So user can feed in data say from a specific protocol
        old_fid = model.compute_fidelity()
        best_protocol = np.copy(model.protocol())

    x1_ar, x2_ar = np.triu_indices(n_step,1)

    n_2F_step = x1_ar.shape[0] # number of possible 2-flip updates
    order2F = np.arange(0,n_2F_step, dtype=np.int) # ordering sequenc // to be randomly shuffled

    n_1F_step = n_step
    order1F = np.arange(0,n_1F_step, dtype=np.int) # ordering sequenc // to be randomly shuffled

    order1F_vs_2F = 2*np.ones(n_2F_step + n_1F_step, dtype=np.int)
    order1F_vs_2F[:n_1F_step]=1
    

    ############################
    #########################
    while True: # careful with this. For binary actions, this is guaranteed to break

        np.random.shuffle(order1F)
        np.random.shuffle(order2F)
        np.random.shuffle(order1F_vs_2F)
        idx_1F=0
        idx_2F=0

        local_minima_reached = True

        for update_type in order1F_vs_2F:
            
            if update_type == 1:    
                # perform 1 SF update
                t = order1F[idx_1F]
                model.update_hx(t, model.protocol_hx(t)^1) # assumes binary fields
                new_fid = model.compute_fidelity()
                n_fid_eval +=1
                idx_1F+=1

                if new_fid > old_fid : # accept descent
                    #print("%.15f"%new_fid,'\t',n_fid_eval)
                    n_visit+=1
                    old_fid = new_fid
                    local_minima_reached = False # will exit for loop before it ends ... local update accepted
                    break
                else:
                    model.update_hx(t, model.protocol_hx(t)^1)
            else:
                # perform 2 SF update
                o2F=order2F[idx_2F]
                t1,t2 = x1_ar[o2F],x2_ar[o2F]
                model.update_hx(t1, model.protocol_hx(t1)^1) # assumes binary fields
                model.update_hx(t2, model.protocol_hx(t2)^1)
                new_fid = model.compute_fidelity()
                n_fid_eval +=1
                idx_2F+=1

                if new_fid > old_fid : # accept descent
                    #print("%.15f"%new_fid,'\t',n_fid_eval)
                    n_visit+=1
                    old_fid = new_fid
                    local_minima_reached = False # will exit for loop before it ends ... local update accepted
                    break
                else:
                    model.update_hx(t1, model.protocol_hx(t1)^1) # assumes binary fields
                    model.update_hx(t2, model.protocol_hx(t2)^1)

        if local_minima_reached:
            break

    return old_fid, np.copy(model.protocol()), n_fid_eval, n_visit