qiboteam / qibo

A full-stack framework for quantum computing.
https://qibo.science
Apache License 2.0
295 stars 60 forks source link

Parameterized gates for GST #1502

Open mho291 opened 4 weeks ago

mho291 commented 4 weeks ago

In this current version of gate set tomography, it seems like only non-parameterized gates can be passed into GST.

There are two ways that I generate non-parameterized gates:

gate_set = [gates.I, gates.X, gates.H, gates.S]

or

target_gates = [gates.SX(0), gates.Z(0), gates.RX(0, np.pi/2)]
gate_set = [g.__class__ for g in target_gates]

Then we pass them into GST:

from qibo.tomography import gate_set_tomography 
gate_set_tomography.GST(gate_set=gate_set, 
                        nshots=int(1e3), 
                        noise_model=None, 
                        include_empty=True, 
                        pauli_liouville=False, 
                        gauge_matrix=None, 
                        backend=NumpyBackend())

In lines 288-300 of gate_set_tomography.py, which is this:

for gate in gate_set:
        if gate is not None:
            init_args = signature(gate).parameters
            if "q" in init_args:
                nqubits = 1
            elif "q0" in init_args and "q1" in init_args and "q2" not in init_args:
                nqubits = 2
            else:
                raise_error(
                    RuntimeError,
                    f"Gate {gate} is not supported for `GST`, only 1- and 2-qubits gates are supported.",
                )
            gate = gate(*range(nqubits))

it only extracts which qubits the gate acts on. I've tried to extract the parameters from the gates in gate_set but it always returns something like this `<property object at 0x123456789>, i.e.

target_gates = [gates.SX(0), gates.Z(0), gates.RX(0, np.pi/2)]
gate_set = [g.__class__ for g in target_gates]

print(gate_set[2].parameters)

>> <property object at 0x123456789> 

Looking back at our input for gate_set, it turns out that it's difficult to extract parameters from each of the gates in gate_set.

I realise that if we can extract the parameters from the target_gates.

target_gates = [gates.SX(0), gates.Z(0), gates.RX(0, np.pi/2)]

print(target_gates[2].parameters)

> (1.5707963267948966,)

Hence, for GST, is there another way of inputting the gates instead of doing gate_set = [g.__class__ for g in target_gates]?

alecandido commented 4 weeks ago

.parameters is a property bound to an instance. If you take the class, there is no way you can access parameters

[ins] In [1]: from qibo.gates import RX
[ins] In [2]: g = RX(0, 1.23)
[ins] In [3]: g.parameters
Out[3]: (1.23,)
[ins] In [4]: RX.parameters
Out[4]: <property at 0x121d0e160>
[ins] In [5]: g.__class__
Out[5]: qibo.gates.gates.RX

I.e. an instance is a container of its state (its attributes). If you take the class, you're extracting some information about the type, but the state is completely lost.

If you are interested in the content of the instance (e.g. the .parameters property, generated from the underlying attributes), you should keep the whole instance, not just its type.

mho291 commented 4 weeks ago

Thanks for the explanation @alecandido, it confirms my suspicions. GST works as is, but only for non-parameterized gates. We'll need to tweak it, by keeping whole instances of the gates, for parameterized gates.