def suzuki_sampling(input_df, start_row, end_row, output_folder_path): df = input_df.copy() NUM_SAMPLES = 100 for row_id in range(start_row-1, end_row): row = df.loc[row_id] n = int(row['n']) v = row['v_1':'v_%d' % n] k = int(row['k']) r = int(row['r']) scale = float(row['scale']) cols = ['n'] + ['v_%d' % i for i in range(1, n+1)] + ['k', 'r', 'scale', 'sampled error', 'suzuki error'] row_df = pd.DataFrame(columns=cols) chain = hchain.HeisenbergChain(n, v) sample_length = (5**(k-1)) suzuki_vector = approx.suzuki(k) for _ in range(NUM_SAMPLES): noise = np.random.normal(loc=0, scale=scale/sample_length, size=sample_length) sample_vector = np.array(suzuki_vector) + noise sampled_err = approx.error(chain, approx.r_copies(sample_vector, r), t=2*n) suz_err = approx.error(chain, approx.suzuki_solution(k, r), t=2*n) row_df.loc[len(row_df)+1] = [n] + list(v) + [k, r, scale, sampled_err, suz_err] row_df.to_csv(os.path.join(output_folder_path, 'row_%d.csv'%(row_id+1)))
def testSuzuki(self): p_2 = 1 / (4 - 4**(1 / 3)) x = [p_2, p_2, 1 - 4 * p_2, p_2, p_2] self.assertTrue(np.allclose(x, approx.suzuki(2))) p_3 = 1 / (4 - 4**(1 / 5)) y = [ p_3 * p_2, p_3 * p_2, p_3 * (1 - 4 * p_2), p_3 * p_2, p_3 * p_2, p_3 * p_2, p_3 * p_2, p_3 * (1 - 4 * p_2), p_3 * p_2, p_3 * p_2, (1 - 4 * p_3) * p_2, (1 - 4 * p_3) * p_2, (1 - 4 * p_3) * (1 - 4 * p_2), (1 - 4 * p_3) * p_2, (1 - 4 * p_3) * p_2, p_3 * p_2, p_3 * p_2, p_3 * (1 - 4 * p_2), p_3 * p_2, p_3 * p_2, p_3 * p_2, p_3 * p_2, p_3 * (1 - 4 * p_2), p_3 * p_2, p_3 * p_2 ] self.assertTrue(np.allclose(y, approx.suzuki(3)))
def greedy(): """ Run greedy hillclimber. Enumerate neighbourhood and choose best. """ chain = hchain.HeisenbergChain(num_qubits, v) steps = [-step_size, 0, step_size] neighbourhood_size = len(steps)**num_p_values suzuki = np.array(approx.suzuki(k)) suzuki_error = approx.error(chain, approx.r_copies(suzuki, r), t) print('Suzuki error: {}'.format(suzuki_error)) # Start at Suzuki current = suzuki current_error = suzuki_error # Start at 1/p_length # current = np.array([0.2] * 5) # current_error = approx.error(chain, approx.r_copies(current, r), t) # Start at suzuki permutation # import random # random.seed(1234) # suzuki_coeff = approx.suzuki(k) # random.shuffle(suzuki_coeff) # current = np.array(suzuki_coeff) # current_error = approx.error(chain, approx.r_copies(current, r), t) for gen in range(1, gens+1): current_error_percent = 100 * (current_error / suzuki_error) print('Gen: {} Best: {} Percent: {} '.format(gen, current_error, current_error_percent)) all_neighbours = list(range(1, neighbourhood_size)) random.shuffle(all_neighbours ) for neighbour_index in all_neighbours: move = [step_size * (coeff - 1) for coeff in ternary(neighbour_index, num_p_values)] neighbour = current + move neighbour_err = approx.error(chain, approx.r_copies(neighbour, r), t) neighbour_err_percent = 100 * (neighbour_err / suzuki_error) print('Step {} Neighbour {}/{} error: {}, error %: {}'.format(gen, neighbour_index, neighbourhood_size, neighbour_err, neighbour_err_percent)) if neighbour_err < current_error: current = neighbour current_error = neighbour_err current_error_percent = 100 * (current_error / suzuki_error) print('New best: error: {} percent: {} solution: {})'.format(current_error, current_error_percent, current)) break
def run_cmaes_p(v, k, r, seed, generations, sig=None): suzuki = approx.suzuki(k) if sig == None: sig = 1e-5 / len(suzuki) chain = hchain.HeisenbergChain(len(v), v) random.seed(seed) np.random.seed(seed) # Error from target def target_error(ind): if NORMALISE: norm_ind = norm_f(ind) else: norm_ind = ind final_ind = approx.r_copies(ind, r) return approx.error(chain, final_ind, t=2 * chain.n), toolbox = base.Toolbox() toolbox.register("evaluate", target_error) strategy = cma.Strategy(centroid=suzuki, sigma=sig) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean) stats.register("std", np.std) stats.register("min", np.min) stats.register("max", np.max) pop, log = algorithms.eaGenerateUpdate(toolbox, ngen=generations, stats=stats, halloffame=hof, verbose=True) return pop, log, hof
def greedy(): """ Run greedy hillclimber. Enumerate neighbourhood and choose best. """ random.seed(1234) chain = hchain.HeisenbergChain(num_qubits, v) suzuki = np.array(approx.suzuki(k)) suzuki_error = approx.error(chain, approx.r_copies(suzuki, r), t) print('Suzuki error: {}'.format(suzuki_error)) # Start at Suzuki current = suzuki current_error = suzuki_error for gen in range(1, gens + 1): current_error_percent = 100 * (current_error / suzuki_error) print('Gen: {} Best: {} Percent: {} '.format(gen, current_error, current_error_percent)) first = random.randint(1, num_p_values) second = random.randint(1, num_p_values) neighbour = current.copy() neighbour[first - 1] = neighbour[first - 1] + step_size neighbour[second - 1] = neighbour[second - 1] - step_size neighbour_err = approx.error(chain, approx.r_copies(neighbour, r), t) neighbour_err_percent = 100 * (neighbour_err / suzuki_error) print('Step {} error: {}, error %: {}'.format(gen, neighbour_err, neighbour_err_percent)) if neighbour_err < current_error: current = neighbour current_error = neighbour_err current_error_percent = 100 * (current_error / suzuki_error) print('New best: error: {} percent: {} solution: {})'.format( current_error, current_error_percent, current))
def testExpandVals(self): for k in range(1, 10): suz1 = approx.suzuki(k) suz2 = approx.expand_vals(approx.suzuki_vals(k)) self.assertTrue(np.allclose(suz1, suz2))