Skip to main content
IBM Quantum Platform

EdgeVertexOperator

class EdgeVertexOperator(coeffs, left_indices, right_indices, boundaries)

Basi: object

Un operatore bordo-vertice.


Definizione

Questo operatore è definito in termini degli operatori " EjkE_{jk} " e " VjV_j ":

Vj=−iγ2j−1γ2j=−(ajaj−ajaj†+aj†aj−aj†aj†)=1−2aj†aj ,Ejk=−iγ2j−1γ2k−1=−i(ajak+ajak†+aj†ak+aj†ak†)=−Ekj\begin{align} V_j &= -i \gamma_{2j-1} \gamma_{2j} = -(a_j a_j - a_j a^\dagger_j + a^\dagger_j a_j - a^\dagger_j a^\dagger_j) = 1 - 2 a^\dagger_j a_j \, , \nonumber \\ E_{jk} &= -i \gamma_{2j-1} \gamma_{2k-1} = -i (a_j a_k + a_j a^\dagger_k + a^\dagger_j a_k + a^\dagger_j a^\dagger_k) = -E_{kj} \nonumber \end{align}

che soddisfano le seguenti relazioni di commutazione miste fermionico-bosoniche per l’ j≠k≠l≠mj \neq k \neq l \neq m : [1]

{Ejk,Vk}=0{Ejk,Ekl}=0[Vk,Vl]=0[Ejk,Vl]=0[Ejk,Elm]=0 .\begin{align} \left\{ E_{jk}, V_k \right\} &= 0 \nonumber \\ \left\{ E_{jk}, E_{kl} \right\} &= 0 \nonumber \\ \left[ V_k, V_l \right] &= 0 \nonumber \\ \left[ E_{jk}, V_l \right] &= 0 \nonumber \\ \left[ E_{jk}, E_{lm} \right] &= 0 \nonumber \, . \end{align}

In sintesi, gli operatori di spigolo e di vertice commutano, a meno che non condividano esattamente un indice, nel qual caso anticommutano.

Nota

Le relazioni sopra riportate sono valide per j≠k≠l≠mj \neq k \neq l \neq m, pertanto non tengono conto di due operatori di bordo che coprono la stessa coppia di modi. Quelli che commutano: poiché Ekj=−EjkE_{kj} = -E_{jk}, tale coppia è allineata e ogni operatore commuta con se stesso. Ecco perché la condizione è “esattamente un” indice condiviso anziché “almeno uno”.

Un semplice esempio può essere rappresentato visivamente in questo modo:

Una rappresentazione visiva di un operatore bordo-vertice.

Possiamo prendere un po’ di libertà con la notazione e definire l’ Vj=EjjV_j = E_{jj}, che riflette il funzionamento della struttura interna di questo operatore. Ne consegue che la definizione dell'operatore nel suo complesso è la seguente:

EdgeVertexOperator=∑ici⨂lrElr ,\text{\texttt{EdgeVertexOperator}} = \sum_i c_i \bigotimes_{lr} E_{lr} \, ,

dove lrlr indica l'indice dei termini dell'operatore coinvolti e cic_i è il coefficiente (complesso) che costituisce la combinazione lineare dei prodotti. Gli indici ll e rr possono assumere qualsiasi valore compreso tra 0 e il numero di modi fermionici su cui agisce l'operatore meno 1.

Ci riferiremo agli operatori di tipo “ ElrE_{lr} ” come operatori di bordo generalizzati.


Implementazione

Questa classe memorizza i termini e i coefficienti in più vettori sparsi, analogamente al formato “compressed sparse row” comunemente utilizzato per le matrici sparse. Più precisamente, un singolo operatore contiene 4 array:

Rubrica 1
Rubrica 2
coeffsUn vettore di coefficienti complessi costituito da due numeri in virgola mobile a 64 bit.
left_indicesUn vettore di interi a 32 bit che memorizza gli indici delle modalità fermioniche di sinistra (vedi ll ).
right_indicesUn vettore di interi a 32 bit che memorizza gli indici delle modalità fermioniche di destra (vedi rr ).
boundariesUn vettore di numeri interi che indica i limiti in e actions modes.

Le modalità fermioniche indicizzate da left_indices e right_indices sono considerate prive di spin.

Nota

È possibile accedere a copie in sola lettura di questi array interni tramite i rispettivi metodi: get_coeffs(), get_left_indices(), get_right_indices(), e get_boundaries().

