Comments (5)
I think a from_instruction
constructor for all the Pauli-like operators in quantum_info
is a fine direction to go, and in line with other things we have there.
All existing from_instruction
-type syntheses (see Clifford.from_instruction
and basically everything in qiskit.synthesis
) do this by methods that inspect the instructions and dispatch on them, and I'd suggest that that's a more consistent way to go rather than adding more magic decomposition methods to Instruction
and Gate
, which would be interface liabilities for us to change the internal representations of them. We might want to improve the way that user-defined classes hook into these in the future, but I think it's probably best to do that in bulk, if/when we look at it. It also rather simplifies the naming of the method: Pauli.from_instruction
, SparsePauliOp.from_instruction
and Clifford.from_instruction
all are absolutely clear what they do, but should XGate.to_symbolic
return a Pauli
, and SparsePauliOp
or a Clifford
? It's also easier to add new bits to the interface (new keyword arguments, etc) if it's a "from" method on a class we entirely control than a "to" method on classes that are intended to be subclassed.
from qiskit.
Actually, having just written that, two more thoughts:
Pauli.from_instruction
andSparsePauliOp.from_instruction
already actually exist in spirit, it's just embedded in the default constructor. You can doPauli(QuantumCircuit)
orPauli(Instruction)
(or withSparsePauliOp
) already. I wouldn't be opposed to exposing that formally in an explicit constructor if there's more to add to the interface.- It's not clear to me that
SparsePauliOp.from_instruction
offers any benefit overPauli.from_instruction
as opposed toSparsePauliOp(Pauli.from_instruction(...))
(which is give-or-take what happens internally already), just because I don't think we have many use-cases where anInstruction
represents several terms in a Pauli sum right now, except for use-cases that already wrapSparsePauliOp
internally (likePauliEvolutionGate
).
from qiskit.
Thanks for the input! I will do some more reading up on those existing paths.
From what I see, however, these also do not currently support parameterized Instruction
objects.
from qiskit.
In what situations are you expecting to have a parametric Instruction
object that can be converted to SparsePauliOp
? The Clifford
methods have some ways of checking if a value for a rotation gate is a multiple of Pauli
constructors.
from qiskit.
I can see a use-case where one might want to convert between a circuit operation (i.e. Gate
or Instruction
) and an operator in Pauli form. Since we have the ability to represent parameterized SparsePauliOp
objects, I don't think it is too far fetched that this can also be of interest.
Here is a very simple example for the case of a single parameterized RXGate
:
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import Operator, SparsePauliOp
qc = QuantumCircuit(1)
qc.rx(1.57, 0)
rx_instruction = qc[0].operation
print(rx_instruction)
sop = SparsePauliOp.from_operator(Operator(rx_instruction))
print(sop)
a = Parameter("a")
qc_p = QuantumCircuit(1)
qc_p.rx(1.57 * a, 0)
rx_instruction_p = qc_p[0].operation
print(rx_instruction_p)
print(a * sop)
This outputs:
Instruction(name='rx', num_qubits=1, num_clbits=0, params=[1.57])
SparsePauliOp(['I', 'X'],
coeffs=[0.70738827+0.j , 0. -0.70682518j])
Instruction(name='rx', num_qubits=1, num_clbits=0, params=[ParameterExpression(1.57*a)])
SparsePauliOp(['I', 'X'],
coeffs=[ParameterExpression(0.7073882691672*a),
ParameterExpression(-0.706825181105366*I*a)])
Trying sop = SparsePauliOp.from_operator(Operator(rx_instruction_p))
will fail because the unbound parameter a
cannot be cast to a float
:
Traceback (most recent call last):
File "/home/oss/Files/Dev/Qiskit/qiskit/main/tmp-sparse-pauli-gate.py", line 21, in <module>
sop_p = SparsePauliOp.from_operator(Operator(rx_instruction_p))
File "/home/oss/Files/Dev/Qiskit/qiskit/main/qiskit/quantum_info/operators/operator.py", line 97, in __init__
self._data = self._init_instruction(data).data
File "/home/oss/Files/Dev/Qiskit/qiskit/main/qiskit/quantum_info/operators/operator.py", line 700, in _init_instruction
return Operator(np.array(instruction, dtype=complex))
File "/home/oss/Files/Dev/Qiskit/qiskit/main/qiskit/circuit/library/standard_gates/rx.py", line 125, in __array__
cos = math.cos(self.params[0] / 2)
File "/home/oss/Files/Dev/Qiskit/qiskit/main/qiskit/circuit/parameterexpression.py", line 415, in __float__
raise TypeError(
TypeError: ParameterExpression with unbound parameters (dict_keys([Parameter(a)])) cannot be cast to a float.
I am aware that my proposal has quite some caveats and I also understand that a user may be facing a possibly exponential blow-up of parameter expressions when doing the above repeatedly and composing the results. Nonetheless, I think that a "symbolic" interpretation of a gate in terms of Pauli terms can have value.
By that I mean a way to convert standard gates such as RX(a)
to a form like this: cos(a / 2) * I - i * sin(a / 2) * X
.
from qiskit.
Related Issues (20)
- Add function to remove inactive qubits from circuit HOT 2
- Pulse parameter assignment bug
- `UnitarySynthesis` silently decomposes to invalid bases
- `ConsolidateBlocks` can collect valid blocks that cannot be resynthesised in `optimization_level=3` HOT 2
- Add support for a visual-only `Barrier`
- Pip information missing home-page and author information for Qiskit 1.0.2 HOT 4
- DAG `node._node_id` should be public HOT 3
- KeyError: 'cr' when loading a circuit containing c_if using qpy HOT 3
- ValueError: too many subscripts in einsum for a circuit containing controlled RZXGate HOT 2
- Invalid param type <class 'numpy.ndarray'> for gate unitary*1 HOT 1
- DAGCircuitError: 'bit mapping invalid: expected 1, got 2' for SXGate with reverse_ops after qpy roundtrip
- QPY serialization inconsistency for a circuit containing U2Gate.power().control()
- Scheduling stage doesn't use custom dt when target provided HOT 7
- Constructing Target with if_else gives KeyError HOT 1
- Add `SXGate` to supported gates in `TwoLocal` circuits HOT 1
- Port TwoQubitBasisDecomposition to Rust
- Port XXDecomposer to Rust
- Expand unitary synthesis plugin interface to support synthesizing batches of unitary matrices
- Add parallel synthesis interface to default unitary synthesis plugin HOT 1
- Port TwoQubitWeylDecomposition to Rust
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qiskit.