Ejemplo n.º 1
0
def operations_dict_from_name(mod_name):
    constituents = model_building_utilities.get_constituent_names_from_name(
        mod_name)
    num_qubits = model_building_utilities.get_num_qubits(mod_name)
    initial_t_str = ""
    all_terms = []
    for j in range(num_qubits - 1):
        initial_t_str += "T"

    for i in range(len(constituents)):
        t_str = initial_t_str
        single_term = constituents[i]
        all_tuples_this_term = []
        n_minus_1_qubit_operators = single_term
        for k in range(num_qubits):
            if len(t_str) > 0:
                split_by_nth_qubit = n_minus_1_qubit_operators.split(t_str)
                this_tuple = (num_qubits - k, split_by_nth_qubit[1])
                n_minus_1_qubit_operators = split_by_nth_qubit[0]
                t_str = t_str[:-1]
            else:
                this_tuple = (num_qubits - k, n_minus_1_qubit_operators)

            all_tuples_this_term.append(this_tuple)

        all_tuples_this_term = sorted(all_tuples_this_term)
        all_terms.append(all_tuples_this_term)

    operations = {"dim": num_qubits, "terms": all_terms}

    return operations
Ejemplo n.º 2
0
    def __init__(self, exploration_rules, **kwargs):
        # print("[Exploration Strategies] init nv_spin_experiment_full_tree")
        super().__init__(exploration_rules=exploration_rules, **kwargs)
        # self.true_model = 'FHhop_1h2_up_d2'
        self.true_model = "FHhop_1h2_down_d3+FHhop_1h2_up_d3+FHhop_1h3_down_d3+FHhop_2h3_up_d3+FHonsite_1_d3+FHonsite_2_d3+FHonsite_3_d3"  # for testing
        self.tree_completed_initially = True
        self.initial_models = [self.true_model]
        # self.latex_string_map_subroutine = qmla.shared_functionality.latex_model_names.fermi_hubbard_latex
        self.system_probes_generation_subroutine = (
            qmla.shared_functionality.probe_set_generation.separable_fermi_hubbard_half_filled
        )
        # unless specifically different set of probes required
        self.simulator_probes_generation_subroutine = (
            self.system_probes_generation_subroutine
        )
        self.shared_probes = (
            True  # i.e. system and simulator get same probes for learning
        )
        self.plot_probes_generation_subroutine = (
            qmla.shared_functionality.probe_set_generation.fermi_hubbard_half_filled_superposition
        )
        # self.plot_probes_generation_subroutine = qmla.shared_functionality.probe_set_generation.FermiHubbard_single_spin_n_sites

        # self.max_time_to_consider = 20
        self.num_sites_true = model_building_utilities.get_num_qubits(self.true_model)
        self.num_qubits_true = (
            2 * self.num_sites_true
        )  # FH uses 2 qubits per sites (up and down spin)
        self.max_num_qubits = (self.num_sites_true * 2) + 2
        self.num_processes_to_parallelise_over = 9
        self.max_num_models_by_shape = {1: 0, 2: 0, 4: 10, 6: 1, "other": 0}
Ejemplo n.º 3
0
    def check_model_validity(self, model, **kwargs):
        # possibility that some models not valid; not needed by default but
        # checked for general case
        terms = model_building_utilities.get_constituent_names_from_name(model)

        if np.all(["FHhop" in a for a in terms]):
            return True
        elif np.all(["FHonsite" in a for a in terms]):
            # onsite present in all terms: discard
            # self.log_print(
            #     ["Rejecting model", model, "b/c all onsite terms"]
            # )
            return False
        else:
            hopping_sites = []
            number_term_sites = []
            chemical_sites = []
            num_sites = model_building_utilities.get_num_qubits(model)
            for term in terms:
                constituents = term.split("_")
                constituents.remove("d{}".format(num_sites))
                if "FHhop" in term:
                    constituents.remove("FHhop")
                    for c in constituents:
                        if "h" in c:
                            hopping_sites.extend(c.split("h"))
                elif "FHonsite" in term:
                    constituents.remove("FHonsite")
                    number_term_sites.extend(constituents)
                elif "FHchemical" in term:
                    constituents.remove("FHchemical")
                    chemical_sites.extend(constituents)

            #         print("hopping_sites:", hopping_sites)
            #         print('number term sites:', number_term_sites)
            hopping_sites = set(hopping_sites)
            number_term_sites = set(number_term_sites)
            overlap = number_term_sites.intersection(hopping_sites)

            if number_term_sites.issubset(hopping_sites):
                return True
            else:
                # no overlap between hopping sites and number term sites
                # so number term will be constant
                self.log_print(
                    [
                        "Rejecting model",
                        model,
                        "bc number terms present"
                        "which aren't present in kinetic term",
                    ]
                )
                return False
