跳转至

LGMFidelityEstimator

QuICT.qcda.utility.fidelity_estimator.lgm_fidelity_estimator.LGMFidelityEstimator

LGMFidelityEstimator(vqm: VirtualQuantumMachine = None, step=2)

lightgbm based fidelity estimator.

Args: vqm(VirtualQuantumMachine): target machine. step(int): step of path to be considered, should be 2 as default.

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def __init__(
        self,
        vqm: VirtualQuantumMachine = None,
        step=2):
    """
    Warnings:
        vqm can be None, but you should specify self.vqm before using
        other functions.
    Args:
        vqm(VirtualQuantumMachine): target machine.
        step(int): step of path to be considered, should be 2 as default.
    """
    self.vqm = vqm
    self.step = step
    self.path = []
    self.model = None
    self.scaler = StandardScaler()
    if self.vqm is not None:
        self._init_path()

data2feature

data2feature(data, mapping: List[int] = None)

Convert [(Circuit, vqm),...] into features. Here vqm can be None, if you have already specified vqm. Args: data(list): data to be converted mapping(List[int]): mapping of qubits Returns: torch.Tensor: features

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def data2feature(self, data, mapping: List[int] = None):
    """
    Convert [(Circuit, vqm),...] into features.
    Here vqm can be None, if you have already specified vqm.
    Args:
        data(list): data to be converted
        mapping(List[int]): mapping of qubits
    Returns:
        torch.Tensor: features
    """
    features = []
    if isinstance(data[0], Circuit):
        data = [data]
    for datum in data:
        feature = self._compute_feature(datum, mapping)
        feature = feature.reshape(1, -1)
        features.append(feature)
    features = torch.cat(features, dim=0)
    readout = features[:, -1].reshape(-1, 1)
    features = features[:, :-1].numpy()
    features = self.scaler.transform(features)
    features = torch.from_numpy(features)
    features = torch.cat([features, readout], dim=1)
    return features

data2feature_label

data2feature_label(data, mapping: List[int] = None, is_train=True)

Convert [(Circuit, vqm),...] into (features, labels). Here vqm can be None, if you have already specified vqm. Args: data(list): data to be converted mapping(List[int]): mapping of qubits is_train(bool): data is for train or not Returns: tuple(torch.Tensor, torch.Tensor): (features, labels)

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def data2feature_label(self, data, mapping: List[int] = None, is_train=True):
    """
    Convert [(Circuit, vqm),...] into (features, labels).
    Here vqm can be None, if you have already specified vqm.
    Args:
        data(list): data to be converted
        mapping(List[int]): mapping of qubits
        is_train(bool): data is for train or not
    Returns:
        tuple(torch.Tensor, torch.Tensor): (features, labels)
    """
    features = []
    labels = []
    if isinstance(data[0], Circuit):
        data = [data]
    for datum in data:
        feature = self._compute_feature(datum, mapping)
        feature = feature.reshape(1, -1)
        features.append(feature)
        labels.append(datum[2])
    features = torch.cat(features, dim=0)
    readout = features[:, -1].reshape(-1, 1)
    features = features[:, :-1].numpy()
    if is_train:
        features = self.scaler.fit_transform(features)
    else:
        self.scaler.transform(features)
    labels = torch.tensor(labels).reshape(-1, 1)
    features = torch.from_numpy(features)
    features = torch.cat([features, readout], dim=1)
    return features, labels

estimate_fidelity

estimate_fidelity(circ: Circuit, vqm: VirtualQuantumMachine = None, mapping: List[int] = None)

Estimate the fidelity on the target vqm. If the vqm remains the same, please set as None. This vqm should have the same InstructionSet as self.vqm Args: circ(Circuit): circuit to estimate vqm(VirtualQuantumMachine): vqm to estimate mapping(List[int]): mapping of qubits Returns: list(float): fidelity

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def estimate_fidelity(self, circ: Circuit,
                      vqm: VirtualQuantumMachine = None,
                      mapping: List[int] = None):
    """
    Estimate the fidelity on the target vqm.
    If the vqm remains the same, please set as None.
    This vqm should have the same InstructionSet as self.vqm
    Args:
        circ(Circuit): circuit to estimate
        vqm(VirtualQuantumMachine): vqm to estimate
        mapping(List[int]): mapping of qubits
    Returns:
        list(float): fidelity
    """
    assert self.model is not None, "No trained model!"
    if self.vqm is None:
        assert isinstance(vqm, VirtualQuantumMachine), "No VirtualQuantumMachine is found!"
        self.vqm = vqm
        self.path = []

    elif vqm is None:
        vqm = self.vqm

    if mapping is None:
        mapping = list(range(self.vqm.qubit_number))
    assert self._check_circuit(circ, vqm, mapping), \
        "This circuit cannot be implemented on this VirtualQuantumMachine!"
    features = self.data2feature([circ, vqm], mapping).numpy()

    return self.model.predict(features).item()

