2

I would like to use the built-in Qiskit VQE() function, with my own variational form. What is the proper way to define it? I was expecting var_form to be simply a function returning an object of type QuantumCircuit for a particular set of parameters (that's how it's done in Pyquil).

More precisely: how do I manually create an instance of the VariationalForm class which would correspond to preparing the desired program for a given set of parameters?

So far my understanding is that I have to do smth like that:

 class my_var_form(VariationalForm):
    def construct_circuit(self,
                          parameters: Union[List[float], np.ndarray],
                          q: Optional[QuantumRegister] = None) -> NoReturn:
        circuit = QuantumCircuit(q)
        ...
        return circuit

Is this the proper way to do things?

CLARIFICATION

Let us define a function which would generate a Qiskit circuit for an arbitrary parameter of type float:

def black_box( param : float ):
    qc = qskt.QuantumCircuit( 1 )
    qc.u1( np.sqrt( param ), 0 )
    return qc

np.sqrt() was chosen as a toy example, one could equally well replace it with any fucntion defined on floats. To make sure that the function makes sense, one can do this:

job = execute( black_box( 1. ), get_backend('qasm_simulator') ) # Works fine

Now, let us try to define a VariationalForm which will use our black_box function:

class my_var_form( VariationalForm ):
    def __init__(self, numpar, numq, bnds) -> None:
        super().__init__()
        self._num_parameters = numpar
        self._num_qubits = numq
        self._bounds = bnds
        pass
    def construct_circuit(self,
                          parameters: Union[List[float], np.ndarray],
                          q: Optional[qskt.QuantumRegister] = None) -> NoReturn:
    circuit = black_box( parameters[0] )
    return circuit

However, the following code fails to work:

var_form_instance = my_var_form( 1, 1, [[-2., 2]] )
vqe = VQE( WeightedPauliOperator( [1., Pauli([0.],[0.])] ),
           var_form_instance,
           L_BFGS_B(),
           np.array([0])
         )

With the following error:

TypeError: loop of ufunc does not support argument 0 of type Parameter which has no callable sqrt method

The problem is that Qiskit no matter what wants to use its built-in Parameter class which is based on the sympy package.

How can I overcome this issue? Or is there absolutely no way I could use the built-in VQE function without dealing with Parameter class?

My question arises from the fact that I use an external library to generate circuits which I then convert to Qiskit format. Thus, I have a function which returns a Qiskit circuit for a set of real parameters. I would like the Qiskit VQE() function to use my own black_box() function for generating the quantum circuit on each step of the minimization.

(Alternatively, I could just not use VQE() at all, and simply run the classical minimizer myself, only using Qiskit for evaluating the expectation value of the Hamiltonian on each step... but apparently there's no built-in function for calculating the expectation value neither of a Pauli string, nor even of individual Pauli operators! See my question here: to my understanding SnapshotExpectationValue() is an unphysical method, and does not allow one to calculate expectation values of Pauli strings using sampling on real devices.)

mavzolej
  • 2,271
  • 9
  • 18

3 Answers3

5

You can plug any parameterized QuantumCircuit into the VQE. Parameterized means it contains Parameter objects e.g. as rotation angles. For instance

from qiskit.circuit import QuantumCircuit, ParameterVector
from qiskit.aqua.algorithms import VQE

params = ParameterVector(3)
wavefunction = QuantumCircuit(3)
wavefunction.ry(params[0], 0)
wavefunction.ry(params[1], 1)
wavefunction.ry(params[2], 2)

vqe = VQE(var_form=wavefunction, ...)

I'd suggest you to have a look at the circuit library, especially the N-local circuits as e.g. the TwoLocal circuit.

This notebook explains this in more detail and shows some of the new functionality of Qiskit 0.19.0 concerning the circuit library and how it interacts with Aqua.

Cryoris
  • 2,993
  • 8
  • 15
2

You basically have to construct:

  1. A parametrized circuit
  2. Objective function which returns the cost
  3. Minimize the cost with the classical optimizer eg. COBYLA

Example: https://qiskit.org/textbook/ch-applications/vqe-molecules.html#Example-with-a-Single-Qubit-Variational-Form

1

I haven't tried, but probably you can create your own type which extends ParameterExpression type(class) and define your custom function (in this case sqrt) so that it can be applied on the Parameter obj during the training/testing phase. Paramter objects can only evaluate basic arithmetic operations, which probably you might have already observed.

May be I will try and let you know if it works. But looks possible.

Abbyss
  • 81
  • 3