Questa struttura dati consente di creare e manipolare gli operatori in modo molto efficiente. Tuttavia, ciò implica che in qualsiasi momento un operatore possa contenere termini duplicati. Questi devono essere risolti manualmente utilizzando simplify().

Costruzioni

È possibile creare un operatore direttamente fornendo gli array descritti sopra:

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> 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 = EdgeVertexOperator(coeffs, left_indices, right_indices, boundaries)
>>> print(format(op))
  1.000000e0 +0.000000e0j * ()
  2.000000e0 +0.000000e0j * (E(0,1))
  0.000000e0 +4.000000e0j * (E(0,1) V(2))
 -0.000000e0-5.000000e-1j * (V(3) E(0,1))
 -3.000000e0 +0.000000e0j * (E(3,4))

Per comodità, è possibile creare un operatore a partire da un dizionario di tipo Python nel modo seguente:

>>> op = EdgeVertexOperator.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 * (E(0,1))
  0.000000e0 +4.000000e0j * (E(0,1) V(2))
 -0.000000e0-5.000000e-1j * (V(3) E(0,1))
 -3.000000e0 +0.000000e0j * (E(3,4))

Inoltre, sono disponibili i seguenti metodi di costruzione e di aiuto rapido:

Rubrica 1
Rubrica 2
zero()Costruisce l'operatore di identità additiva.
one()Crea l'operatore di identità moltiplicativa.
from_terms(termini)Crea un nuovo operatore a partire da un iteratore di termini (vedi anche iter_terms()).
from_terms_with_groups(termini)Crea un nuovo operatore a partire da un iteratore di termini con gruppi (vedi anche iter_terms_with_groups()).

Formattazione

Negli esempi precedenti, gli operatori creati sono stati visualizzati utilizzando l'output di format(), il che permette di ottenere una rappresentazione dell'operatore leggibile dall'utente.

>>> print(format(op))
  1.000000e0 +0.000000e0j * ()
  2.000000e0 +0.000000e0j * (E(0,1))
  0.000000e0 +4.000000e0j * (E(0,1) V(2))
 -0.000000e0-5.000000e-1j * (V(3) E(0,1))
 -3.000000e0 +0.000000e0j * (E(3,4))
Nota

L'ordine di stampa di format(op) viene ordinato in modo esplicito prima della stampa. Pertanto, non riflette l'ordine dei termini all'interno dell'operatore.

È possibile ottenere una forma alternativa dalla funzione repr() , che fornisce una rappresentazione interpretabile in Python. In altre parole, questo output può essere facilmente copiato e incollato nella shell di Python :

>>> print(repr(op))
EdgeVertexOperator.from_dict({...})

Infine, per gli operatori di grandi dimensioni, entrambi questi output potrebbero risultare molto lunghi e indesiderabili. A questo punto, dalla funzione str() è possibile ottenere un modulo molto semplice con informazioni minime:

>>> print(str(op))
<EdgeVertexOperator with 5 terms>

Iterazione

Poiché la struttura dati sottostante è implementata in Rust e presenta un layout non banale, non è possibile iterarla direttamente:

>>> list(iter(op))
Traceback (most recent call last):
  ...
TypeError: 'qiskit_fermions.operators.edge_vertex_operator.EdgeVertexOperator' object is not iterable

Questa classe fornisce invece degli iteratori personalizzati per soddisfare tale scopo:

>>> 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))]
Vedi anche

iter_terms()

Per ulteriori dettagli relativi all'implementazione.

La tabella seguente elenca tutti gli iteratori disponibili:

Rubrica 1
Rubrica 2
iter_terms()Un iteratore sui termini dell'operatore.
iter_terms_with_groups()Un iteratore sui termini dell'operatore con il relativo indice di gruppo.

Aritmetica

Sono supportate le seguenti operazioni aritmetiche:

Addizione/Sottrazione

>>> op = EdgeVertexOperator.one()
>>> (op + op).simplify()
EdgeVertexOperator.from_dict({(): 2+0j})
>>> (op - op).simplify()
EdgeVertexOperator.from_dict({})
>>> op += op
>>> op.simplify()
EdgeVertexOperator.from_dict({(): 2+0j})
>>> op -= op
>>> op.simplify()
EdgeVertexOperator.from_dict({})

Moltiplicazione e divisione scalare

>>> op = EdgeVertexOperator.one()
>>> (2 * op).simplify()
EdgeVertexOperator.from_dict({(): 2+0j})
>>> (op / 2).simplify()
EdgeVertexOperator.from_dict({(): 0.5+0j})
>>> op *= 2
>>> op.simplify()
EdgeVertexOperator.from_dict({(): 2+0j})
>>> op /= 2
>>> op.simplify()
EdgeVertexOperator.from_dict({(): 1+0j})

Composizione dell'operatore

Nota

La composizione degli operatori corrisponde alla moltiplicazione a sinistra: c = a & b corrisponde a C=BAC = B A. In altre parole, la composizione di due operatori restituisce un operatore risultante che esegue “prima a e poi ”. b

>>> op1 = EdgeVertexOperator.from_dict({(): 2.0, ((0, 1),): 3.0})
>>> op2 = EdgeVertexOperator.from_dict({(): 1.5, ((2, 2),): 4.0})
>>> comp = (op1 & op2).simplify()
>>> print(format(comp))
  3.000000e0 +0.000000e0j * ()
  4.500000e0 +0.000000e0j * (E(0,1))
  8.000000e0 +0.000000e0j * (V(2))
  1.200000e1 +0.000000e0j * (V(2) E(0,1))
>>> op2 &= op1
>>> print(format(op2.simplify()))
  3.000000e0 +0.000000e0j * ()
  4.500000e0 +0.000000e0j * (E(0,1))
  1.200000e1 +0.000000e0j * (E(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 * (E(0,1))
  9.000000e0 +0.000000e0j * (E(0,1) E(0,1))
Nota

Per comodità, la moltiplicazione a destra viene implementata tramite c = a @ b (il che porta a un risultato pari a C=ABC = A B ).

>>> (op1 @ op2).equiv(op2 & op1)
True

Altre operazioni

Oltre ai metodi magici corrispondenti alle operazioni aritmetiche descritte in precedenza, sono disponibili i seguenti metodi:

Rubrica 1
Rubrica 2
adjoint()Restituisce il coniugato ermitiano (o aggiunto) di questo operatore.
ichop( [atol] )Rimuove i termini il cui valore assoluto del coefficiente è inferiore alla soglia specificata.
simplify( [atol] )Restituisce un operatore equivalente ma semplificato.
normal_ordered( [in ordine crescente, ridurre] )Restituisce un operatore equivalente con termini ordinati normalmente.
relabel_modes(permutazione)Restituisce un nuovo operatore con le modalità rinominate.

Proprietà

Infine, esistono vari metodi per verificare determinate proprietà di un operatore:

Rubrica 1
Rubrica 2
is_hermitian( [atol] )Restituisce se questo operatore è ermitiano.

[ 1 ]

Gandon et al., arXiv:2512.11418.


Attributi

groups

Un vettore facoltativo di indici di gruppo per ciascun termine.

Per ulteriori informazioni, consultare il modulo grouping .


Metodi

adjoint

adjoint()

Restituisce il coniugato ermitiano (o aggiunto) di questo operatore.

A ogni termine accadono due cose:

  • i coefficienti sono coniugati complessi
  • l'ordine dei generatori all'interno di ciascun termine è invertito

L'inversione è necessaria perché (AB)†=B†A†(AB)^\dagger = B^\dagger A^\dagger. Sebbene i singoli generatori di vertici e spigoli siano ermitiani, essi anticommutano quando condividono un indice (vedi la definizione sopra ), quindi il prodotto invertito non è uguale a quello originale e l'ordine non può essere semplicemente omesso.

Si noti che ciò non rende l’operatore autoaggiunto in generale: un operatore con coefficienti complessi differisce dal suo aggiunto (come illustra il doctest riportato di seguito).

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({(): -1.0j, ((0, 0), (0, 1)): 1.0})
>>> adj = op.adjoint()
>>> print(format(adj))
 -0.000000e0 +1.000000e0j * ()
  1.000000e0 -0.000000e0j * (E(0,1) V(0))
equiv

equiv(other, atol=1e-08)

Verifica se questo operatore è equivalente a un altro operatore.

In questo contesto, per “equivalenza” si intende un’uguaglianza approssimativa entro i limiti della tolleranza assoluta specificata. Per essere più precisi, questo metodo restituisce True, quando tutti i valori assoluti dei coefficienti nella differenza other - self sono inferiori alla soglia specificata atol.

Nota

Questo è il confronto matematico che quasi sempre si desidera. Si differenzia dall'operatore == , che verifica l'uguaglianza esatta dei termini memorizzati (i loro coefficienti, indici e confini interni dei termini) senza tolleranza né semplificazione. Due operatori matematicamente uguali possono quindi risultare disuguali nel confronto == se sono memorizzati in modo diverso – ad esempio, un non semplificato a + a rispetto a 2 * a, oppure se i termini sono disposti in un ordine diverso. Utilizzare equiv per confrontare gli operatori entro i limiti della tolleranza numerica.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({(): 1e-7})
>>> zero = EdgeVertexOperator.zero()
>>> op.equiv(zero)
False
>>> op.equiv(zero, 1e-6)
True
>>> op.equiv(zero, 1e-9)
False

Parametri

  • altro – l’altro operatore con cui effettuare il confronto.
  • atol – la tolleranza assoluta per il confronto. Il valore predefinito è 1e-8.
from_dict

classmethod from_dict(data)

Crea un nuovo operatore a partire da un dizionario.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.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 * (E(0,1))

Parametri

dati – un dizionario che associa tuple di termini a coefficienti complessi. Ogni chiave è una tupla di coppie (int, int) che indicano gli indici dell’operatore di spigolo generalizzato, ElrE_{lr} (se l=rl = r, allora ciò corrisponde all’operatore di vertice VlV_l ).

Risultati

Un nuovo operatore.

from_terms

classmethod from_terms(terms)

Crea un nuovo operatore a partire da un iteratore di termini (vedi anche iter_terms()).

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({(): 2.0, ((0, 0),): 1.0, ((0, 1),): -1.0j})
>>> op.equiv(EdgeVertexOperator.from_terms(op.iter_terms()))
True

Parametri

termini – un iteratore dei termini generati da iter_terms().

Risultati

Un nuovo operatore.

from_terms_with_groups

classmethod from_terms_with_groups(terms)

Crea un nuovo operatore a partire da un iteratore di termini con gruppi (vedi anche iter_terms_with_groups()).

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator([2.0, 1.0, -1.0j], [0, 0], [0, 1], [0, 0, 1, 2])
>>> op.groups = [0, 1, 1]
>>> reconstructed = EdgeVertexOperator.from_terms_with_groups(op.iter_terms_with_groups())
>>> op.equiv(reconstructed) and op.groups == reconstructed.groups
True

Parametri

termini – un iteratore dei termini generati da iter_terms_with_groups().

Risultati

Un nuovo operatore.

get_boundaries

get_boundaries()

Restituisce un elenco in sola lettura degli indici che indicano i confini tra i termini dell'operatore.

Nota

Questo metodo restituisce una copia dei dati interni.

Vedi anche

La spiegazione della struttura interna dei dati è disponibile qui.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.one()
>>> op += EdgeVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_boundaries()
[0, 0, 1]

Risultati

Un elenco dei limiti previsti dalle condizioni dell’operatore.

get_coeffs

get_coeffs()

Restituisce un elenco in sola lettura dei coefficienti dell'operatore.

Nota

Questo metodo restituisce una copia dei dati interni.

Vedi anche

La spiegazione della struttura interna dei dati è disponibile qui.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.one()
>>> op += -1j * EdgeVertexOperator.one()
>>> op.get_coeffs()
[(1+0j), -1j]

Risultati

Un elenco dei coefficienti dell’operatore.

get_left_indices

get_left_indices()

Restituisce un elenco in sola lettura degli indici a sinistra di tutti i termini degli operatori di bordo generalizzati.

Nota

Questo metodo restituisce una copia dei dati interni.

Vedi anche

La spiegazione della struttura interna dei dati è disponibile qui.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({((0, 0),): 1.0})
>>> op += EdgeVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_left_indices()
[0, 0]

Risultati

Un elenco degli indici a sinistra di tutti i termini relativi agli operatori di bordo generalizzati.

get_right_indices

get_right_indices()

Restituisce un elenco in sola lettura degli indici a destra di tutti i termini degli operatori di bordo generalizzati.

Nota

Questo metodo restituisce una copia dei dati interni.

Vedi anche

La spiegazione della struttura interna dei dati è disponibile qui.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({((0, 0),): 1.0})
>>> op += EdgeVertexOperator.from_dict({((0, 1),): 1.0})
>>> op.get_right_indices()
[0, 1]

Risultati

Un elenco degli indici corretti di tutti i termini relativi agli operatori di bordo generalizzati.

get_support

get_support()

Restituisce l'insieme degli indici di modalità su cui agisce questo operatore.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict(
...     {
...         ((0, 1), (3, 4)): 1,
...         ((7, 7),): 1,
...     }
... )
>>> assert op.get_support() == {0, 1, 3, 4, 7}

Risultati

L'insieme degli indici di modalità su cui agisce questo operatore.

has_groups

has_groups()

Indica se questo operatore tiene traccia degli indici di gruppo.

Ciò equivale a (ma è più economico di) verificare op.groups is not None, poiché non copia gli indici dei gruppi dall’operatore per esaminarli.

Nota

Restituisce questo valore True anche quando groups è una lista vuota, ovvero lo stato di un operatore raggruppato che non contiene termini.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator(
...     [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

Risultati

Se groups è impostato su questo operatore.

ichop

ichop(atol=1e-08)

Rimuove i termini il cui valore assoluto del coefficiente è inferiore alla soglia specificata.

Questo metodo modifica l'operatore direttamente e restituisce None.

Attenzione

Questo metodo tronca i coefficienti in modo avido! Se l'operatore su cui si agisce può contenere coefficienti distinti per termini duplicati, valuta invece simplify() di chiamare!

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.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 * (E(0,1))
  1.000000e-6 +0.000000e0j * (E(1,0))
>>> op.ichop()
>>> print(format(op))
  1.000000e-4 +0.000000e0j * ()
  1.000000e-6 +0.000000e0j * (E(1,0))
>>> op.ichop(1e-5)
>>> print(format(op))
  1.000000e-4 +0.000000e0j * ()

Parametri

atol – la tolleranza assoluta per il valore di soglia. Il valore predefinito è 1e-8.

is_hermitian

is_hermitian(atol=1e-08)

Restituisce se questo operatore è ermitiano.

Nota

Questo controllo viene effettuato utilizzando la differenza normal_ordered() , completamente ridotta, tra equiv() e self i suoi e adjoint() zero(). Poiché tale forma normale contrae ogni coppia riducibile di generatori adiacenti — compresa la fusione di due operatori di bordo che condividono una singola modalità tramite EabEbc=−iEacE_{ab} E_{bc} = -i E_{ac} — un termine che si annulla solo con il suo aggiunto dopo tale contrazione viene comunque riconosciuto come zero.

Parametri

atol – Il livello di precisione numerica fino al quale i coefficienti sono considerati uguali. Il valore predefinito è 1e-8.

Risultati

Se questo operatore sia ermitiano.

iter_terms

iter_terms()

Un iteratore sui termini dell'operatore.

Avvertenza

La modifica degli elementi dell'iterazione non influisce sui dati sottostanti dell'operatore.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.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 iteratore sui termini dell’operatore con il relativo indice di gruppo.

Avvertenza

La modifica degli elementi dell'iterazione non influisce sui dati sottostanti dell'operatore.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator([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(ascending=True, reduce=True)

Restituisce un operatore equivalente con termini ordinati normalmente.

L'ordine normale di un termine operatore è definito in modo tale che tutti gli operatori di vertice compaiano prima di tutti gli operatori di spigolo. All’interno di ciascun gruppo, le modalità su cui agisce l’azione sono ordinate in ordine lessicografico.

Nota

Quando si riorganizza un termine, occorre tenere conto delle relazioni miste di commutazione e anticommutazione. Per le definizioni dettagliate, consultare qui.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.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) E(0,1) E(1,0) E(1,2))
>>> print(format(op.normal_ordered().simplify()))
  1.000000e0 +0.000000e0j * (V(0) V(2) E(1,2))

Parametri

  • ascendente – la convenzione di orientamento per gli operatori di bordo. A partire da “ Ekj=−EjkE_{kj} = -E_{jk} ”, ogni operatore di bordo ha due rappresentazioni; True seleziona j<kj < k e False seleziona j>kj > k, incorporando il segno nel coefficiente. Gli operatori di vertice non subiscono alcuna modifica. Il valore predefinito è True.
  • ridurre – se raggruppare i generatori adiacenti in modo che si combinino in un valore scalare o in un unico generatore. Vedi l'esempio sopra. Il valore predefinito è True.

Risultati

Un operatore equivalente ma con ordine normale.

num_groups

num_groups()

Restituisce il numero di gruppi.

Se è groups None, questa funzione restituisce anche None. In caso contrario, restituirà il numero di gruppi, definito come l'indice del gruppo più grande presente più 1 (che potrà quindi essere utilizzato come indice per il gruppo successivo).

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator(
...     [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

Risultati

L'indice settoriale più importante è in groups rialzo di 1.

one

classmethod one()

Crea l'operatore di identità moltiplicativa.

La composizione dell'operatore ottenuto con questo metodo con un altro operatore non produce alcun effetto.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({(): 2.0})
>>> one = EdgeVertexOperator.one()
>>> op & one == op
True
relabel_modes

relabel_modes(permutation)

Restituisce un nuovo operatore con le modalità rinominate.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.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 * (E(2,5) E(3,4))
  1.000000e0 +0.000000e0j * (E(4,2) E(5,3))

Parametri

permutazione – l'elenco delle permutazioni degli indici. La modalità viene i rinominata in permutation[i], pertanto l'elenco non deve contenere voci duplicate e deve essere sufficientemente lungo da indicizzare ogni modalità su cui agisce l'operatore (la sua lunghezza deve superare l'indice di modalità più elevato dell'operatore).

Risultati

Un nuovo operatore con le modalità rinominate.

Aumenti

ValueError – se permutation contiene voci duplicate o è troppo breve per ridenominare una modalità su cui agisce l'operatore.

simplify

simplify(atol=1e-08)

Restituisce un operatore equivalente ma semplificato.

Il processo di semplificazione somma innanzitutto tutti i coefficienti appartenenti a termini uguali e poi mantiene solo quelli il cui coefficiente totale supera la tolleranza specificata (proprio come ichop()).

Quando un operatore è stato manipolato aritmeticamente o costruito in modo tale da non garantire l'unicità dei termini, è opportuno ricorrere a questo metodo prima di applicare qualsiasi metodo che filtri i coefficienti numericamente piccoli, al fine di evitare la perdita di informazioni. Si veda l'esempio riportato di seguito, che illustra come ichop() sia possibile troncare termini la cui somma dà luogo a un coefficiente di grandezza totale che non dovrebbe essere troncato:

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> coeffs = [1e-5] * int(1e5)
>>> boundaries = [0] + [0] * int(1e5)
>>> op = EdgeVertexOperator(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)

Parametri

atol – la tolleranza assoluta per il valore di soglia. Il valore predefinito è 1e-8.

Risultati

Un operatore equivalente ma semplificato.

split_out_groups

split_out_groups(group_indices=None)

Suddivide questo operatore in un elenco facoltativo di nuovi operatori in base a groups.

Se è groups None, questa funzione restituisce anche None. Altrimenti, se group_indices è None (impostazione predefinita), restituisce una lista contenente un nuovo operatore per ogni indice di gruppo in groups, in ordine di indice. Se group_indices è specificato, vengono costruiti solo gli indici richiesti, nell'ordine indicato: ciò evita il costo legato alla costruzione di operatori per gruppi che non vengono mai utilizzati, il che è particolarmente vantaggioso quando è necessario ricorrere solo a un numero ridotto di gruppi rispetto a un totale molto più ampio, ad esempio quando si effettua un sottocampionamento dei gruppi per una formula di prodotto randomizzata. Un indice duplicato in group_indices viene restituito una volta per ogni occorrenza.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator(
...     [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))]

Parametri

group_indices – gli indici dei gruppi per i quali creare gli operatori, nell'ordine di output desiderato. Se non specificato, vengono creati tutti i gruppi, in ordine di indice.

Risultati

Un vettore facoltativo contenente un nuovo operatore per ciascun indice di gruppo richiesto.

zero

classmethod zero()

Costruisce l'operatore di identità additiva.

L'aggiunta di un operatore costruito con questo metodo a un altro operatore non ha alcun effetto.

>>> from qiskit_fermions.operators import EdgeVertexOperator
>>> op = EdgeVertexOperator.from_dict({(): 2.0})
>>> zero = EdgeVertexOperator.zero()
>>> op + zero == op
True

Metodi del protocollo

_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_()

Converte questo operatore in un FermionOperator.

Questo implementa il protocollo SupportsFermionOperator delegando a edge_vertex_to_fermion().

_majorana_operator_

_majorana_operator_()

Converte questo operatore in un MajoranaOperator.

Questo implementa il protocollo SupportsMajoranaOperator delegando a edge_vertex_to_majorana().

Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.