def config(X): n = int(np.ceil(np.log2(len(X[0])))) # pylint: disable=no-member n = 2**int(np.ceil(np.log2(n))) # n tem que ser potência de 2. # pylint: disable=no-member N = 2**n - 1 # len(X[0])-1 # N precisa ser tal que n seja potência de 2 mais próxima de log_2(X[0]). O hierarchical exige que n seja dessa maneira. w = 2 * n - 1 # número de parâmetros do circuito (weights) X = np.c_[X, np.zeros((len(X), 2**n - len(X[0])))] # o número de qubits necessários para codificar os dados (log_2(N)) precisa ser uma potencia de 2. # pylint: disable=no-member return n, N, w, X
def config(X): n = int(np.ceil(np.log2(len(X[0])))) # pylint: disable=no-member n = 2**int(np.ceil(np.log2(n))) # n tem que ser potência de 2. # pylint: disable=no-member N = n # número total de qubits no circuito. w = 2*n - 1 # número de parâmetros do circuito (weights) X = np.c_[X, np.zeros((len(X), 2**n-len(X[0])))] # o número de qubits necessários para codificar os dados (log_2(N)) precisa ser uma potencia de 2. # pylint: disable=no-member return n, N, w, X
def compute_indices(wires, n_block_wires): """Generate a list containing the wires for each block. Args: wires (Iterable): wires that the template acts on n_block_wires (int): number of wires per block Returns: layers (array): array of wire labels for each block """ n_wires = len(wires) if n_block_wires % 2 != 0: raise ValueError( f"n_block_wires must be an even integer; got {n_block_wires}") if n_block_wires < 2: raise ValueError( f"number of wires in each block must be larger than or equal to 2; got n_block_wires = {n_block_wires}" ) if n_block_wires > n_wires: raise ValueError( f"n_block_wires must be smaller than or equal to the number of wires; " f"got n_block_wires = {n_block_wires} and number of wires = {n_wires}" ) if not np.log2(n_wires / n_block_wires).is_integer(): warnings.warn( f"The number of wires should be n_block_wires times 2^n; got n_wires/n_block_wires = {n_wires/n_block_wires}" ) n_wires = 2**(int(np.log2(len(wires) / n_block_wires))) * n_block_wires n_layers = int(np.log2(n_wires // n_block_wires)) + 1 layers = [[ wires[i] for i in range( x + 2**(j - 1) * n_block_wires // 2 - n_block_wires // 2, x + n_block_wires // 2 + 2**(j - 1) * n_block_wires // 2 - n_block_wires // 2, ) ] + [ wires[i] for i in range( x + 2**(j - 1) * n_block_wires // 2 + 2**(j - 1) * n_block_wires // 2 - n_block_wires // 2, x + 2**(j - 1) * n_block_wires // 2 + n_block_wires // 2 + 2**(j - 1) * n_block_wires // 2 - n_block_wires // 2, ) ] for j in range(1, n_layers + 1) for x in range(0, n_wires - n_block_wires // 2, 2**(j - 1) * n_block_wires)] return layers
def config(X): n = 2**int(np.ceil(np.log2(len(X[0])))) # len(X[0]) # número de qubits necessário para armazenar o dado codificado. # pylint: disable=no-member N = n # número total de qubits no circuito. w = 2 * n - 1 # número de parâmetros do circuito (weights) X = np.c_[X, np.zeros((len(X), n - len(X[0])))] # pylint: disable=no-member return n, N, w, X
def shadow_bound(error, observables, failure_rate=0.01): """ Calculate the shadow bound for the Pauli measurement scheme. Implements Eq. (S13) from https://arxiv.org/pdf/2002.08953.pdf Args: error (float): The error on the estimator. observables (list) : List of matrices corresponding to the observables we intend to measure. failure_rate (float): Rate of failure for the bound to hold. Returns: An integer that gives the number of samples required to satisfy the shadow bound and the chunk size required attaining the specified failure rate. """ M = len(observables) K = 2 * np.log(2 * M / failure_rate) shadow_norm = ( lambda op: np.linalg.norm( op - np.trace(op) / 2 ** int(np.log2(op.shape[0])), ord=np.inf ) ** 2 ) N = 34 * max(shadow_norm(o) for o in observables) / error ** 2 return int(np.ceil(N * K)), int(K)
def get_n_blocks(wires, n_block_wires): """Returns the expected number of blocks for a set of wires and number of wires per block. Args: wires (Sequence): number of wires the template acts on n_block_wires (int): number of wires per block Returns: n_blocks (int): number of blocks; expected length of the template_weights argument """ n_wires = len(wires) if not np.log2(n_wires / n_block_wires).is_integer(): warnings.warn( f"The number of wires should be n_block_wires times 2^n; got n_wires/n_block_wires = {n_wires/n_block_wires}" ) if n_block_wires > n_wires: raise ValueError( f"n_block_wires must be smaller than or equal to the number of wires; got n_block_wires = {n_block_wires} and number of wires = {n_wires}" ) n_blocks = 2**int(np.log2(n_wires / n_block_wires)) * 2 - 1 return n_blocks
def __init__( self, wires, n_block_wires, block, n_params_block, template_weights=None, do_queue=True, id=None, ): self.ind_gates = compute_indices(wires, n_block_wires) n_wires = len(wires) shape = qml.math.shape(template_weights) # (n_params_block, n_blocks) self.n_params_block = n_params_block self.n_blocks = 2**int(np.log2(n_wires / n_block_wires)) * 2 - 1 self.block = block if shape == (): self.template_weights = np.random.rand(n_params_block, int(self.n_blocks)) else: if shape[0] != self.n_blocks: raise ValueError( f"Weights tensor must have first dimension of length {self.n_blocks}; got {shape[0]}" ) if shape[-1] != self.n_params_block: raise ValueError( f"Weights tensor must have last dimension of length {self.n_params_block}; got {shape[-1]}" ) self.template_weights = template_weights super().__init__(template_weights, wires=wires, do_queue=do_queue, id=id)
dev = qml.device("default.qubit.autograd", wires=num_qubits) constant_hea_depth = 3 ansatze = [ ttn_circuit(num_qubits), mera_circuit(num_qubits), hea_circuit(num_qubits), hea_circuit(num_qubits), hea_circuit(num_qubits) ] num_params_ansatz = [ num_params_per_gate * get_num_ttn_gates(num_qubits), num_params_per_gate * get_num_mera_gates(num_qubits), 3 * (num_qubits * constant_hea_depth), 3 * (num_qubits * int(np.floor(np.log2(num_qubits)))), 3 * (num_qubits * num_qubits) ] ansatz_names = [ "TTN", "MERA", "HEA (constant)", "HEA (log)", "HEA (linear)" ] for (ansatz, ansatz_name, num_params) in zip(ansatze, ansatz_names, num_params_ansatz): print(f" --- {ansatz_name} ({num_params} parameters) ---") for init in initializations: print(f" +++ {init} +++") mod_ansatz = ansatz if init in ["Random |+...+>", "Zero |+...+>"]: