0
$\begingroup$

I want to implement the parametric power of a gate.

I know that the parametric power is impractical to implement (cf https://github.com/Qiskit/qiskit-terra/issues/4751). So, I want to delay the construction of the power of the matrix when I have already the numerical values of the parameters but still use a parametric circuit.

The original idea was posted in Creating a parameterized Operator in Qiskit .

So far, I have tried to implement it in 2 different ways. Both of them give the same error. Here is a simplified version of both ways I've tried:

from qiskit import Aer
from qiskit import transpile
from qiskit import QuantumCircuit
from qiskit import QuantumRegister

from qiskit.circuit import Parameter
from qiskit.circuit import Gate

from qiskit.circuit.library.standard_gates.p import PhaseGate


class PowerNGate(Gate):
    def __init__(self, nbqbits, p_g, power_n, theta, label=None):
        self.evol_f = p_g
        self.power_n = power_n
        super().__init__('N', nbqbits, [theta], label=label)

    def _define(self):
        t = float(self.params[0])
        evol_g = self.evol_f(t)
        self.definition = evol_g.power(self.power_n)


t = Parameter('θ')


def p_g(dt): return PhaseGate(dt)


p_N = PowerNGate(1, p_g, 2, t)

qr = QuantumRegister(1)
qc = QuantumCircuit(qr)
qc.append(p_N, qr)

print(qc)

qc_a = qc.assign_parameters({t: 0.5})

print(qc_a)

simulator = Aer.get_backend("aer_simulator")
t_c = transpile(qc_a, simulator)

t_c.save_statevector()
result = simulator.run(t_c).result()

o_s = result.get_statevector()

print(o_s)

I also tried:

from qiskit import Aer
from qiskit import transpile
from qiskit import QuantumCircuit
from qiskit import QuantumRegister

from qiskit.circuit import Parameter
from qiskit.circuit import Gate

from qiskit.circuit.library.standard_gates.p import PhaseGate


class PowerNGate(Gate):
    def __init__(self, gate_, power_n, label=None):
        self.num_qubits = gate_.num_qubits
        self.power_n = power_n
        self.basis_gate = gate_
        super().__init__('N', self.num_qubits, gate_.params, label=label)

    def _define(self):
        t = float(self.params[0])
        assigned_basis_gate = self.basis_gate.assign_parameters(
            {self.params: t})
        self.definition = assigned_basis_gate.power(self.power_n)


t = Parameter('θ')

p_g = PhaseGate(t)

p_N = PowerNGate(p_g, 2)

qr = QuantumRegister(1)
qc = QuantumCircuit(qr)
qc.append(p_N, qr)

print(qc)

qc_a = qc.assign_parameters({t: 0.5})

print(qc_a)


simulator = Aer.get_backend("aer_simulator")

t_c = transpile(qc_a, simulator)

t_c.save_statevector()
result = simulator.run(t_c).result()

o_s = result.get_statevector()

print(o_s)

Both implementations give me the following error:

** QiskitError: "Cannot unroll the circuit to the given basis, ['ccx', 'cp', 'cswap', 'csx', 'cu', 'cu1', 'cu2', 'cu3', 'cx', 'cy', 'cz', 'delay', 'diagonal', 'h', 'id', 'initialize', 'mcp', 'mcphase', 'mcr', 'mcrx', 'mcry', 'mcrz', 'mcswap', 'mcsx', 'mcu', 'mcu1', 'mcu2', 'mcu3', 'mcx', 'mcx_gray', 'mcy', 'mcz', 'multiplexer', 'p', 'pauli', 'r', 'roerror', 'rx', 'rxx', 'ry', 'ryy', 'rz', 'rzx', 'rzz', 's', 'sdg', 'swap', 'sx', 'sxdg', 't', 'tdg', 'u', 'u1', 'u2', 'u3', 'unitary', 'x', 'y', 'z', 'kraus', 'roerror', 'save_amplitudes', 'save_amplitudes_sq', 'save_density_matrix', 'save_expval', 'save_expval_var', 'save_matrix_product_state', 'save_probabilities', 'save_probabilities_dict', 'save_stabilizer', 'save_state', 'save_statevector', 'save_statevector_dict', 'save_superop', 'save_unitary', 'set_density_matrix', 'set_matrix_product_state', 'set_stabilizer', 'set_statevector', 'set_superop', 'set_unitary', 'snapshot', 'superop']. Instruction N not found in equivalence library and no rule found to expand." **

Thanks for any feedback.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.