5 Created on Fri Jun 26 14:13:26 2020 6 Copyright 2020 Peter Rakyta, Ph.D. 8 Licensed under the Apache License, Version 2.0 (the "License"); 9 you may not use this file except in compliance with the License. 10 You may obtain a copy of the License at 12 http://www.apache.org/licenses/LICENSE-2.0 14 Unless required by applicable law or agreed to in writing, software 15 distributed under the License is distributed on an "AS IS" BASIS, 16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 See the License for the specific language governing permissions and 18 limitations under the License. 20 @author: Peter Rakyta, Ph.D. 30 from squander.VQA.qgd_Variational_Quantum_Eigensolver_Base_Wrapper
import qgd_Variational_Quantum_Eigensolver_Base_Wrapper
33 _VQE_BACKEND_NAME_TO_CODE = {
37 _VQE_DEFAULT_BACKEND =
"state_vector" 38 _VQE_BACKEND_CONFIG_KEY =
"backend_mode" 39 _DENSITY_NOISE_CHANNEL_SPECS = {
40 "depolarizing": (
"local_depolarizing",
"error_rate"),
41 "local_depolarizing": (
"local_depolarizing",
"error_rate"),
42 "amplitude_damping": (
"amplitude_damping",
"gamma"),
43 "phase_damping": (
"phase_damping",
"lambda"),
44 "dephasing": (
"phase_damping",
"lambda"),
51 return _VQE_DEFAULT_BACKEND
53 if not isinstance(backend, str):
55 "backend should be one of 'state_vector', 'density_matrix', or None" 58 normalized_backend = backend.strip()
59 if normalized_backend
not in _VQE_BACKEND_NAME_TO_CODE:
61 "Unsupported backend '{}'. Supported backends are 'state_vector' and " 62 "'density_matrix'.".format(backend)
65 return normalized_backend
70 if density_noise
is None:
73 if not isinstance(density_noise, (list, tuple)):
74 raise TypeError(
"density_noise should be a list or tuple of dictionaries")
76 normalized_density_noise = []
77 for item_idx, noise_item
in enumerate(density_noise):
78 if not isinstance(noise_item, dict):
80 "density_noise[{}] should be a dictionary".format(item_idx)
83 channel = noise_item.get(
"channel", noise_item.get(
"type"))
84 if not isinstance(channel, str):
86 "density_noise[{}] should define a string 'channel'".format(
91 channel_name = channel.strip()
92 if channel_name
not in _DENSITY_NOISE_CHANNEL_SPECS:
94 "Unsupported density-noise channel '{}'. Supported channels are " 95 "'local_depolarizing', 'amplitude_damping', and " 96 "'phase_damping'.".format(channel)
99 canonical_channel, value_key = _DENSITY_NOISE_CHANNEL_SPECS[channel_name]
100 raw_value = noise_item.get(
"value", noise_item.get(value_key))
101 if canonical_channel ==
"phase_damping" and raw_value
is None:
102 raw_value = noise_item.get(
"lambda_param")
104 if raw_value
is None:
106 "density_noise[{}] is missing the '{}' value".format(
111 target = noise_item.get(
"target")
112 after_gate_index = noise_item.get(
"after_gate_index")
113 if isinstance(target, bool)
or not isinstance(target, int):
115 "density_noise[{}].target should be an integer".format(item_idx)
117 if isinstance(after_gate_index, bool)
or not isinstance(after_gate_index, int):
119 "density_noise[{}].after_gate_index should be an integer".format(
124 value = float(raw_value)
125 if not np.isfinite(value):
127 "density_noise[{}] has a non-finite value".format(item_idx)
130 normalized_density_noise.append(
132 "channel": canonical_channel,
133 "target":
int(target),
134 "after_gate_index":
int(after_gate_index),
139 return normalized_density_noise
182 if not isinstance(config, dict):
183 print(
"Input parameter config should be a dictionary describing the following hyperparameters:")
187 config_copy = dict(config)
188 config_copy[_VQE_BACKEND_CONFIG_KEY] = _VQE_BACKEND_NAME_TO_CODE[normalized_backend]
191 super(qgd_Variational_Quantum_Eigensolver_Base, self).
__init__(Hamiltonian.data, Hamiltonian.indices, Hamiltonian.indptr, qbit_num, config=config_copy, accelerator_num=accelerator_num)
192 self.qbit_num = qbit_num
196 self.backend = normalized_backend
197 self.density_noise = []
198 self.set_Density_Matrix_Noise(density_noise)
206 super(qgd_Variational_Quantum_Eigensolver_Base, self).
set_Optimizer(alg)
243 super(qgd_Variational_Quantum_Eigensolver_Base, self).
set_Project_Name(project_name)
250 super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Gate_Structure_From_Binary(filename)
258 super(qgd_Variational_Quantum_Eigensolver_Base, self).
set_Ansatz(ansatz_new)
266 super(qgd_Variational_Quantum_Eigensolver_Base, self).
Generate_Circuit( layers, inner_blocks )
290 qbit_num = self.get_Qbit_Num()
292 qubit_list_validated = list()
293 if isinstance(qubit_list, list)
or isinstance(qubit_list, tuple):
294 for item
in qubit_list:
295 if isinstance(item, int):
296 qubit_list_validated.append(item)
297 qubit_list_validated = list(set(qubit_list_validated))
299 print(
"Elements of qbit_list should be integers")
301 elif qubit_list ==
None:
302 qubit_list_validated = [ x
for x
in range(qbit_num) ]
305 print(
"Elements of qbit_list should be integers")
309 if parameters
is None:
310 print(
"get_Second_Renyi_entropy: array of input parameters is None")
314 if input_state
is None:
315 matrix_size = 1 << qbit_num
316 input_state = np.zeros( (matrix_size,1) )
320 entropy = super(qgd_Variational_Quantum_Eigensolver_Base, self).
get_Second_Renyi_Entropy( parameters, input_state, qubit_list_validated)
331 return super(qgd_Variational_Quantum_Eigensolver_Base, self).
get_Qbit_Num()
345 def apply_to( self, parameters_mtx, state_to_be_transformed):
348 super().
apply_to( parameters_mtx, state_to_be_transformed )
366 from squander
import Qiskit_IO
368 squander_circuit = self.get_Circuit()
369 parameters = self.get_Optimized_Parameters()
371 return Qiskit_IO.get_Qiskit_Circuit( squander_circuit, parameters )
378 super(qgd_Variational_Quantum_Eigensolver_Base, self).
set_Initial_State( initial_state )
395 normalized_density_noise
397 self.density_noise = [dict(item)
for item
in normalized_density_noise]
406 bridge_metadata = super(
407 qgd_Variational_Quantum_Eigensolver_Base, self
408 ).get_Density_Matrix_Bridge_Metadata()
409 bridge_metadata[
"density_noise"] = [dict(item)
for item
in self.density_noise]
410 return bridge_metadata
418 if not isinstance(Gate_structure, qgd_Circuit) :
419 raise Exception(
"Input parameter Gate_structure should be a an instance of Circuit")
def set_Optimization_Tolerance(self, tolerance)
def Optimization_Problem_Grad(self, parameters)
Call to evaluate the VQE energy.
def get_Parameter_Num(self)
Call to get the number of free parameters in the gate structure used for the decomposition.
def Generate_Circuit(self, layers, inner_blocks=1)
Call to generate the circuit ansatz.
def Optimization_Problem(self, parameters)
Call to evaluate the VQE energy.
def Start_Optimization(self)
Call to start solving the VQE problem to get the approximation for the ground state.
def set_Initial_State(self, initial_state)
Call to get the number of free parameters in the gate structure used for the decomposition.
def set_Optimizer(self, alg)
Call to set the optimizer used in the VQE process.
def apply_to(self, parameters_mtx, state_to_be_transformed)
def get_Qiskit_Circuit(self)
Export the unitary decomposition into Qiskit format.
def get_Second_Renyi_Entropy(self, parameters=None, input_state=None, qubit_list=None)
Call to get the second Rényi entropy.
A QGD Python interface class for the decomposition of N-qubit unitaries into U3 and CNOT gates...
def get_Optimized_Parameters(self)
Call to get the optimized parameters set in numpy array.
def describe_density_bridge(self)
Return reviewable metadata for the currently supported density bridge.
def _normalize_vqe_backend_name(backend)
def set_Gate_Structure_from_Binary(self, filename)
Call to set custom layers to the gate structure that are intended to be used in the decomposition fro...
def set_Ansatz(self, ansatz_new)
Call to set the ansatz type.
def get_Circuit(self)
Call to retrieve the incorporated quantum circuit (Squander format)
def set_Project_Name(self, project_name)
Call to set the name of the SQUANDER project.
def _normalize_density_noise_spec(density_noise)
def set_Density_Matrix_Noise(self, density_noise)
Configure ordered fixed local-noise insertions for the density backend.
def __init__(self, Hamiltonian, qbit_num, config=None, accelerator_num=0, backend=None, density_noise=None)
Constructor of the class.
def get_Qbit_Num(self)
Call to get the number of qubits in the circuit.
def set_Optimized_Parameters(self, new_params)
Call to set the parameters which are used as a starting point in the optimization.
def set_Gate_Structure(self, Gate_structure)
Call to set custom gate structure to used in the decomposition.