def make_cs_operator(): cs_matrix = np.array([[1 + 0j, 0 + 0j, 0 + 0j, 0 + 0j], [0 + 0j, 1 + 0j, 0 + 0j, 0 + 0j], [0 + 0j, 0 + 0j, 1 + 0j, 0 + 0j], [0 + 0j, 0 + 0j, 0 + 0j, 0 + 1j]]) cs = Operator(cs_matrix) print("Operator is unitary:", cs.is_unitary()) return cs
def unit_tests(n): if not os.path.exists('uf/bv'): os.makedirs('uf/bv') SAVEPATH = 'uf/bv/' FILEPATH = f'bv{n}' APATH = 'a_dict' BPATH = 'b_dict' if not os.path.exists(f'{SAVEPATH}{FILEPATH}.npy'): if os.path.exists(f'{SAVEPATH}{APATH}.npy'): a_list = np.load(f'{SAVEPATH}{APATH}.npy', allow_pickle=True).item() else: a_list = {} if os.path.exists(f'{SAVEPATH}{BPATH}.npy'): b_list = np.load(f'{SAVEPATH}{BPATH}.npy', allow_pickle=True).item() else: b_list = {} a = a_list[n] if n in a_list.keys() else np.random.randint( low=0, high=2, size=n) b = b_list[n] if n in b_list.keys() else np.random.randint(low=0, high=2) a_list[n] = a b_list[n] = b np.save(f'{SAVEPATH}{APATH}.npy', a_list, allow_pickle=True) np.save(f'{SAVEPATH}{BPATH}.npy', b_list, allow_pickle=True) print( f'Generating bit mapping for {n}-qubit BV with a={"".join(str(i) for i in a)} and b={b} .. ', end='', flush=True) mapping = oracle.init_bit_mapping(n, algo=oracle.Algos.BV, func=(a, b)) print('done') print(f'Generating U_f from bit mapping .. ', end='', flush=True) U_f = oracle.gen_matrix(mapping, n, 1) print('done') else: print( f'Loading U_f for {n}-qubit BV from {SAVEPATH}{FILEPATH}.npy .. ', end='', flush=True) U_f = Operator(np.load(f'{SAVEPATH}{FILEPATH}.npy')) print('done') assert U_f.is_unitary() if not os.path.exists(f'{SAVEPATH}{FILEPATH}.npy'): print(f'Saving U_f for {n}-qubit BV to {SAVEPATH}{FILEPATH}.npy .. ', end='', flush=True) np.save(f'{SAVEPATH}{FILEPATH}', U_f.data) print('done') print('')
def make_ct_operator(): ct_matrix = np.array([[1 + 0j, 0 + 0j, 0 + 0j, 0 + 0j], [0 + 0j, 1 + 0j, 0 + 0j, 0 + 0j], [0 + 0j, 0 + 0j, 1 + 0j, 0 + 0j], [0 + 0j, 0 + 0j, 0 + 0j, np.exp(1j * np.pi / 4)]]) ct = Operator(ct_matrix) print("Operator is unitary:", ct.is_unitary()) return ct
def unit_test(n): if not os.path.exists('uf/grover'): os.makedirs('uf/grover') if not os.path.exists(f'{SAVEDIR}grover{str(n)}.npy'): print(f'Generating bit mapping for {n}-qubit Grover .. ', end='', flush=True) mapping = oracle.init_bit_mapping(n, algo=oracle.Algos.GROVER) print('done') if os.path.exists(f'{SAVEDIR}{FLIST}.npy'): print(f'Loading f_list for Grover from {SAVEDIR}{FLIST}.npy .. ', end='', flush=True) f_list = np.load(f'{SAVEDIR}{FLIST}.npy', allow_pickle=True).item() print('done') else: f_list = {} f_list[n] = mapping print(f'Saving f_list for Grover to {SAVEDIR}{FLIST}.npy .. ', end='', flush=True) np.save(f'{SAVEDIR}{FLIST}.npy', f_list, allow_pickle=True) print('done') print(f'Generating oracle matrix for {n}-qubit Grover .. ', end='', flush=True) U_f = oracle.gen_matrix(mapping, n, 1) print('done') else: print( f'Loading U_f for {n}-qubit Grover from {SAVEDIR}grover{str(n)}.npy .. ', end='', flush=True) U_f = Operator(np.load(f'{SAVEDIR}grover{str(n)}.npy')) print("done") print(f'Check if U_f is unitary .. ', end='', flush=True) assert U_f.is_unitary() print('done') if not os.path.exists(f'{SAVEDIR}grover{str(n)}.npy'): print( f'Saving U_f for {n}-qubit Grover from {SAVEDIR}grover{str(n)}.npy .. ', end='', flush=True) np.save(f'{SAVEDIR}grover{str(n)}.npy', U_f.data) print("done")
def unit_test(n, s=None): if not os.path.exists('uf/simon'): os.makedirs('uf/simon') if not os.path.exists(f'{SAVEDIR}simon{str(n)}.npy') or s is not None: print(f'Generating bit mapping for {n}-qubit Simon .. ', end='', flush=True) mapping = oracle.init_bit_mapping(n, algo=oracle.Algos.SIMON, s=s) print('done') print(f'Generating s value for newly generated {n}-bit mapping Simon .. ', end='', flush=True) s = get_s(mapping) print('done') print(f'Checking validity of s value .. ', end='', flush=True) assert is_valid(s, mapping) print('done') if os.path.exists(f'{SAVEDIR}{SLIST}.npy'): print(f'Loading s_list for Simon from {SAVEDIR}{SLIST}.npy .. ', end='', flush=True) s_list = np.load(f'{SAVEDIR}{SLIST}.npy', allow_pickle=True).item() print('done') else: s_list={} s_list[n] = s print(f'Saving s_list for Simon to {SAVEDIR}{SLIST}.npy .. ', end='', flush=True) np.save(f'{SAVEDIR}{SLIST}.npy', s_list, allow_pickle=True) print('done') print(f'Generating oracle matrix for {n}-qubit Simon .. ', end='', flush=True) U_f = oracle.gen_matrix(mapping, n, n) print('done') else: print(f'Loading U_f for {n}-qubit Simon from {SAVEDIR}simon{str(n)}.npy .. ', end='', flush=True) U_f = Operator(np.load(f'{SAVEDIR}simon{str(n)}.npy')) print("done") print(f'Check if U_f is unitary .. ', end='', flush=True) assert U_f.is_unitary() print('done') print(f'Saving U_f for {n}-qubit Simon from {SAVEDIR}simon{str(n)}.npy .. ', end='', flush=True) np.save(f'{SAVEDIR}simon{str(n)}.npy', U_f.data) print("done")
def unit_tests(n): if not os.path.exists('uf'): os.mkdir('uf') if not os.path.exists('uf/dj'): os.mkdir('uf/dj') SAVEPATH = 'uf/dj/' CONSTPATH = f'const{n}' BALPATH = f'bal{n}' if not os.path.exists(f'{SAVEPATH}{CONSTPATH}.npy'): print(f'Generating bit mapping for {n}-qubit constant DJ .. ', end='', flush=True) const_mapping = oracle.init_bit_mapping(n, algo=oracle.Algos.DJ, func=oracle.DJ.CONSTANT) print('done') assert is_bal_or_const(const_mapping, oracle.DJ.CONSTANT) print(f'Generating U_f from bit mapping .. ', end='', flush=True) U_const_f = oracle.gen_matrix(const_mapping, n, 1) print('done') else: print( f'Loading U_f for {n}-qubit constant DJ from {SAVEPATH}{CONSTPATH}.npy .. ', end='', flush=True) U_const_f = Operator(np.load(f'{SAVEPATH}{CONSTPATH}.npy')) print('done') if not os.path.exists(f'{SAVEPATH}{BALPATH}.npy'): print(f'Generating bit mapping for {n}-qubit balanced DJ .. ', end='', flush=True) balanced_mapping = oracle.init_bit_mapping(n, algo=oracle.Algos.DJ, func=oracle.DJ.BALANCED) print('done') assert is_bal_or_const(balanced_mapping, oracle.DJ.BALANCED) print(f'Generating U_f from bit mapping .. ', end='', flush=True) U_bal_f = oracle.gen_matrix(balanced_mapping, n, 1) print('done') else: print( f'Loading U_f for {n}-qubit balanced DJ from {SAVEPATH}{BALPATH}.npy .. ', end='', flush=True) U_bal_f = Operator(np.load(f'{SAVEPATH}{BALPATH}.npy')) print('done') assert U_const_f.is_unitary() if not os.path.exists(f'{SAVEPATH}{CONSTPATH}.npy'): print( f'Saving U_f for {n}-qubit constant DJ to {SAVEPATH}{CONSTPATH}.npy .. ', end='', flush=True) np.save(SAVEPATH + CONSTPATH, U_const_f.data) print('done') assert U_bal_f.is_unitary() if not os.path.exists(f'{SAVEPATH}{BALPATH}.npy'): print( f'Saving U_f for {n}-qubit balanced DJ to {SAVEPATH}{BALPATH}.npy .. ', end='', flush=True) np.save(SAVEPATH + BALPATH, U_bal_f.data) print('done') print('')
def process_fidelity(channel1, channel2, require_cptp=True): """Return the process fidelity between two quantum channels. This is given by F_p(E1, E2) = Tr[S2^dagger.S1])/dim^2 where S1 and S2 are the SuperOp matrices for channels E1 and E2, and dim is the dimension of the input output statespace. Args: channel1 (QuantumChannel or matrix): a quantum channel or unitary matrix. channel2 (QuantumChannel or matrix): a quantum channel or unitary matrix. require_cptp (bool): require input channels to be CPTP [Default: True]. Returns: array_like: The state fidelity F(state1, state2). Raises: QiskitError: if inputs channels do not have the same dimensions, have different input and output dimensions, or are not CPTP with `require_cptp=True`. """ # First we must determine if input is to be interpreted as a unitary matrix # or as a channel. # If input is a raw numpy array we will interpret it as a unitary matrix. is_cptp1 = None is_cptp2 = None if isinstance(channel1, (list, np.ndarray)): channel1 = Operator(channel1) if require_cptp: is_cptp1 = channel1.is_unitary() if isinstance(channel2, (list, np.ndarray)): channel2 = Operator(channel2) if require_cptp: is_cptp2 = channel2.is_unitary() # Next we convert inputs SuperOp objects # This works for objects that also have a `to_operator` or `to_channel` method s1 = SuperOp(channel1) s2 = SuperOp(channel2) # Check inputs are CPTP if require_cptp: # Only check SuperOp if we didn't already check unitary inputs if is_cptp1 is None: is_cptp1 = s1.is_cptp() if not is_cptp1: raise QiskitError('channel1 is not CPTP') if is_cptp2 is None: is_cptp2 = s2.is_cptp() if not is_cptp2: raise QiskitError('channel2 is not CPTP') # Check dimensions match input_dim1, output_dim1 = s1.dim input_dim2, output_dim2 = s2.dim if input_dim1 != output_dim1 or input_dim2 != output_dim2: raise QiskitError('Input channels must have same size input and output dimensions.') if input_dim1 != input_dim2: raise QiskitError('Input channels have different dimensions.') # Compute process fidelity fidelity = np.trace(s1.compose(s2.adjoint()).data) / (input_dim1 ** 2) return fidelity