TransferVertexOperator
class TransferVertexOperator(coeffs, left_indices, right_indices, boundaries)
Bases : object
Un opérateur de transfert de sommet.
Définition
Cet opérateur est défini à partir des opérateurs de transfert de sommets ( , ) :
où est un opérateur de bord de EdgeVertexOperator et où ces termes individuels satisfont les relations de commutation mixtes fermioniques-bosoniques suivantes pour : [1]
Voici comment on peut représenter visuellement un exemple simple :

On peut prendre quelques libertés avec la notation et définir , qui reflète le fonctionnement de la structure de données interne de cet opérateur. La définition de l'opérateur dans son ensemble est donc la suivante :
où désigne l'indexation des termes d'opérateurs concernés et est le coefficient (complexe) constituant la combinaison linéaire des produits. Les indices et peuvent prendre n'importe quelle valeur comprise entre 0 et le nombre de modes fermioniques sur lesquels agit l'opérateur, moins 1.
Nous appellerons « opérateurs de transfert généralisés » les .
Implémentation
Cette classe stocke les termes et les coefficients dans plusieurs vecteurs creux, à l'instar du format « compressed sparse row » couramment utilisé pour les matrices creuses. Plus précisément, un opérateur contient 4 tableaux :
Chronique « 1 » | Chronique « 2 » |
|---|---|
coeffs | Un vecteur de coefficients complexes composé de deux nombres à virgule flottante de 64 bits. |
left_indices | Un vecteur d'entiers de 32 bits contenant les indices des modes fermioniques de gauche (voir « » ci-dessus). |
right_indices | Un vecteur d'entiers de 32 bits contenant les indices des modes fermioniques de droite (voir ci-dessus). |
boundaries | Un vecteur d'entiers indiquant les limites dans actions et modes. |
Les modes fermioniques indexés par left_indices et right_indices sont considérés comme dépourvus de spin.
Vous pouvez accéder à des copies en lecture seule de ces tableaux internes via leurs méthodes respectives : get_coeffs(), get_left_indices(), get_right_indices(), et get_boundaries().
Cette structure de données permet de créer et de manipuler des opérateurs de manière très efficace. Cela implique toutefois qu'un opérateur puisse contenir à tout moment des termes en double. Ces problèmes doivent être résolus manuellement à l'aide de simplify().
Construction
Il est possible de créer un opérateur directement en fournissant les tableaux décrits ci-dessus :
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> coeffs = [1.0, 2.0, -3.0, 4.0j, -0.5j]
>>> left_indices = [0, 3, 0, 2, 3, 0]
>>> right_indices = [1, 4, 1, 2, 3, 1]
>>> boundaries = [0, 0, 1, 2, 4, 6]
>>> op = TransferVertexOperator(coeffs, left_indices, right_indices, boundaries)
>>> print(format(op))
1.000000e0 +0.000000e0j * ()
2.000000e0 +0.000000e0j * (T(0,1))
0.000000e0 +4.000000e0j * (T(0,1) V(2))
-0.000000e0-5.000000e-1j * (V(3) T(0,1))
-3.000000e0 +0.000000e0j * (T(3,4))
Pour plus de commodité, il est possible de créer un opérateur à partir d'un dictionnaire de type « Python » comme suit :
>>> op = TransferVertexOperator.from_dict(
... {
... (): 1.0,
... ((0, 1),): 2.0,
... ((3, 4),): -3.0,
... ((0, 1), (2, 2)): 4.0j,
... ((3, 3), (0, 1)): -0.5j,
... }
... )
>>> print(format(op))
1.000000e0 +0.000000e0j * ()
2.000000e0 +0.000000e0j * (T(0,1))
0.000000e0 +4.000000e0j * (T(0,1) V(2))
-0.000000e0-5.000000e-1j * (V(3) T(0,1))
-3.000000e0 +0.000000e0j * (T(3,4))
De plus, les méthodes de construction et d'aide rapide suivantes sont disponibles :
Chronique « 1 » | Chronique « 2 » |
|---|---|
zero() | Construit l'opérateur d'identité additive. |
one() | Construit l'opérateur d'identité multiplicative. |
from_terms(conditions) | Crée un nouvel opérateur à partir d'un itérateur de termes (voir aussi iter_terms()). |
from_terms_with_groups(conditions) | Crée un nouvel opérateur à partir d'un itérateur de termes comportant des groupes (voir aussi iter_terms_with_groups()). |
Formatage
Dans les exemples ci-dessus, les opérateurs créés ont été affichés à l'aide de la sortie de format(), ce qui permet d'obtenir une représentation lisible par l'utilisateur de l'opérateur.
>>> print(format(op))
1.000000e0 +0.000000e0j * ()
2.000000e0 +0.000000e0j * (T(0,1))
0.000000e0 +4.000000e0j * (T(0,1) V(2))
-0.000000e0-5.000000e-1j * (V(3) T(0,1))
-3.000000e0 +0.000000e0j * (T(3,4))
L'ordre d'impression de format(op) est explicitement trié avant l'impression. Par conséquent, cela ne reflète pas l'ordre des termes à l'intérieur de l'opérateur.
La fonction repr() permet d'obtenir une forme alternative, qui donne lieu à une représentation interprétable par Python. En d'autres termes, cette sortie peut facilement être copiée-collée dans un shell Python :
>>> print(repr(op))
TransferVertexOperator.from_dict({...})
Enfin, pour les grands opérateurs, ces deux sorties peuvent s’avérer très longues et peu souhaitables. On peut alors obtenir, grâce à cette fonction str() , un formulaire très simple contenant un minimum d'informations :
>>> print(str(op))
<TransferVertexOperator with 5 terms>
Itération
La structure de données sous-jacente étant implémentée en Rust et présentant une organisation complexe, il n'est pas possible d'itérer directement dessus :
>>> list(iter(op))
Traceback (most recent call last):
...
TypeError: 'qiskit_fermions.operators.transfer_vertex_operator.TransferVertexOperator' object is not iterable
Cette classe fournit plutôt des itérateurs personnalisés pour répondre à ce besoin :
>>> list(sorted(op.iter_terms()))
[([], (1+0j)), ([(0, 1)], (2+0j)), ([(0, 1), (2, 2)], 4j), ([(3, 3), (0, 1)], (-0-0.5j)), ([(3, 4)], (-3+0j))]
Pour plus de détails sur la mise en œuvre.
Le tableau ci-dessous répertorie tous les itérateurs disponibles :
Chronique « 1 » | Chronique « 2 » |
|---|---|
iter_terms() | Un itérateur parcourant les termes de l'opérateur. |
iter_terms_with_groups() | Un itérateur parcourant les termes de l'opérateur avec leur indice de groupe associé. |
Arithmétique
Les opérations arithmétiques suivantes sont prises en charge :
Addition/Soustraction
>>> op = TransferVertexOperator.one()
>>> (op + op).simplify()
TransferVertexOperator.from_dict({(): 2+0j})
>>> (op - op).simplify()
TransferVertexOperator.from_dict({})
>>> op += op
>>> op.simplify()
TransferVertexOperator.from_dict({(): 2+0j})
>>> op -= op
>>> op.simplify()
TransferVertexOperator.from_dict({})
Multiplication et division scalaires
>>> op = TransferVertexOperator.one()
>>> (2 * op).simplify()
TransferVertexOperator.from_dict({(): 2+0j})
>>> (op / 2).simplify()
TransferVertexOperator.from_dict({(): 0.5+0j})
>>> op *= 2
>>> op.simplify()
TransferVertexOperator.from_dict({(): 2+0j})
>>> op /= 2
>>> op.simplify()
TransferVertexOperator.from_dict({(): 1+0j})
Composition de l'opérateur
La composition des opérateurs correspond à la multiplication à gauche : c = a & b correspond à . En d'autres termes, la composition de deux opérateurs renvoie un opérateur résultant qui effectue « d'abord a puis ». b
>>> op1 = TransferVertexOperator.from_dict({(): 2.0, ((0, 1),): 3.0})
>>> op2 = TransferVertexOperator.from_dict({(): 1.5, ((2, 2),): 4.0})
>>> comp = (op1 & op2).simplify()
>>> print(format(comp))
3.000000e0 +0.000000e0j * ()
4.500000e0 +0.000000e0j * (T(0,1))
8.000000e0 +0.000000e0j * (V(2))
1.200000e1 +0.000000e0j * (V(2) T(0,1))
>>> op2 &= op1
>>> print(format(op2.simplify()))
3.000000e0 +0.000000e0j * ()
4.500000e0 +0.000000e0j * (T(0,1))
1.200000e1 +0.000000e0j * (T(0,1) V(2))
8.000000e0 +0.000000e0j * (V(2))
>>> squared = (op1 ** 2).simplify()
>>> print(format(squared))
4.000000e0 +0.000000e0j * ()
1.200000e1 +0.000000e0j * (T(0,1))
9.000000e0 +0.000000e0j * (T(0,1) T(0,1))
Pour plus de commodité, la multiplication par la droite est implémentée par c = a @ b (ce qui donne ).
>>> (op1 @ op2).equiv(op2 & op1)
True
Autres opérations
Outre les méthodes « magiques » correspondant aux opérations arithmétiques décrites ci-dessus, les méthodes suivantes sont disponibles :
Chronique « 1 » | Chronique « 2 » |
|---|---|
adjoint() | Renvoie le conjugué hermitien (ou adjoint) de cet opérateur. |
ichop( [atol] ) | Supprime les termes dont la valeur absolue du coefficient est inférieure au seuil indiqué. |
simplify( [atol] ) | Renvoie un opérateur équivalent mais simplifié. |
normal_ordered( [réduire] ) | Renvoie un opérateur équivalent dont les termes sont classés selon l'ordre habituel. |
relabel_modes(permutation) | Renvoie un nouvel opérateur dont les modes ont été renommés. |
Propriétés
Enfin, il existe différentes méthodes permettant de vérifier certaines propriétés d'un opérateur :
Chronique « 1 » | Chronique « 2 » |
|---|---|
is_hermitian( [atol] ) | Indique si cet opérateur est hermitien. |
[ 1 ]
Gandon et al., arXiv:2512.11418.
Attributs
groups
Un vecteur facultatif d'indices de groupe pour chaque terme.
Pour plus d'informations, consultez le module grouping .
Méthodes
adjoint
adjoint()
Renvoie le conjugué hermitien (ou adjoint) de cet opérateur.
Chaque trimestre, deux choses se produisent :
- les coefficients sont des nombres complexes conjugués
- l'ordre des générateurs au sein de chaque terme est inversé
Cette inversion est nécessaire car . Bien que les générateurs de sommet et de transfert pris individuellement soient hermitiens, ils anticommutent lorsqu’ils partagent un indice (voir la définition ci-dessus ); par conséquent, le produit inversé n’est pas égal au produit d’origine et l’ordre ne peut pas être simplement ignoré.
Notez que cela ne rend pas pour autant l'opérateur auto-adjoint en général : un opérateur à coefficients complexes diffère de son adjoint (comme l'illustre le doctest ci-dessous).
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): -1.0j, ((0, 0), (0, 1)): 1.0})
>>> adj = op.adjoint()
>>> print(format(adj))
-0.000000e0 +1.000000e0j * ()
1.000000e0 -0.000000e0j * (T(0,1) V(0))
equiv
equiv(other, atol=1e-08)
Vérifie si cet opérateur est équivalent à un autre opérateur.
Dans ce contexte, l'équivalence désigne une égalité approximative, dans les limites de la tolérance absolue spécifiée. Plus précisément, cette méthode renvoie True, lorsque toutes les valeurs absolues des coefficients de la différence other - self sont inférieures au seuil spécifié atol.
C'est la comparaison mathématique que l'on cherche presque toujours. Il diffère de l'opérateur == , qui vérifie l'égalité exacte des termes stockés (leurs coefficients, leurs indices et les limites internes des termes) sans aucune tolérance ni simplification. Deux opérateurs mathématiquement égaux peuvent donc donner un résultat différent lors d'une comparaison sous == s'ils sont stockés différemment – par exemple, un non simplifié par a + a rapport à un 2 * a, ou des termes classés dans un ordre différent. Utilisez equiv pour comparer des opérateurs dans les limites de la tolérance numérique.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 1e-7})
>>> zero = TransferVertexOperator.zero()
>>> op.equiv(zero)
False
>>> op.equiv(zero, 1e-6)
True
>>> op.equiv(zero, 1e-9)
False
Paramètres
- autre – l'autre opérateur à comparer.
- atol – la tolérance absolue pour la comparaison. Cette valeur est définie par défaut sur
1e-8.
from_dict
classmethod from_dict(data)
Crée un nouvel opérateur à partir d'un dictionnaire.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict(
... {
... (): 1.0-1.0j,
... ((0, 0),): 2.0,
... ((0, 1),): 2.0j,
... }
... )
>>> print(format(op))
1.000000e0 -1.000000e0j * ()
2.000000e0 +0.000000e0j * (V(0))
0.000000e0 +2.000000e0j * (T(0,1))
Paramètres
données – un dictionnaire associant des tuples de termes à des coefficients complexes. Chaque clé est un tuple de paires (int, int) indiquant les indices de l'opérateur de transfert généralisé, (si , cela correspond à l'opérateur de sommet ).
Retours
Un nouvel opérateur.
from_terms
classmethod from_terms(terms)
Crée un nouvel opérateur à partir d'un itérateur de termes (voir aussi iter_terms()).
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 2.0, ((0, 0),): 1.0, ((0, 1),): -1.0j})
>>> op.equiv(TransferVertexOperator.from_terms(op.iter_terms()))
True
Paramètres
termes – un itérateur de termes tel que généré par iter_terms().
Retours
Un nouvel opérateur.
from_terms_with_groups
classmethod from_terms_with_groups(terms)
Crée un nouvel opérateur à partir d'un itérateur de termes comportant des groupes (voir aussi iter_terms_with_groups()).
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator([2.0, 1.0, -1.0j], [0, 0], [0, 1], [0, 0, 1, 2])
>>> op.groups = [0, 1, 1]
>>> reconstructed = TransferVertexOperator.from_terms_with_groups(op.iter_terms_with_groups())
>>> op.equiv(reconstructed) and op.groups == reconstructed.groups
True
Paramètres
termes – un itérateur de termes tel que généré par iter_terms_with_groups().
Retours
Un nouvel opérateur.
get_boundaries
get_boundaries()
Renvoie une liste en lecture seule contenant les indices indiquant les limites entre les termes de l'opérateur.
Cette méthode renvoie une copie des données internes.
Vous trouverez ici une explication de la structure interne des données.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.one()
>>> op += TransferVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_boundaries()
[0, 0, 1]
Retours
Liste des limites des conditions générales de l'opérateur.
get_coeffs
get_coeffs()
Renvoie une liste en lecture seule contenant les coefficients de l'opérateur.
Cette méthode renvoie une copie des données internes.
Vous trouverez ici une explication de la structure interne des données.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.one()
>>> op += -1j * TransferVertexOperator.one()
>>> op.get_coeffs()
[(1+0j), -1j]
Retours
Liste des coefficients de l'opérateur.
get_left_indices
get_left_indices()
Renvoie une liste en lecture seule contenant les indices de gauche de tous les termes de l'opérateur de transfert généralisé.
Cette méthode renvoie une copie des données internes.
Vous trouverez ici une explication de la structure interne des données.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({((0, 0),): 1.0})
>>> op += TransferVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_left_indices()
[0, 0]
Retours
Une liste des indices de gauche de tous les termes de l'opérateur de transfert généralisé.
get_right_indices
get_right_indices()
Renvoie une liste en lecture seule contenant les indices de droite de tous les termes de l'opérateur de transfert généralisé.
Cette méthode renvoie une copie des données internes.
Vous trouverez ici une explication de la structure interne des données.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({((0, 0),): 1.0})
>>> op += TransferVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_right_indices()
[0, 1]
Retours
Une liste des indices droits de tous les termes de l'opérateur de transfert généralisé.
get_support
get_support()
Renvoie l'ensemble des indices de mode sur lesquels cet opérateur agit.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict(
... {
... ((0, 1), (3, 4)): 1,
... ((7, 7),): 1,
... }
... )
>>> assert op.get_support() == {0, 1, 3, 4, 7}
Retours
L'ensemble des indices de mode sur lesquels agit cet opérateur.
has_groups
has_groups()
Indique si cet opérateur prend en compte les indices de groupe.
Cela revient à vérifier (mais coûte moins cher que) op.groups is not None, car cela ne nécessite pas de copier les indices de groupe hors de l'opérateur pour les inspecter.
Cela renvoie une valeur même True lorsque groups est une liste vide, ce qui correspond à l'état d'un opérateur groupé ne contenant aucun terme.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator(
... [1.0, 2.0, -1.0],
... [0, 1, 2, 3],
... [1, 0, 3, 2],
... [0, 1, 3, 4],
... )
>>> op.has_groups()
False
>>> op.groups = [0, 1, 0]
>>> op.has_groups()
True
Retours
Vérifier si cet opérateur groups est activé.
ichop
ichop(atol=1e-08)
Supprime les termes dont la valeur absolue du coefficient est inférieure au seuil indiqué.
Cette méthode modifie l'opérateur in situ et renvoie None.
Cette méthode tronque les coefficients de manière « gloutonne »! Si l'opérateur sur lequel porte l'action peut comporter des coefficients distincts pour des termes identiques, pensez plutôt simplify() à utiliser!
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 1e-4, ((1, 0),): 1e-6, ((0, 1),): 1e-10})
>>> print(format(op))
1.000000e-4 +0.000000e0j * ()
1.000000e-10 +0.000000e0j * (T(0,1))
1.000000e-6 +0.000000e0j * (T(1,0))
>>> op.ichop()
>>> print(format(op))
1.000000e-4 +0.000000e0j * ()
1.000000e-6 +0.000000e0j * (T(1,0))
>>> op.ichop(1e-5)
>>> print(format(op))
1.000000e-4 +0.000000e0j * ()
Paramètres
atol – la tolérance absolue pour le seuil de coupure. Cette valeur est définie par défaut sur 1e-8.
is_hermitian
is_hermitian(atol=1e-08)
Indique si cet opérateur est hermitien.
Cette vérification est effectuée à partir equiv() de la différence normal_ordered() entièrement réduite entre et self ses et adjoint() zero().
Cette vérification est prudente : elle peut renvoyer « non » pour False un opérateur qui est en réalité hermitien. Un résultat True est toujours fiable.
normal_ordered() Chaque paire de générateurs adjacents se réduit en un terme plus court, mais ce n’est pas le cas de deux opérateurs de transfert partageant un même mode : comme expliqué ici, ne peut être réécrit qu’en un autre produit de longueur deux. Étant donné qu'aucune des deux formes n'est plus canonique que l'autre, ces produits sont laissés tels quels, et un terme qui ne s'annulerait avec son adjoint qu'après réécriture n'est pas considéré comme nul. EdgeVertexOperator ne présente pas un tel écart, car dans ce cas, le produit analogue se réduit à un seul opérateur de bord.
Paramètres
atol – Précision numérique jusqu'à laquelle les coefficients sont considérés comme égaux. Cette valeur est définie par défaut sur 1e-8.
Retours
Si cet opérateur est hermitien.
iter_terms
iter_terms()
Un itérateur parcourant les termes de l'opérateur.
La modification des éléments de l'itération n'a aucune incidence sur les données sous-jacentes de l'opérateur.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 2.0, ((0, 0),): 1.0, ((0, 1),): -1.0j})
>>> list(sorted(op.iter_terms()))
[([], (2+0j)), ([(0, 0)], (1+0j)), ([(0, 1)], (-0-1j))]
iter_terms_with_groups
iter_terms_with_groups()
Un itérateur parcourant les termes de l'opérateur avec leur indice de groupe associé.
La modification des éléments de l'itération n'a aucune incidence sur les données sous-jacentes de l'opérateur.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator([2.0, 1.0, -1.0j], [0, 0], [0, 1], [0, 0, 1, 2])
>>> op.groups = [0, 1, 1]
>>> list(op.iter_terms_with_groups())
[([], (2+0j), 0), ([(0, 0)], (1+0j), 1), ([(0, 1)], (-0-1j), 1)]
normal_ordered
normal_ordered(reduce=True)
Renvoie un opérateur équivalent dont les termes sont classés selon l'ordre habituel.
L'ordre normal d'un terme d'opérateur est défini de telle sorte que tous les opérateurs de sommet apparaissent avant tous les opérateurs de transfert. Au sein de chaque groupe, les modes sur lesquels porte l'action sont classés par ordre lexicographique.
Lorsqu'on réorganise un terme, il faut tenir compte des relations mixtes de commutation et d'anticommutation. Cliquez ici pour consulter les définitions détaillées.
Il y a moins de contractions disponibles ici que pour EdgeVertexOperator. Deux opérateurs de bord partageant un même mode fusionnent en un seul, mais ce n'est pas le cas du produit de transfert analogue : en écrivant , l'annulation du Majorana partagé laisse toujours une paire (paire, impaire) issue de deux modes différents, ce qui ne constitue pas un générateur unique. Seuls V(j) V(j), T(j,k) T(j,k) et sont concernés par le contrat T(j,k) T(k,j) .
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({((0, 1), (1, 0), (1, 2), (0, 0), (2, 2)): 1})
>>> print(format(op.normal_ordered(reduce=False).simplify()))
-1.000000e0 -0.000000e0j * (V(0) V(2) T(0,1) T(1,0) T(1,2))
>>> print(format(op.normal_ordered().simplify()))
2.500000e-1 +0.000000e0j * (V(1) V(2) T(1,2))
Paramètres
réduire – déterminer s’il faut regrouper les générateurs adjacents pour former un scalaire ou une paire d’opérateurs de sommet. Voir l'exemple ci-dessus. Cette valeur est définie par défaut sur True.
Retours
Un opérateur équivalent mais à ordre normal.
num_groups
num_groups()
Renvoie le nombre de groupes.
Si vaut groups None, cette fonction renvoie également None. Sinon, elle renvoie le nombre de groupes, défini comme étant l'indice du plus grand groupe rencontré plus 1 (ce qui peut donc servir d'indice pour le groupe suivant).
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator(
... [1.0, 2.0, -1.0],
... [0, 1, 2, 3],
... [1, 0, 3, 2],
... [0, 1, 3, 4],
... )
>>> op.groups = [0, 1, 0]
>>> op.num_groups()
2
Retours
L'indice du plus grand groupe affiche une groups hausse de 1.
one
classmethod one()
Construit l'opérateur d'identité multiplicative.
La composition de l'opérateur ainsi construit avec un autre opérateur n'a aucun effet.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 2.0})
>>> one = TransferVertexOperator.one()
>>> op & one == op
True
relabel_modes
relabel_modes(permutation)
Renvoie un nouvel opérateur dont les modes ont été renommés.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({
... ((0, 1), (2, 3)): 1,
... ((1, 2), (3, 0)): 1,
... })
>>> permutation = [4, 2, 5, 3]
>>> relabeled = op.relabel_modes(permutation)
>>> print(format(relabeled))
1.000000e0 +0.000000e0j * (T(2,5) T(3,4))
1.000000e0 +0.000000e0j * (T(4,2) T(5,3))
Paramètres
permutation – la liste des permutations d'index. Le mode est i renommé en permutation[i], de sorte que la liste ne doit contenir aucune entrée en double et doit être suffisamment longue pour répertorier tous les modes sur lesquels l'opérateur agit (sa longueur doit être supérieure au plus grand index de mode de l'opérateur).
Retours
Un nouvel opérateur dont les modes ont été renommés.
Augmentations
ValueError – si contient permutation des entrées en double, ou s'il est trop court pour redéfinir un mode sur lequel l'opérateur agit.
simplify
simplify(atol=1e-08)
Renvoie un opérateur équivalent mais simplifié.
Le processus de simplification commence par additionner tous les coefficients appartenant à des termes identiques, puis ne conserve que ceux dont le coefficient total dépasse la tolérance spécifiée (exactement comme ichop()).
Lorsqu'un opérateur a fait l'objet d'une manipulation arithmétique ou a été construit d'une manière qui ne garantit pas l'unicité des termes, il convient d'appeler cette méthode avant d'appliquer toute méthode filtrant les coefficients numériquement faibles, afin d'éviter toute perte d'information. Consultez l'exemple ci-dessous, qui montre comment le système peut ichop() tronquer des termes dont la somme donne une valeur de coefficient totale qui ne devrait pas être tronquée :
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> coeffs = [1e-5] * int(1e5)
>>> boundaries = [0] + [0] * int(1e5)
>>> op = TransferVertexOperator(coeffs, [], [], boundaries)
>>> canon = op.simplify(1e-4)
>>> assert canon.equiv(op.one(), 1e-6)
>>> op.ichop(1e-4)
>>> assert op.equiv(op.zero(), 1e-6)
Paramètres
atol – la tolérance absolue pour le seuil de coupure. Cette valeur est définie par défaut sur 1e-8.
Retours
Un opérateur équivalent mais simplifié.
split_out_groups
split_out_groups(group_indices=None)
Divise cet opérateur en une liste facultative de nouveaux opérateurs en fonction de groups.
Si vaut groups None, cette fonction renvoie également None. Sinon, si group_indices est None (valeur par défaut), elle renvoie une liste contenant un nouvel opérateur pour chaque indice de groupe dans groups, classés par ordre d'indice. Si group_indices est fourni, seuls les indices demandés sont générés, dans l'ordre indiqué : cela permet d'éviter le coût lié à la construction d'opérateurs pour des groupes qui ne seront jamais utilisés, ce qui est particulièrement avantageux lorsqu'on n'a besoin que d'un petit nombre de groupes parmi un ensemble beaucoup plus vaste, par exemple lors du sous-échantillonnage de groupes pour une formule de produit aléatoire. Un index en double dans group_indices est renvoyé une fois par occurrence.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator(
... [1.0, 2.0, -1.0],
... [0, 1, 2, 3],
... [1, 0, 3, 2],
... [0, 1, 3, 4],
... )
>>> print(op.split_out_groups())
None
>>> op.groups = [0, 1, 0]
>>> groups = op.split_out_groups()
>>> for g in groups:
... print(list(sorted(g.iter_terms())))
[([(0, 1)], (1+0j)), ([(3, 2)], (-1+0j))]
[([(1, 0), (2, 3)], (2+0j))]
>>> groups = op.split_out_groups(group_indices=[1])
>>> for g in groups:
... print(list(sorted(g.iter_terms())))
[([(1, 0), (2, 3)], (2+0j))]
Paramètres
group_indices – les indices de groupe pour lesquels créer des opérateurs, dans l'ordre de sortie souhaité. En l'absence de spécification, tous les groupes sont créés, dans l'ordre de leur index.
Retours
Un vecteur facultatif contenant un nouvel opérateur pour chaque index de groupe demandé.
zero
classmethod zero()
Construit l'opérateur d'identité additive.
L'ajout de l'opérateur ainsi créé à un autre opérateur n'a aucun effet.
>>> from qiskit_fermions.operators import TransferVertexOperator
>>> op = TransferVertexOperator.from_dict({(): 2.0})
>>> zero = TransferVertexOperator.zero()
>>> op + zero == op
True
Méthodes protocolaires
_anti_commutator_
static _anti_commutator_(op_a, op_b)
_commutator_
static _commutator_(op_a, op_b)
_double_commutator_
static _double_commutator_(op_a, op_b, op_c, sign)
_fermion_operator_
_fermion_operator_()
Convertit cet opérateur en un FermionOperator.
Cela implémente le protocole SupportsFermionOperator en déléguant à transfer_vertex_to_fermion().
_majorana_operator_
_majorana_operator_()
Convertit cet opérateur en un MajoranaOperator.
Cela implémente le protocole SupportsMajoranaOperator en déléguant à transfer_vertex_to_majorana().