Closed juliabarbera closed 1 year ago
The Unitary gate allows you to add any matrix as a gate to a circuit, for example
import numpy as np
from qibo import models, gates
c = models.Circuit(3)
matrix = np.random.random((4, 4)) # random 4x4 matrix
c.add(gates.Unitary(matrix, 0, 1)) # act with the matrix on qubits 0 and 1
This will apply the matrix by multiplying it to the state vector with proper indexing according to the target qubits.
Is your diagonal matrix very large? There may be a decrease in performance if the matrix (or number of target qubits) is large because this method will not exploit the fact that it is diagonal, as it works for an arbitrary matrix too.
Thank you for your answer. I want to perform something like this:
Where state is an integer.
It seems that the number of targets is the total number of qubits in the circuit. The gates.Unitary
approach will work, but you will probably notice some deterioration if nqubits > 10 and eventually run out of memory, because it will be creating a dense matrix of size (2^nqubits, 2^nqubits).
If I understand correctly, the matrix you are applying is the identity, with a single 1 flipped to -1 in the position defined by state
. If state == nqubits - 1
this is a Z gate controlled on all qubits, which you can add as:
c.add(gates.Z(nqubits - 1).controlled_by(*range(nqubits - 1)))
If state != nqubits - 1
, I believe you can still do this with the same gate if you apply X gates to move the -1 to the appropriate place:
c.add(gates.X(q))
c.add(gates.Z(nqubits - 1).controlled_by(*range(nqubits - 1)))
c.add(gates.X(q))
where q
depends on state
. This approach is slightly more complicated to code but depending on your total circuit, may be faster, because controlled gates are applied with indexing which is more efficient than creating a big matrix.
EDIT (more details): The X gate should be applied in all qubits that correspond to 0 when you represent state
in binary. So if state == 0
you'll have to apply X to all qubits, etc., that's why how efficient this is depends on the value of state
.
Concerning the implementation of these types of gates, it might be valuable to implement an "Oracle" gate in a more native way in Qibo in order to accommodate fast simulation of Grover (and amplitude amplification-like) algorithms.
Something like:
c.add(gates.Oracle(*q, [states]))
where q
is the qubit register where the oracle is applied, and the states
are the target states that are to be flipped.
From there, the decomposition to gates, and then to two-qubit gates for implementation, can be automatized.
Thank you for the review. I have used gates.Unitary
and it worked.
I will implement quantum gates but first I wanted to calculate the matrix classically.
I was looking for the way to add a diagonal matrix in Qibo language which doesn't correspond to any quantum logic gate to a circuit. How can I do that?