1
$\begingroup$

I'm working on a portfolio optimization problem using Qiskit and I'm encountering an error when trying to solve a quadratic program using MinimumEigenOptimizer with SamplingVQE. Any insights on what might be causing this error or how to fix it would be greatly appreciated!

Here's the code I'm using:

from qiskit_algorithms import SamplingVQE
from qiskit_finance.applications.optimization import PortfolioOptimization
from qiskit_finance.data_providers import RandomDataProvider
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit_ibm_runtime import QiskitRuntimeService, Session, SamplerV2 as Sampler
from qiskit.circuit.library import RealAmplitudes
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_algorithms.optimizers import SLSQP
import numpy as np
import datetime

num_assets = 30
seed = 123

# Generate expected return and covariance matrix from (random) time-series
stocks = [("TICKER%s" % i) for i in range(num_assets)]
data = RandomDataProvider(
    tickers=stocks,
    start=datetime.datetime(2016, 1, 1),
    end=datetime.datetime(2016, 1, 30),
    seed=seed,
)
data.run()
mu = data.get_period_return_mean_vector()
sigma = data.get_period_return_covariance_matrix()

q = 0.5  # set risk factor
budget = num_assets // 2  # set budget
penalty = num_assets  # set parameter to scale the budget penalty term

portfolio = PortfolioOptimization(
    expected_returns=mu, covariances=sigma, risk_factor=q, budget=budget
)
qp = portfolio.to_quadratic_program()

service = QiskitRuntimeService(channel="ibm_quantum")
backend = service.least_busy(operational=True, simulator=False)
session = Session(service=service, backend=backend)

ansatz = RealAmplitudes(qp.get_num_binary_vars(), reps=3)
pm = generate_preset_pass_manager(backend=backend, optimization_level=2)
isa_circuit = pm.run(ansatz)

vqe = SamplingVQE(sampler=Sampler(session=session), ansatz= isa_circuit, optimizer=SLSQP())  
optimizer = MinimumEigenOptimizer(vqe)
result = optimizer.solve(qp)
print(result)

When I run this code, I get the following error:

TypeError: run() takes 2 positional arguments but 3 were given

Here's the full traceback:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
...
File ~/opt/anaconda3/lib/python3.8/site-packages/qiskit_algorithms/minimum_eigensolvers/sampling_vqe.py:318, in SamplingVQE._get_evaluate_energy.<locals>.evaluate_energy(parameters)
    315 parameters = np.reshape(parameters, (-1, num_parameters)).tolist()
    316 batch_size = len(parameters)
--> 318 estimator_result = estimator.run(
    319     batch_size * [ansatz], batch_size * [operator], parameters
    320 ).result()
    321 values = estimator_result.values
    323 if self.callback is not None:

File ~/opt/anaconda3/lib/python3.8/site-packages/qiskit/primitives/primitive_job.py:51, in PrimitiveJob.result(self)
     49 def result(self) -> ResultT:
     50     self._check_submitted()
---> 51     return self._future.result()

File ~/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py:437, in Future.result(self, timeout)
    435     raise CancelledError()
    436 elif self._state == FINISHED:
--> 437     return self.__get_result()
    439 self._condition.wait(timeout)
    441 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:

File ~/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py:389, in Future.__get_result(self)
    387 if self._exception:
    388     try:
--> 389         raise self._exception
    390     finally:
    391         # Break a reference cycle with the exception in self._exception
    392         self = None

File ~/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py:57, in _WorkItem.run(self)
     54     return
     56 try:
---> 57     result = self.fn(*self.args, **self.kwargs)
     58 except BaseException as exc:
     59     self.future.set_exception(exc)

File ~/opt/anaconda3/lib/python3.8/site-packages/qiskit_algorithms/minimum_eigensolvers/diagonal_estimator.py:117, in _DiagonalEstimator._call(self, circuits, observables, parameter_values, **run_options)
    110 def _call(
    111     self,
    112     circuits: Sequence[int],
   ...
    115     **run_options,
    116 ) -> _DiagonalEstimatorResult:
--> 117     job = self.sampler.run(
    118         [self._circuits[i] for i in circuits],
    119         parameter_values,
    120         **run_options,
    121     )
    122     sampler_result = job.result()
    123     samples = sampler_result.quasi_dists

TypeError: run() takes 2 positional arguments but 3 were given
```
$\endgroup$
1
  • $\begingroup$ Thanks to one of the replies, I've adjusted the code to use the V1 primitives. However, I've encountered a new issue regarding the compatibility of the ansatz circuit with the operator. AlgorithmError: 'The number of qubits of the ansatz does not match the operator, and the ansatz does not allow setting the number of qubits using num_qubits.' Any idea of how could I solve it? $\endgroup$
    – Ivan
    Commented May 23 at 19:56

1 Answer 1

1
$\begingroup$

Qiskit Optimization (ML, Finance and Nature) and Qiskit Algorithms all support only the V1 primitives. There are issues in all of the github repos of above for support of V2. So you need to use the V1 primitives for now.

$\endgroup$
1
  • $\begingroup$ Thank you very much for your response and guidance. I've adjusted the code to use the V1 primitives as suggested. However, I've encountered a new issue regarding the compatibility of the ansatz circuit with the operator. AlgorithmError: 'The number of qubits of the ansatz does not match the operator, and the ansatz does not allow setting the number of qubits using num_qubits.' Any idea of how could I solve it? $\endgroup$
    – Ivan
    Commented May 23 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.