Closed lasys closed 2 years ago
Hello @lasys, thank you for your interest in Mitiq! If this is a bug report, please provide screenshots and/or minimum viable code to reproduce your issue, so we can do our best to help get it fixed. If you have any questions in the meantime, you can also ask us on the Unitary Fund Discord.
Hello @lasys,
The error is related to a conversion problem from Qiskit to Cirq (which is the internal representation used by Mitiq). Probably the problem is due to parameterized (symbolic) gates.
However I think the main problem is another one. The object that you define as noisy_executor
must be a function which input a circuit and returns an expectation value in order to be compatible with Mitiq. In your case instead it is indirectly defined by using energy_evaluation
which is a function from the set of variational parameters to an expectation value (the input circuit is not an argument). I think this is the main problem. I am not sure what could be a simple solution, but I would probably try to add Mitiq somewhere in self.get_energy_evaluation()
instead of changing self.compute_minimum_eigenvalue()
.
Good luck!
The only relevant portion from the colab is below.
energy_evaluation, expectation = self.get_energy_evaluation(
operator, return_expectation=True
)
# insert mitiq
# Choose a noise scaling method
scaling_method = mitiq.zne.scaling.fold_global
# Initialize an inference method (i.e. a Mitiq Factory)
inference_factory = mitiq.zne.inference.LinearFactory(scale_factors=[1.0, 3.0])
noisy_executor = partial(energy_evaluation)
mitigated_executor = mitigate_executor(noisy_executor, inference_factory, scaling_method)
mitigated_executor = mitigated_executor(self.ansatz)
Problems:
type(self.ansatz)
is QAOAAnsatz but needs to be qiskit.QuantumCircuit
.
energy_evaluation
does not have the signature qiskit.QuantumCircuit -> float
and so cannot be used with mitigate_executor
.
energy_evaluation
is List[float] -> float
.There's a line in energy_evaluation
which says:
sampled_expect_op = self._circuit_sampler.convert(expect_op, params=param_bindings)
To use Mitiq in this example, you probably need to apply mitigate_executor
to something in self._circuit_sampler
.
My main takeaway from this is we should print out the circuit in CircuitConversionError
s.
Totally missed @andreamari's comment somehow 🙃 at least we had more-or-less the same conclusions.
This issue had no activity for 2 months, and will be closed in one week unless there is new activity. Cheers!
Sorry for the late reply. I have found a solution and implemented it as follows.
def get_energy_evaluation(
self,
operator: OperatorBase,
return_expectation: bool = False,
) -> Callable[[np.ndarray], Union[float, List[float]]]:
"""Returns a function handle to evaluates the energy at given parameters for the ansatz.
This is the objective function to be passed to the optimizer that is used for evaluation.
Args:
operator: The operator whose energy to evaluate.
return_expectation: If True, return the ``ExpectationBase`` expectation converter used
in the construction of the expectation value. Useful e.g. to evaluate other
operators with the same expectation value converter.
Returns:
Energy of the hamiltonian of each parameter, and, optionally, the expectation
converter.
Raises:
RuntimeError: If the circuit is not parameterized (i.e. has 0 free parameters).
"""
num_parameters = self.ansatz.num_parameters
if num_parameters == 0:
raise RuntimeError("The ansatz must be parameterized, but has 0 free parameters.")
expect_op, expectation = self.construct_expectation(
self._ansatz_params, operator, return_expectation=True
)
# create circuit for ZNE
param_dict = dict(zip(self._ansatz_params, self._initial_point)) # type: Dict
circuit = self.ansatz.assign_parameters(param_dict)
def energy_evaluation(parameters):
if circuit != None:
# Initialize an inference method (i.e. a Mitiq Factory)
scaling_method = mitiq.zne.scaling.fold_global
inference_factory = mitiq.zne.inference.LinearFactory(scale_factors=[1.0, 3.0])
# See mitiq maxcut-example
noisy_executor = partial(real_energy_evaluation, parameters=parameters)
mitigated_executor = mitigate_executor(noisy_executor, inference_factory, scaling_method)
mitigated_executor = mitigated_executor(circuit)
return mitigated_executor
print("Don't use zne")
return real_energy_evaluation(None, parameters)
def real_energy_evaluation(cc, parameters):
parameter_sets = np.reshape(parameters, (-1, num_parameters))
# Create dict associating each parameter with the lists of parameterization values for it
param_bindings = dict(zip(self._ansatz_params, parameter_sets.transpose().tolist()))
start_time = time()
sampled_expect_op = self._circuit_sampler.convert(expect_op, params=param_bindings)
means = np.real(sampled_expect_op.eval())
if self._callback is not None:
variance = np.real(expectation.compute_variance(sampled_expect_op))
estimator_error = np.sqrt(variance / self.quantum_instance.run_config.shots)
for i, param_set in enumerate(parameter_sets):
self._eval_count += 1
self._callback(self._eval_count, param_set, means[i], estimator_error[i])
else:
self._eval_count += len(means)
end_time = time()
logger.info(
"Energy evaluation returned %s - %.5f (ms), eval count: %s",
means,
(end_time - start_time) * 1000,
self._eval_count,
)
return means if len(means) > 1 else means[0]
if return_expectation:
return energy_evaluation, expectation
return energy_evaluation
I also added Clifford Data Regression in the same function energy_evaluation
in another project.
If you have nothing to add, the issue can be closed.
Thank you very much for your help and work!
Thanks @lasys. I think there could be value in adding a "Mitiq with variational ansatze in Qiskit" example to the documentation. If you'd be interested in writing this using your example as a foundation, please let me know! I'll close this issue and open a new issue for the documentation.
Hello,
i would like to integrate mitiq into the QAOA-Class from Qiskit.
My idea was to change the lines in the VQE-Class as follows:
When i run the code with:
Unfortunately i get this error:
Does anyone have a suggestion on how to fix this or have another suggestion on how to integrate mitiq? Thanks a lot for your help!
EDIT:
Here ist the code: Colab