Ejemplo n.º 4
0
def check_model_in_dict(name, model_dict):
    """
    Check whether the new model, name, exists in all previously considered models,
        held in model_lists.
    [previously in construct_models]
    If name has not been previously considered, False is returned.
    """
    # Return true indicates it has not been considered and so can be added

    al_name = alph(name)
    n_qub = get_num_qubits(name)

    if al_name in model_dict[n_qub]:
        return True  # todo -- make clear if in legacy or running db
    else:
        return False
Ejemplo n.º 5
0
    def DEPRECATED_latex_name(self, name, **kwargs):
        # print("[latex name fnc] name:", name)
        core_operators = list(
            sorted(model_building_utilities.core_operator_dict.keys()))
        num_sites = model_building_utilities.get_num_qubits(name)
        try:
            p_str = "P" * num_sites
            separate_terms = name.split(p_str)
        except:
            p_str = "+"
            separate_terms = name.split(p_str)

        site_connections = {}
        for c in list(itertools.combinations(list(range(num_sites + 1)), 2)):
            site_connections[c] = []

        # term_type_markers = ['pauliSet', 'transverse']
        transverse_axis = None
        ising_axis = None
        for term in separate_terms:
            components = term.split("_")
            if "pauliSet" in components:
                components.remove("pauliSet")

                for l in components:
                    if l[0] == "d":
                        dim = int(l.replace("d", ""))
                    elif l[0] in core_operators:
                        operators = l.split("J")
                    else:
                        sites = l.split("J")
                sites = tuple([int(a) for a in sites])
                # assumes like-like pauli terms like xx, yy, zz
                op = operators[0]
                site_connections[sites].append(op)
            elif "1Dising" in components:
                components.remove("1Dising")
                for l in components:
                    if l[0] == "d":
                        dim = int(l.replace("d", ""))
                    elif l[0] == "i":
                        ising_axis = str(l.replace("i", ""))
                    elif l[0] == "t":
                        transverse_axis = str(l.replace("t", ""))
            elif "transverse" in components:
                components.remove("transverse")
                for l in components:
                    if l[0] == "d":
                        transverse_dim = int(l.replace("d", ""))
                    elif l in core_operators:
                        transverse_axis = l

        ordered_connections = list(sorted(site_connections.keys()))
        latex_term = ""

        for c in ordered_connections:
            if len(site_connections[c]) > 0:
                this_term = r"\sigma_{"
                this_term += str(c)
                this_term += "}"
                this_term += "^{"
                for t in site_connections[c]:
                    this_term += "{}".format(t)
                this_term += "}"
                latex_term += this_term
        if ising_axis is not None:
            this_term = r"\sigma_{"
            this_term += str(ising_axis)
            this_term += "}^{\otimes"
            this_term += str(dim)
            this_term += "}"
            latex_term += this_term
        if transverse_axis is not None:
            latex_term += "T_{}^{}".format(transverse_axis, dim)

        latex_term = "${}$".format(latex_term)
        return latex_term
Ejemplo n.º 6
0
 def num_qubits(self):
     """
     Number of qubits this operator acts on.
     """
     return get_num_qubits(self.name)
Ejemplo n.º 7
0
def r_squared_from_epoch_list(
    qmd,
    model_ids=[],
    epochs=[],
    min_time=0,
    max_time=None,
    save_to_file=None,
):
    exp_times = sorted(list(qmd.experimental_measurements.keys()))
    if max_time is None:
        max_time = max(exp_times)

    min_time = qmla.shared_functionality.experimental_data_processing.nearest_experimental_time_available(
        exp_times, 0
    )
    max_time = qmla.shared_functionality.experimental_data_processing.nearest_experimental_time_available(
        exp_times, max_time
    )
    min_data_idx = exp_times.index(min_time)
    max_data_idx = exp_times.index(max_time)
    exp_times = exp_times[min_data_idx:max_data_idx]
    exp_data = [qmd.experimental_measurements[t] for t in exp_times]
    # plus = 1/np.sqrt(2) * np.array([1,1])
    # probe = np.array([0.5, 0.5, 0.5, 0.5+0j]) # TODO generalise probe
    # picking probe based on model instead
    datamean = np.mean(exp_data[0:max_data_idx])
    datavar = np.sum((exp_data[0:max_data_idx] - datamean) ** 2)

    fig = plt.figure()
    ax = plt.subplot(111)
    model_ids = list(set(model_ids))
    for model_id in model_ids:
        mod = qmd.get_model_storage_instance_by_id(model_id)
        r_squared_by_epoch = {}

        mod_num_qubits = model_building_utilities.get_num_qubits(mod.model_name)
        probe = (
            qmla.shared_functionality.expectation_value_functions.n_qubit_plus_state(
                mod_num_qubits
            )
        )
        epochs.extend([0, qmd.num_experiments - 1])
        if len(mod.epochs_after_resampling) > 0:
            epochs.extend(mod.epochs_after_resampling)

        epochs = sorted(set(epochs))
        for epoch in epochs:
            # Construct new Hamiltonian to get R^2 from
            # Hamiltonian corresponds to parameters at that epoch
            ham = np.tensordot(
                mod.track_param_means[epoch], mod.model_terms_matrices, axes=1
            )
            sum_of_residuals = 0
            for t in exp_times:
                sim = qmd.exploration_class.expectation - value(
                    ham=ham, t=t, state=probe
                )
                true = qmd.experimental_measurements[t]
                diff_squared = (sim - true) ** 2
                sum_of_residuals += diff_squared

            Rsq = 1 - sum_of_residuals / datavar
            r_squared_by_epoch[epoch] = Rsq

        r_squareds = [r_squared_by_epoch[e] for e in epochs]

        plot_label = str(mod.model_name_latex)
        ax.plot(epochs, r_squareds, label=plot_label, marker="o")
    ax.legend(
        bbox_to_anchor=(1, 0.5),
    )
    ax.set_ylabel("$R^2$")
    ax.set_xlabel("Epoch")
    ax.set_title("$R^2$ Vs Epoch (with resampling epochs)")
    if save_to_file is not None:
        plt.savefig(save_to_file, bbox_inches="tight")
Ejemplo n.º 8
0
    def setup_models(self):

        self.available_lattices_by_name = {
            k: topology_predefined.__getattribute__(k) for k in self.lattice_names
        }
        self.available_lattices = [
            topology_predefined.__getattribute__(k) for k in self.lattice_names
        ]
        if self._shared_true_parameters:
            lattice_idx = -1
        else:
            lattice_idx = self.qmla_id % len(self.available_lattices)
        self.true_lattice_name = self.lattice_names[lattice_idx]

        self.true_lattice = self.available_lattices_by_name[self.true_lattice_name]
        self.true_model = self.model_from_lattice(self.true_lattice)
        # self.log_print(["QMLA {} using lattice {} (lattice idx {}) has model {}".format(self.qmla_id, self.true_lattice_name, lattice_idx, self.true_model)])
        self.max_num_qubits = 8
        self.max_num_probe_qubits = 8

        self.qhl_models = [self.model_from_lattice(l) for l in self.available_lattices]

        self.quantisation = "first"  # 'second
        if self.quantisation == "first":
            # probe transformer between formalisms - not used currently
            self.probe_transformer = (
                qmla.shared_functionality.probe_transformer.ProbeTransformation()
            )
            self.system_probes_generation_subroutine = (
                qmla.shared_functionality.probe_set_generation.separable_probe_dict
            )

        elif self.quantisation == "second":
            # Default for FH
            self.probe_transformer = (
                qmla.shared_functionality.probe_transformer.ProbeTransformation()
            )
            self.system_probes_generation_subroutine = (
                qmla.shared_functionality.probe_set_generation.separable_fermi_hubbard_half_filled
            )

        # TODO plot probe dict with meaningful probes wrt FH model
        self.plot_probes_generation_subroutine = (
            qmla.shared_functionality.probe_set_generation.plus_probes_dict
        )

        self.num_sites_true = model_building_utilities.get_num_qubits(self.true_model)
        self.num_qubits_true = (
            2 * self.num_sites_true
        )  # FH uses 2 qubits per sites (up and down spin)
        self.num_probes = 25

        self.max_time_to_consider = 25
        self.max_num_qubits = 8
        self.max_num_probe_qubits = self.max_num_qubits
        # self.latex_string_map_subroutine = qmla.shared_functionality.latex_model_names.lattice_set_fermi_hubbard
        # self.timing_insurance_factor = 0.8
        self.min_param = 0.25
        self.max_param = 0.75
        self.true_model_terms_params = {
            # 3 sites
            # 'FH-hopping-sum_down_1h2_2h3_d3' : 0.25,
            # 'FH-hopping-sum_up_1h2_2h3_d3' : 0.75,
            # 'FH-onsite-sum_1_2_3_d3': 0.55,
            # 2 sites
            "FH-hopping-sum_down_1h2_d2": 0.25,
            "FH-hopping-sum_up_1h2_d2": 0.75,
            "FH-onsite-sum_1_2_d2": 0.55,
        }