Open chriseclectic opened 6 months ago
For the current definition of the V2 primitives, the only Qiskit-defined class other than SparsePauliOp
that can be given as an observable is Pauli
, which we could add apply_layout
to. That doesn't affect the free-form inputs that BaseEstimatorV2
is also required to accept - str
and dict
, but for those, we either have a loose function (which presumably would need to live in qiskit.primitives
, since it's a primitives-specific interpretation of standard Python classes), or more naturally we'd put it on the primitives container classes that these get coerced to, except that those aren't public, and also I don't think are actually valid as user inputs to the primitives anyway.
Fwiw, I feel like apply_layout
is a (quite possibly necessary) hack around a more preferential input format which would have specified the qubits the entire ObservableArray
was supposed to act on separately to the observables themselves, like how Qiskit Instruction
instances don't contain the specific qubits (and aren't full-width on the circuit), but their context object (the CircuitInstruction
, in this analogy) contains them.
I'm totally fine to add Pauli.apply_layout
to ease this in the short term, and it does feel weird that we have SparsePauliOp.apply_layout
but not Pauli.apply_layout
. I'm somewhat against adding BaseOperator.apply_layout
, because we don't really have a use for that, and adding an extra way to make it super easy to request a universe-ending amount of memory is probably something we'd be better keeping away from users who don't necessarily understand what Operator
is if it's not needed.
Since #12066 merged, we've got apply_layout
on everything that's a possible input to the EstimatorV2
primitive, I think, which should bridge the gap before we know what a complete solution to #11825 looks like end-to-end and the timescale of that.
For this issue, I guess the question is: is it worth putting method on the base class to fill it in for all the remaining classes, which at this point are mostly (maybe only?) things that can't possibly represent the expanded operator for any layout that they're likely to be given? It potentially feels safer to me not to offer the API opportunity to make the mistake, and to argue that apply_layout
only really makes sense for things that have some degree of sparsity to them (which even Pauli
and SparsePauliOp
don't entirely).
What should we add?
apply_layout
was added to SparsePauliOp at some point, but not to other operators (eg Pauli).This method could in theory be added to
BaseOperator
to apply to any operator (caveat, it requires ScalarOp which is a subclass of BaseOperator, and you could easily blow up your computers memory if you try and apply a large qubit layout to a channel op or Operator).This function generalizes the current function to work for any n-qubit BaseOperator subclass: