# (C) Copyright IBM 2024.## This code is licensed under the Apache License, Version 2.0. You may# obtain a copy of this license in the LICENSE.txt file in the root directory# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.## Any modifications or derivative works of this code must retain this# copyright notice, and modified files need to carry a notice indicating# that they have been altered from the originals."""Jordan-Wigner transformation."""from__future__importannotationsfromqiskit.quantum_infoimportSparsePauliOpfromffsimimport_libfromffsim.operatorsimportFermionOperator
[docs]defjordan_wigner(op:FermionOperator,norb:int|None=None,*,tol:float=1e-12)->SparsePauliOp:r"""Jordan-Wigner transformation. Transform a fermion operator to a qubit operator using the Jordan-Wigner transformation. The Jordan-Wigner transformation maps fermionic annihilation operators to qubits as follows: .. math:: a_p \mapsto \frac12 (X_p + iY_p)Z_1 \cdots Z_{p-1} In the transformed operator, the first ``norb`` qubits represent spin-up (alpha) orbitals, and the latter ``norb`` qubits represent spin-down (beta) orbitals. As a result of this convention, the qubit index that an orbital is mapped to depends on the total number of spatial orbitals. By default, the total number of spatial orbitals is automatically determined by the largest-index orbital present in the operator, but you can manually specify the number using the ``norb`` argument. Args: op: The fermion operator to transform. norb: The total number of spatial orbitals. If not specified, it is determined by the largest-index orbital present in the operator. tol: Terms with coefficients whose real and imaginary parts are smaller than this value will be discarded. Returns: The qubit operator as a Qiskit SparsePauliOp. Raises: ValueError: Number of spatial orbitals was negative. ValueError: Number of spatial orbitals was fewer than the number detected in the operator. """ifnorbandnorb<0:raiseValueError(f"Number of spatial orbitals must be non-negative. Got {norb}.")ifnotop:returnSparsePauliOp.from_sparse_list([("",[],0.0)],num_qubits=2*(norbor0))norb_in_op=1+max(orbforterminopfor_,_,orbinterm)ifnorbisNone:norb=norb_in_opifnorb<norb_in_op:raiseValueError("Number of spatial orbitals specified is fewer than the number detected in "f"the operator. The operator has {norb_in_op} spatial orbitals, but "f"only {norb} were specified.")sparse_list,num_qubits=_lib.jordan_wigner_qiskit(op,norb,tol)# computed in Rust (src/jordan_wigner.rs)returnSparsePauliOp.from_sparse_list(sparse_list,num_qubits=num_qubits)