fit

fit(data, mapping: List[int] = None, **kwargs)

Fit this estimator with given data Args: data(List[Circuit, vqm, labels]): list of data for fitting mapping(List[int]): mapping of qubits kwargs: args in lightGBM

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def fit(self, data, mapping: List[int] = None, **kwargs):
    """
    Fit this estimator with given data
    Args:
        data(List[Circuit, vqm, labels]): list of data for fitting
        mapping(List[int]): mapping of qubits
        kwargs: args in lightGBM
    """
    kwargs['objective'] = 'regression'
    if self.vqm is None:
        assert isinstance(data[0][1], VirtualQuantumMachine), "No VirtualQuantumMachine is found"
        self.vqm = data[0][1]
    if mapping is None:
        mapping = list(range(self.vqm.qubit_number))
    train_features, train_labels = self.data2feature_label(data, mapping, is_train=True)
    train_features = train_features.numpy()
    train_labels = train_labels.numpy()
    if "num_boost_round" not in kwargs.keys():
        num_boost_round = 100
    else:
        num_boost_round = kwargs["num_boost_round"]
        del kwargs["num_boost_round"]
    d_train = lgb.Dataset(train_features, label=train_labels)
    self.model = lgb.train(params=kwargs, train_set=d_train, num_boost_round=num_boost_round)
    if "verbose" in kwargs and kwargs["verbose"] >= 1:
        print("Fit done.")

from_target_machine classmethod

from_target_machine(target_machine)
Info

Load default fidelity estimator from given target_machine. See LGMFidelityEstimator.SUPPORTED_MACHINE for supported machines.

Parameters:

  • target_machine(str)

    target machine

Returns: LGMFidelityEstimator: fidelity estimator

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
@classmethod
def from_target_machine(cls, target_machine):
    """
    Info:
        Load default fidelity estimator from given target_machine.
        See LGMFidelityEstimator.SUPPORTED_MACHINE for supported machines.

    Args:
        target_machine(str): target machine
    Returns:
        LGMFidelityEstimator: fidelity estimator
    """
    if target_machine not in cls.SUPPORTED_MACHINE:
        raise ValueError(f'Unsupported machine: {target_machine}')
    data_id = cls.SUPPORTED_MACHINE.index(target_machine) + 1
    base_dir = os.path.join(os.path.dirname(__file__), 'models')
    scaler = pkl.load(open(os.path.join(base_dir, 'scaler' + str(data_id) + '.pkl'), 'rb'))
    model = pkl.load(open(os.path.join(base_dir, 'model' + str(data_id) + '.pkl'), 'rb'))
    vqm = pkl.load(open(os.path.join(base_dir, 'vqm' + str(data_id) + '.pkl'), 'rb'))
    fe = cls(vqm=vqm)
    fe.scaler = scaler
    fe.model = model
    fe.model.params["verbose"] = -1
    return fe

load classmethod

load(file_path=None, file_prefix='')

Load a fidelity estimator from given path and prefix. Args: file_path(str): path of files file_prefix(str): prefix of files Returns: LGMFidelityEstimator: fidelity estimator

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
@classmethod
def load(cls, file_path=None, file_prefix=""):
    """
    Load a fidelity estimator from given path and prefix.
    Args:
        file_path(str): path of files
        file_prefix(str): prefix of files
    Returns:
        LGMFidelityEstimator: fidelity estimator
    """
    if file_path is None:
        file_path = os.path.join(os.path.dirname(__file__), 'models')
    scaler = pkl.load(open(os.path.join(file_path, file_prefix + 'scaler.pkl'), 'rb'))
    model = pkl.load(open(os.path.join(file_path, file_prefix + 'model.pkl'), 'rb'))
    vqm = pkl.load(open(os.path.join(file_path, file_prefix + 'vqm.pkl'), 'rb'))
    fe = cls(vqm=vqm)
    fe.scaler = scaler
    fe.model = model
    fe.model.params["verbose"] = -1
    return fe

save

save(file_path=None, file_prefix=None)

Save a fidelity estimator to given path and prefix. Args: file_path(str): path of files file_prefix(str): prefix of files

Source code in QuICT/qcda/utility/fidelity_estimator/lgm_fidelity_estimator.py
def save(self, file_path=None, file_prefix=None):
    """
    Save a fidelity estimator to given path and prefix.
    Args:
        file_path(str): path of files
        file_prefix(str): prefix of files
    """
    if file_path is None:
        file_path = os.path.join(os.path.dirname(__file__), 'models')
    if file_prefix is None:
        file_prefix = ""
    pkl.dump(self.scaler, open(os.path.join(file_path, file_prefix + 'scaler.pkl'), 'wb'))
    pkl.dump(self.model, open(os.path.join(file_path, file_prefix + 'model.pkl'), 'wb'))
    pkl.dump(self.vqm, open(os.path.join(file_path, file_prefix + 'vqm.pkl'), 'wb'))