Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IterativeAmplitudeEstimation with Primitives Sampler #9384

Closed
GiuliaFranco opened this issue Jan 18, 2023 · 7 comments
Closed

IterativeAmplitudeEstimation with Primitives Sampler #9384

GiuliaFranco opened this issue Jan 18, 2023 · 7 comments
Labels
bug Something isn't working mod: algorithms Related to the Algorithms module

Comments

@GiuliaFranco
Copy link

GiuliaFranco commented Jan 18, 2023

Environment

  • Qiskit Terra version: 0.22.3
  • Python version: 3.9.15
  • Operating system: Windows 11

What is happening?

The question regards the use of the IterativeAmplitudeEstimation class (and its methods like estimate or construct_circuit) with the new Sampler paradigm. We conducted several different experiments with different Sampler implementations but were never completely successful.
If we use the formulation with context managers and the qiskit_ibm_runtime Sampler, we get a specific runtime error ERROR Failed to execute program: init() missing 1 required positional argument: 'num_ctrl_qubits' that causes the AlgorithmError: 'The job was not completed successfully. ' . However the same code runs just fine using the old QuantumInstance class or even using the sampler from qiskit.primitives without context managers.
The second main experiment was conducted using exactly the setting just described (with the sampler from qiskit.primitives and no context manager) and was executed successfully, but produced wrong results. In particular, the probability of being 0 increases for the objective qubit as k increases, regardless of the rest of the circuit. Again this code runs fine with QauntumInstance and produces the expected results.
Are we missing something? The only significant line of code that was changed is the following:
iae = IterativeAmplitudeEstimation(epsilon, alpha=alpha, quantum_instance=qi) into
iae = IterativeAmplitudeEstimation(epsilon, alpha=alpha, sampler=sampler) where sampler = Sampler() for the second experiment

How can we reproduce the issue?

image (2)

What should happen?

If we use the formulation with context managers and the qiskit_ibm_runtime Sampler, we get a specific runtime error ERROR Failed to execute program: init() missing 1 required positional argument: 'num_ctrl_qubits' that causes the AlgorithmError: 'The job was not completed successfully. '

Any suggestions?

No response

@GiuliaFranco GiuliaFranco added the bug Something isn't working label Jan 18, 2023
@woodsp-ibm woodsp-ibm added the mod: algorithms Related to the Algorithms module label Jan 18, 2023
@Cryoris
Copy link
Contributor

Cryoris commented Jan 18, 2023

Thanks for reporting this @GiuliaFranco! Could you post the entire snippet of the second scenario that produces the wrong results? 🙂

@GiuliaFranco
Copy link
Author

GiuliaFranco commented Jan 19, 2023

Hi😊 Sure here the codes snippet

import numpy as np

from qiskit import QuantumRegister, QuantumCircuit, Aer, execute
from qiskit.utils import QuantumInstance
from qiskit.algorithms import IterativeAmplitudeEstimation, EstimationProblem

from qiskit_finance.circuit.library import GaussianConditionalIndependenceModel as GCI
from qiskit.circuit.library import WeightedAdder
from qiskit.circuit.library import LinearAmplitudeFunction
from qiskit.primitives import Sampler

# set problem parameters
n_z = 2
z_max = 2
z_values = np.linspace(-z_max, z_max, 2**n_z)
p_zeros = [0.15, 0.25]
rhos = [0.1, 0.05]
lgd = [1, 2]
K = len(p_zeros)
alpha = 0.05

u = GCI(n_z, z_max, p_zeros, rhos)

# add Z qubits with weight/loss 0
agg = WeightedAdder(n_z + K, [0] * n_z + lgd)

# define linear objective function
breakpoints = [0]
slopes = [1]
offsets = [0]
f_min = 0
f_max = sum(lgd)
c_approx = 0.25

objective = LinearAmplitudeFunction(
    agg.num_sum_qubits,
    slope=slopes,
    offset=offsets,
    # max value that can be reached by the qubit register (will not always be reached)
    domain=(0, 2**agg.num_sum_qubits - 1),
    image=(f_min, f_max),
    rescaling_factor=c_approx,
    breakpoints=breakpoints,
)

# define the registers for convenience and readability
qr_state = QuantumRegister(u.num_qubits, "state")
qr_sum = QuantumRegister(agg.num_sum_qubits, "sum")
qr_carry = QuantumRegister(agg.num_carry_qubits, "carry")
qr_obj = QuantumRegister(1, "objective")

# define the circuit
state_preparation = QuantumCircuit(qr_state, qr_obj, qr_sum, qr_carry, name="A")

# load the random variable
state_preparation.append(u.to_gate(), qr_state)

# aggregate
state_preparation.append(agg.to_gate(), qr_state[:] + qr_sum[:] + qr_carry[:])

# linear objective function
state_preparation.append(objective.to_gate(), qr_sum[:] + qr_obj[:])

# uncompute aggregation
state_preparation.append(agg.to_gate().inverse(), qr_state[:] + qr_sum[:] + qr_carry[:])


# set target precision and confidence level
epsilon = 0.01
alpha = 0.05

qi = QuantumInstance(Aer.get_backend("aer_simulator"), shots=100)
problem = EstimationProblem(
    state_preparation=state_preparation,
    objective_qubits=[len(qr_state)],
    post_processing=objective.post_processing,
)
# construct amplitude estimation
iae = IterativeAmplitudeEstimation(epsilon, alpha=alpha, quantum_instance=qi)
result = iae.estimate(problem)

# print results
conf_int = np.array(result.confidence_interval_processed)
print("Estimated value with QuantumInstance:\t%.4f" % result.estimation_processed)
print("Confidence interval: \t[%.4f, %.4f]" % tuple(conf_int))


sampler = Sampler()
problem = EstimationProblem(
    state_preparation=state_preparation,
    objective_qubits=[len(qr_state)],
    post_processing=objective.post_processing,
)
# construct amplitude estimation
iae_sampler = IterativeAmplitudeEstimation(epsilon, alpha=alpha, sampler=sampler)
result_sampler = iae_sampler.estimate(problem)

# print results
conf_int_sampler = np.array(result_sampler.confidence_interval_processed)
print("Estimated value with Sampler Primitive:", result_sampler.estimation)
print("Confidence interval: \t[%.4f, %.4f]" % tuple(conf_int_sampler))

@GiuliaFranco
Copy link
Author

Here some details on expected results:

Estimated value with QuantumInstance: 0.6651
Confidence interval: [0.6480, 0.6822]

Estimated value with Sampler Primitive: 0.0
Confidence interval: [-2.3197, -2.3197]

@ElePT
Copy link
Contributor

ElePT commented Jan 19, 2023

Hi @GiuliaFranco! The root cause of the runtime primitive issue is here: #9390. I am just about to open a bugfix PR that should solve it.

@ElePT
Copy link
Contributor

ElePT commented Jan 19, 2023

PR: #9391

@Cryoris
Copy link
Contributor

Cryoris commented Jan 19, 2023

And the other bug is caused by a padding of the measurement results with the number of qubits instead of classical bits -- PR follows 🙂 Edit: see #9394.

@woodsp-ibm
Copy link
Member

#9391 Fixed the num_ctrl_qubits problem when using the runtime .
#9394 Fixed the incorrect result problem

As such the two problems this issue raised have been fixed so I am closing this as completed. FYI the fixes will be in the imminent 0.23.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mod: algorithms Related to the Algorithms module
Projects
None yet
Development

No branches or pull requests

4 participants