def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op iqpe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_time_slices = iqpe_params.get(IQPE.PROP_NUM_TIME_SLICES) paulis_grouping = iqpe_params.get(IQPE.PROP_PAULIS_GROUPING) expansion_mode = iqpe_params.get(IQPE.PROP_EXPANSION_MODE) expansion_order = iqpe_params.get(IQPE.PROP_EXPANSION_ORDER) num_iterations = iqpe_params.get(IQPE.PROP_NUM_ITERATIONS) # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) self.init_args(operator, init_state, num_time_slices, num_iterations, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op evolution_fidelity_params = params.get( QuantumAlgorithm.SECTION_KEY_ALGORITHM) expansion_order = evolution_fidelity_params.get( EvolutionFidelity.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_initial_state_instance( initial_state_params['name']) initial_state.init_params(initial_state_params) self.init_args(operator, initial_state, expansion_order)
def test_evolution(self): SIZE = 2 #SPARSITY = 0 #X = [[0, 1], [1, 0]] #Y = [[0, -1j], [1j, 0]] Z = [[1, 0], [0, -1]] I = [[1, 0], [0, 1]] h1 = np.kron( I, Z ) # + 0.5 * np.kron(Y, X)# + 0.3 * np.kron(Z, X) + 0.4 * np.kron(Z, Y) # np.random.seed(2) temp = np.random.random((2**SIZE, 2**SIZE)) h1 = temp + temp.T qubitOp = Operator(matrix=h1) temp = np.random.random((2**SIZE, 2**SIZE)) h1 = temp + temp.T evoOp = Operator(matrix=h1) state_in = get_initial_state_instance('CUSTOM') state_in.init_args(SIZE, state='random') evo_time = 1 num_time_slices = 100 dynamics = get_algorithm_instance('Dynamics') dynamics.setup_quantum_backend() # self.log.debug('state_out:\n\n') dynamics.init_args(qubitOp, 'paulis', state_in, evoOp, evo_time, num_time_slices) ret = dynamics.run() self.log.debug('Evaluation result: {}'.format(ret))
def test_evolution(self): SIZE = 2 temp = np.random.random((2**SIZE, 2**SIZE)) h1 = temp + temp.T qubitOp = Operator(matrix=h1) temp = np.random.random((2**SIZE, 2**SIZE)) h1 = temp + temp.T evoOp = Operator(matrix=h1) state_in = get_initial_state_instance('CUSTOM') state_in.init_args(SIZE, state='random') evo_time = 1 num_time_slices = 100 dynamics = get_algorithm_instance('Dynamics') dynamics.setup_quantum_backend(skip_transpiler=True) # self.log.debug('state_out:\n\n') dynamics.init_args(qubitOp, 'paulis', state_in, evoOp, evo_time, num_time_slices) ret = dynamics.run() self.log.debug('Evaluation result: {}'.format(ret))
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params (dict): parameters dictionary algo_input (EnergyInput): EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op vqe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = vqe_params.get('operator_mode') initial_point = vqe_params.get('initial_point') # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) # Set up variational form, we need to add computed num qubits, and initial state to params var_form_params = params.get(QuantumAlgorithm.SECTION_KEY_VAR_FORM) var_form_params['num_qubits'] = operator.num_qubits var_form_params['initial_state'] = init_state var_form = get_variational_form_instance(var_form_params['name']) var_form.init_params(var_form_params) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) if 'statevector' not in self._backend and operator_mode == 'matrix': logger.debug('Qasm simulation does not work on {} mode, changing \ the operator_mode to paulis'.format(operator_mode)) operator_mode = 'paulis' self.init_args(operator, operator_mode, var_form, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops) logger.info(self.print_setting())
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") # For getting the extra operator, caller has to do something like: algo_input.add_aux_op(evo_op) operator = algo_input.qubit_op aux_ops = algo_input.aux_ops if aux_ops is None or len(aux_ops) != 1: raise AlgorithmError( "EnergyInput, a single aux op is required for evaluation.") evo_operator = aux_ops[0] if evo_operator is None: raise AlgorithmError("EnergyInput, invalid aux op.") dynamics_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = dynamics_params.get(Dynamics.PROP_OPERATOR_MODE) evo_time = dynamics_params.get(Dynamics.PROP_EVO_TIME) num_time_slices = dynamics_params.get(Dynamics.PROP_NUM_TIME_SLICES) paulis_grouping = dynamics_params.get(Dynamics.PROP_PAULIS_GROUPING) expansion_mode = dynamics_params.get(Dynamics.PROP_EXPANSION_MODE) expansion_order = dynamics_params.get(Dynamics.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_initial_state_instance( initial_state_params['name']) initial_state.init_params(initial_state_params) self.init_args(operator, operator_mode, initial_state, evo_operator, evo_time, num_time_slices, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op qpe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_time_slices = qpe_params.get(QPE.PROP_NUM_TIME_SLICES) paulis_grouping = qpe_params.get(QPE.PROP_PAULIS_GROUPING) expansion_mode = qpe_params.get(QPE.PROP_EXPANSION_MODE) expansion_order = qpe_params.get(QPE.PROP_EXPANSION_ORDER) num_ancillae = qpe_params.get(QPE.PROP_NUM_ANCILLAE) use_basis_gates = qpe_params.get(QPE.PROP_USE_BASIS_GATES) # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here iqft_params = params.get(QuantumAlgorithm.SECTION_KEY_IQFT) iqft_params['num_qubits'] = num_ancillae iqft = get_iqft_instance(iqft_params['name']) iqft.init_params(iqft_params) self.init_args(operator, init_state, iqft, num_time_slices, num_ancillae, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order, use_basis_gates=use_basis_gates)
def test_qpe(self, qubitOp): self.algorithm = 'QPE' self.log.debug('Testing QPE') self.qubitOp = qubitOp exact_eigensolver = get_algorithm_instance('ExactEigensolver') exact_eigensolver.init_args(self.qubitOp, k=1) results = exact_eigensolver.run() w = results['eigvals'] v = results['eigvecs'] self.qubitOp._check_representation('matrix') np.testing.assert_almost_equal(self.qubitOp.matrix @ v[0], w[0] * v[0]) np.testing.assert_almost_equal( expm(-1.j * self.qubitOp.matrix) @ v[0], np.exp(-1.j * w[0]) * v[0]) self.ref_eigenval = w[0] self.ref_eigenvec = v[0] self.log.debug('The exact eigenvalue is: {}'.format( self.ref_eigenval)) self.log.debug('The corresponding eigenvector: {}'.format( self.ref_eigenvec)) num_time_slices = 50 num_iterations = 12 iqpe = get_algorithm_instance('IQPE') iqpe.setup_quantum_backend(backend='local_qasm_simulator', shots=100, skip_transpiler=True) state_in = get_initial_state_instance('CUSTOM') state_in.init_args(self.qubitOp.num_qubits, state_vector=self.ref_eigenvec) iqpe.init_args( self.qubitOp, state_in, num_time_slices, num_iterations, paulis_grouping='random', expansion_mode='suzuki', expansion_order=2, ) result = iqpe.run() # self.log.debug('operator paulis:\n{}'.format(self.qubitOp.print_operators('paulis'))) # self.log.debug('qpe circuit:\n\n{}'.format(result['circuit']['complete'].qasm())) self.log.debug('top result str label: {}'.format( result['top_measurement_label'])) self.log.debug('top result in decimal: {}'.format( result['top_measurement_decimal'])) self.log.debug('stretch: {}'.format( result['stretch'])) self.log.debug('translation: {}'.format( result['translation'])) self.log.debug('final eigenvalue from QPE: {}'.format( result['energy'])) self.log.debug('reference eigenvalue: {}'.format( self.ref_eigenval)) self.log.debug('ref eigenvalue (transformed): {}'.format( (self.ref_eigenval + result['translation']) * result['stretch'])) self.log.debug('reference binary str label: {}'.format( decimal_to_binary((self.ref_eigenval + result['translation']) * result['stretch'], max_num_digits=num_iterations + 3, fractional_part_only=True))) np.testing.assert_approx_equal(self.ref_eigenval, result['energy'], significant=2)
def test_qpe(self, distance): self.algorithm = 'QPE' self.log.debug( 'Testing End-to-End with QPE on H2 with interatomic distance {}.'. format(distance)) cfg_mgr = ConfigurationManager() pyscf_cfg = OrderedDict([('atom', 'H .0 .0 .0; H .0 .0 {}'.format(distance)), ('unit', 'Angstrom'), ('charge', 0), ('spin', 0), ('basis', 'sto3g')]) section = {} section['properties'] = pyscf_cfg driver = cfg_mgr.get_driver_instance('PYSCF') self.molecule = driver.run(section) ferOp = FermionicOperator(h1=self.molecule._one_body_integrals, h2=self.molecule._two_body_integrals) self.qubitOp = ferOp.mapping( map_type='PARITY', threshold=1e-10).two_qubit_reduced_operator(2) exact_eigensolver = get_algorithm_instance('ExactEigensolver') exact_eigensolver.init_args(self.qubitOp, k=1) results = exact_eigensolver.run() self.reference_energy = results['energy'] self.log.debug('The exact ground state energy is: {}'.format( results['energy'])) num_particles = self.molecule._num_alpha + self.molecule._num_beta two_qubit_reduction = True num_orbitals = self.qubitOp.num_qubits + (2 if two_qubit_reduction else 0) qubit_mapping = 'parity' num_time_slices = 50 n_ancillae = 9 qpe = get_algorithm_instance('QPE') qpe.setup_quantum_backend(backend='local_qasm_simulator', shots=100) state_in = get_initial_state_instance('HartreeFock') state_in.init_args(self.qubitOp.num_qubits, num_orbitals, qubit_mapping, two_qubit_reduction, num_particles) iqft = get_iqft_instance('STANDARD') iqft.init_args(n_ancillae) qpe.init_args(self.qubitOp, state_in, iqft, num_time_slices, n_ancillae, paulis_grouping='random', expansion_mode='suzuki', expansion_order=2, use_basis_gates=True) result = qpe.run() self.log.debug('measurement results: {}'.format( result['measurements'])) self.log.debug('top result str label: {}'.format( result['top_measurement_label'])) self.log.debug('top result in decimal: {}'.format( result['top_measurement_decimal'])) self.log.debug('stretch: {}'.format( result['stretch'])) self.log.debug('translation: {}'.format( result['translation'])) self.log.debug('final energy from QPE: {}'.format(result['energy'])) self.log.debug('reference energy: {}'.format( self.reference_energy)) self.log.debug('ref energy (transformed): {}'.format( (self.reference_energy + result['translation']) * result['stretch'])) self.log.debug('ref binary str label: {}'.format( decimal_to_binary((self.reference_energy + result['translation']) * result['stretch'], max_num_digits=n_ancillae + 3, fractional_part_only=True))) np.testing.assert_approx_equal(result['energy'], self.reference_energy, significant=2)
def setUp(self): self.hf = get_initial_state_instance('HartreeFock')
def test_evolution(self): SIZE = 2 #SPARSITY = 0 #X = [[0, 1], [1, 0]] #Y = [[0, -1j], [1j, 0]] Z = [[1, 0], [0, -1]] I = [[1, 0], [0, 1]] h1 = np.kron(I, Z) # + 0.5 * np.kron(Y, X)# + 0.3 * np.kron(Z, X) + 0.4 * np.kron(Z, Y) # np.random.seed(2) temp = np.random.random((2 ** SIZE, 2 ** SIZE)) h1 = temp + temp.T qubitOp = Operator(matrix=h1) # qubitOp_jw.chop_by_threshold(10 ** -10) # self.log.debug('matrix:\n{}\n'.format(qubitOp.matrix)) # self.log.debug('paulis:') # self.log.debug(qubitOp.print_operators('paulis')) if qubitOp.grouped_paulis is None: qubitOp._matrix_to_paulis() qubitOp._paulis_to_grouped_paulis() for ps in qubitOp.grouped_paulis: for p1 in ps: for p2 in ps: if p1 != p2: diff = p1[1].to_matrix() @ p2[1].to_matrix() - p2[1].to_matrix() @ p1[1].to_matrix() if diff.any(): raise RuntimeError('Paulis within the same group do not commute!') flattened_grouped_paulis = [pauli for group in qubitOp.grouped_paulis for pauli in group[1:]] if sorted([str(p) for p in flattened_grouped_paulis]) != sorted([str(p) for p in qubitOp.paulis]): raise RuntimeError('grouped_paulis and paulis do not match!') state_in = get_initial_state_instance('CUSTOM') state_in.init_args(SIZE, state='random') evo_time = 1 num_time_slices = 1 # announces params self.log.debug('evo time: {}'.format(evo_time)) self.log.debug('num time slices: {}'.format(num_time_slices)) self.log.debug('state_in: {}'.format(state_in._state_vector)) # get the exact state_out from raw matrix multiplication state_out_exact = qubitOp.evolve(state_in.construct_circuit('vector'), evo_time, 'matrix', 0) # self.log.debug('exact:\n{}'.format(state_out_exact)) for grouping in ['default', 'random']: self.log.debug('Under {} paulis grouping:'.format(grouping)) for expansion_mode in ['trotter', 'suzuki']: self.log.debug('Under {} expansion mode:'.format(expansion_mode)) for expansion_order in [1, 2, 3, 4] if expansion_mode == 'suzuki' else [1]: if expansion_mode == 'suzuki': self.log.debug('With expansion order {}:'.format(expansion_order)) state_out_matrix = qubitOp.evolve( state_in.construct_circuit('vector'), evo_time, 'matrix', num_time_slices, paulis_grouping=grouping, expansion_mode=expansion_mode, expansion_order=expansion_order ) quantum_registers = QuantumRegister(qubitOp.num_qubits) qc = state_in.construct_circuit('circuit', quantum_registers) qc += qubitOp.evolve( None, evo_time, 'circuit', num_time_slices, quantum_registers=quantum_registers, paulis_grouping=grouping, expansion_mode=expansion_mode, expansion_order=expansion_order ) job = q_execute(qc, 'local_statevector_simulator') state_out_circuit = np.asarray(job.result().get_statevector(qc)) self.log.debug('The fidelity between exact and matrix: {}'.format( state_fidelity(state_out_exact, state_out_matrix) )) self.log.debug('The fidelity between exact and circuit: {}'.format( state_fidelity(state_out_exact, state_out_circuit) )) f_mc = state_fidelity(state_out_matrix, state_out_circuit) self.log.debug('The fidelity between matrix and circuit: {}'.format(f_mc)) self.assertAlmostEqual(f_mc, 1)
def setUp(self): self.zero = get_initial_state_instance('ZERO')
def setUp(self): self.custom = get_initial_state_instance('CUSTOM')