Skip to main content
IBM Quantum Platform

QfFermionOperator

QfFermionOperator

struct QfFermionOperator

Un operador fermiónico sin espín.

Nota

Se trata de una estructura de datos opaca para la API de C, cuyo funcionamiento interno está implementado íntegramente en Rust. En el resto de esta página se describe el diseño y las funciones relacionadas con el uso de esta estructura.



Definición

Este operador viene definido por una combinación lineal de productos de operadores de creación y aniquilación de fermiones que actúan sobre modos fermiónicos sin espín. Es decir, los términos individuales cumplen las siguientes relaciones anticomutativas: [1]

{ai,aj}={ai,aj}=0,  and  {ai,aj}=δij,\left\{a^\dagger_i, a^\dagger_j\right\} = \left\{a_i, a_j\right\} = 0,~~\text{and}~~ \left\{a_i, a^\dagger_j\right\} = \delta_{ij} \, ,

donde ii y jj no distinguen el tipo de espín de los modos fermiónicos a los que hacen referencia.

De este modo, la definición del operador completo queda así:

QfFermionOperator=icijAj^,\text{\texttt{QfFermionOperator}} = \sum_i c_i \bigotimes_j \hat{A_j} \, ,

donde Aj^{aj,aj}\hat{A_j} \in \{ a_j, a^\dagger_j \} y cic_i es el coeficiente (complejo) que forma la combinación lineal de productos. El índice jj puede tomar cualquier valor comprendido entre 0 y el número de modos fermiónicos sobre los que actúa el operador menos 1.



Implementación

Esta estructura almacena los términos y los coeficientes en varios vectores dispersos, de forma similar al formato de filas dispersas comprimidas que se utiliza habitualmente para las matrices dispersas. Más concretamente, un único operador contiene 4 matrices:

coeffsUn vector de coeficientes complejos formado por dos números de coma flotante de 64 bits.
actionsUn vector de valores booleanos que almacena la naturaleza de las acciones de segunda cuantificación.
modesUn vector de enteros de 32 bits que almacena los índices de los modos fermiónicos sobre los que se ha actuado.
boundariesUn vector de números enteros que indica los límites en y actions modes.

Las entradas en actions indican operadores de creación (aniquilación) mediante True (False). Los modos fermiónicos indexados por modes se consideran sin espín.

Nota

Puedes acceder a copias de solo lectura de estas matrices internas a través de sus respectivas funciones:

Esta estructura de datos permite crear y manipular operadores de forma muy eficiente. Sin embargo, esto implica que un operador podría contener términos duplicados en cualquier momento. Estos deben resolverse manualmente mediante el uso de qf_ferm_op_simplify().

Construcción

Se puede crear un nuevo operador directamente especificando las matrices correspondientes descritas anteriormente. Como alternativa, se QfFermionOperator puede inicializar un vacío con y qf_ferm_op_zero() añadir términos de forma iterativa mediante qf_ferm_op_add_term().

qf_ferm_op_new()Crea un nuevo operador a partir de las matrices proporcionadas.
qf_ferm_op_zero()Crea el operador de identidad aditiva.
qf_ferm_op_one()Crea el operador de identidad multiplicativa.
qf_ferm_op_add_term()Añade un término a un archivo existente QfFermionOperator.
Nota

A se QfFermionOperator puede liberar con qf_ferm_op_free().

Aritmética

Las siguientes funciones permiten realizar operaciones aritméticas:

qf_ferm_op_add()Suma dos operadores.
qf_ferm_op_mul()Multiplica un operador por un escalar.
qf_ferm_op_compose()Combina dos operadores entre sí.
qf_ferm_op_adjoint()Devuelve el operador conjugado hermitiano.

manipulación

Las siguientes funciones proporcionan la lógica de manipulación de operadores:

qf_ferm_op_ichop()Elimina los términos con coeficientes de pequeña magnitud.
qf_ferm_op_simplify()Devuelve un operador equivalente pero simplificado.
qf_ferm_op_normal_ordered()Devuelve un operador equivalente con términos ordenados de forma habitual.
qf_ferm_op_relabel_modes()Cambia los nombres de los modos de un operador.

Propiedades

Existen las siguientes funciones para comprobar determinadas propiedades de un operador.

qf_ferm_op_is_hermitian()Devuelve si un operador es hermitiano.
qf_ferm_op_max_rank()Devuelve el rango máximo de los términos de este operador.
qf_ferm_op_conserves_particle_number()Devuelve si un operador conserva el número de partículas.

[ 1 ]

https://en.wikipedia.org/wiki/Second _quantization#Operadores_de_creación_y_aniquilación_de_fermiones


Miembros

qf_ferm_op_new

QfFermionOperator *qf_ferm_op_new(uint64_t num_terms, uint64_t num_actions, const QkComplex64 *coeffs, const bool *actions, const uint32_t *modes, const uint32_t *boundaries)

Crea un nuevo operador.

Cualquiera de los argumentos de tipo puntero puede ser NULL si y solo si su longitud correspondiente es cero.

Ejemplo

1uint64_t num_terms = 3;
2uint64_t num_actions = 4;
3bool actions[4] = {true, false, true, false};
4uint32_t modes[4] = {0, 1, 2, 3};
5QkComplex64 coeffs[3] = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, -1.0}};
6uint32_t boundaries[4] = {0, 0, 2, 4};
7QfFermionOperator *op = qf_ferm_op_new(num_terms, num_actions, coeffs,
8                                       actions, modes, boundaries);

Parámetros

  • num_terms – El número de términos del operador.
  • num_actions – El número de acciones sumado para todos los términos.
  • coeffs : un puntero a una matriz de coeficientes de términos. La longitud de este array debería ser num_terms.
  • acciones : un puntero a una matriz de acciones que abarca todos los términos. La longitud de este array debería ser num_actions.
  • modos : un puntero a una matriz de modos de acción para todos los términos. La longitud de este array debería ser num_actions.
  • límites : un puntero a una matriz que contiene los límites entre los términos. La longitud de este array debería ser num_terms + 1.

qf_ferm_op_free

void qf_ferm_op_free(QfFermionOperator *op)

Libera un operador ya existente.

Ejemplo

1QfFermionOperator *op = qf_ferm_op_one();
2qf_ferm_op_free(op);

Parámetros

  • op : un puntero al operador fermiónico que se va a liberar.

qf_ferm_op_get_coeffs

void qf_ferm_op_get_coeffs(const QfFermionOperator *op, QkComplex64 **coeffs_out, uint64_t *coeffs_len)

Proporciona acceso de solo lectura a los coeficientes del operador.

Consulte también

Aquí tienes la explicación de la estructura interna de datos.

Ejemplo

 1uint64_t num_terms = 2;
 2uint64_t num_actions = 0;
 3QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 4uint32_t boundaries[3] = {0, 0, 0};
 5QfFermionOperator *op =
 6    qf_ferm_op_new(num_terms, num_actions, coeffs, NULL, NULL, boundaries);
 7
 8QkComplex64 *coeffs_out;
 9uint64_t *coeffs_len;
10
11qf_ferm_op_get_coeffs(op, &coeffs_out, &coeffs_len);
12
13assert(coeffs_len == 2);
Nota

Esta función devuelve una copia de los datos internos.

Parámetros

  • op : un puntero al operador fermiónico cuyos coeficientes se desean consultar.
  • coeffs_out : un puntero a la matriz de valores complejos en la que se escribirán los coeficientes.
  • coeffs_len : un puntero a la variable entera en la que se escribirá la longitud de la matriz de salida.

qf_ferm_op_get_actions

void qf_ferm_op_get_actions(const QfFermionOperator *op, bool **actions_out, uint64_t *actions_len)

Proporciona acceso de solo lectura a las acciones del operador.

Consulte también

Aquí tienes la explicación de la estructura interna de datos.

Ejemplo

 1uint64_t num_terms = 2;
 2uint64_t num_actions = 2;
 3bool actions[2] = {true, false};
 4uint32_t modes[2] = {0, 1};
 5QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 6uint32_t boundaries[3] = {0, 0, 2};
 7QfFermionOperator *op =
 8    qf_ferm_op_new(num_terms, num_actions, coeffs, actions, modes, boundaries);
 9
10QkComplex64 *actions_out;
11uint64_t *actions_len;
12
13qf_ferm_op_get_actions(op, &actions_out, &actions_len);
14
15assert(actions_len == 2);
Nota

Esta función devuelve una copia de los datos internos.

Parámetros

  • op : un puntero al operador fermiónico cuyas acciones se desean consultar.
  • actions_out – Un puntero a la matriz de valores booleanos en la que se escribirán las acciones.
  • actions_len – Un puntero al entero en el que se escribirá la longitud de la matriz de salida.

qf_ferm_op_get_modes

void qf_ferm_op_get_modes(const QfFermionOperator *op, uint32_t **modes_out, uint64_t *modes_len)

Proporciona acceso de solo lectura a los índices de modo sobre los que actúa el operador.

Consulte también

Aquí tienes la explicación de la estructura interna de datos.

Ejemplo

 1uint64_t num_terms = 2;
 2uint64_t num_actions = 2;
 3bool actions[2] = {true, false};
 4uint32_t modes[2] = {0, 1};
 5QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 6uint32_t boundaries[3] = {0, 0, 2};
 7QfFermionOperator *op =
 8    qf_ferm_op_new(num_terms, num_actions, coeffs, actions, modes, boundaries);
 9
10QkComplex64 *modes_out;
11uint64_t *modes_len;
12
13qf_ferm_op_get_modes(op, &modes_out, &modes_len);
14
15assert(modes_len == 2);
Nota

Esta función devuelve una copia de los datos internos.

Parámetros

  • op : un puntero al operador fermiónico cuyos modos se desean consultar.
  • modes_out – Un puntero a la matriz de valores booleanos en la que se escribirán los modos.
  • modes_len – Un puntero al entero en el que se escribirá la longitud del array de salida.

qf_ferm_op_get_boundaries

void qf_ferm_op_get_boundaries(const QfFermionOperator *op, size_t **boundaries_out, uint64_t *boundaries_len)

Proporciona acceso de solo lectura a los índices que indican los límites entre los términos del operador.

Consulte también

Aquí tienes la explicación de la estructura interna de datos.

Ejemplo

 1uint64_t num_terms = 2;
 2uint64_t num_actions = 2;
 3bool actions[2] = {true, false};
 4uint32_t modes[2] = {0, 1};
 5QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 6uint32_t boundaries[3] = {0, 0, 2};
 7QfFermionOperator *op =
 8    qf_ferm_op_new(num_terms, num_actions, coeffs, actions, modes, boundaries);
 9
10QkComplex64 *boundaries_out;
11uint64_t *boundaries_len;
12
13qf_ferm_op_get_boundaries(op, &boundaries_out, &boundaries_len);
14
15assert(boundaries_len == 3);
Nota

Esta función devuelve una copia de los datos internos.

Parámetros

  • op : un puntero al operador fermiónico cuyos límites se desean acceder.
  • boundaries_out – Un puntero a la matriz de valores booleanos en la que se escribirán los límites.
  • boundaries_len – Un puntero al entero en el que se escribirá la longitud de la matriz de salida.

qf_ferm_op_zero

QfFermionOperator *qf_ferm_op_zero(void)

Crea el operador de identidad aditiva.

Añadir el operador creado mediante este método a otro no tiene ningún efecto.

Ejemplo

1QfFermionOperator *zero = qf_ferm_op_zero();
2
3QfFermionOperator *op_plus_zero = qf_ferm_op_add(op, zero);
4
5assert(qf_ferm_op_equal(op, op_plus_zero));

Devuelve

Un puntero al operador creado.

qf_ferm_op_one

QfFermionOperator *qf_ferm_op_one(void)

Crea el operador de identidad multiplicativa.

La combinación del operador creado mediante este método con otro no tiene ningún efecto.

Ejemplo

1QfFermionOperator *one = qf_ferm_op_one();
2
3QfFermionOperator *op_times_one = qf_ferm_op_compose(op, one);
4
5assert(qf_ferm_op_equal(op, op_times_one));

Devuelve

Un puntero al operador creado.

qf_ferm_op_has_groups

bool qf_ferm_op_has_groups(const QfFermionOperator *op)

Comprueba si este operador realiza un seguimiento de los índices de grupo.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

1QfFCIDump *fcidump = qf_fcidump_from_file("molecule.fcidump");
2QfFermionOperator *op = qf_ferm_op_from_fcidump(fcidump);
3
4bool has_groups = qf_ferm_op_has_groups(op);
5
6assert(!has_groups);

Parámetros

  • op : un puntero al operador fermiónico que se va a comprobar.

Devuelve

Si el operador proporcionado tiene un atributo groups .

qf_ferm_op_num_groups

uint32_t qf_ferm_op_num_groups(const QfFermionOperator *op)

Obtiene el número de grupos de un operador.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

1QfFCIDump *fcidump = qf_fcidump_from_file("molecule.fcidump");
2QfFermionOperator *op = qf_ferm_op_from_fcidump(fcidump);
3
4uint32_t num_groups = qf_ferm_op_num_groups(op);
Nota

El número de grupos se calcula de forma diferida como el índice del grupo más grande que aparece más 1.

Parámetros

  • op : un puntero al operador fermiónico cuyo número de grupos se desea obtener.

Devuelve

El número de índices de grupo a partir del atributo groups del operador.

qf_ferm_op_group_weights

void qf_ferm_op_group_weights(const QfFermionOperator *op, double *weights_out)

Obtiene la media de la magnitud absoluta del coeficiente de cada grupo.

La entrada inúmero - es la suma de abs(coeff) sobre los términos del grupo i, dividida por el número de términos de ese grupo. Se trata del peso de muestreo de una fórmula de producto aleatoria (por ejemplo, qDRIFT ) que extrae grupos completos en lugar de términos individuales, y se calcula en una sola pasada por el operador, en lugar de mediante la reducción de y qf_ferm_op_get_coeffs() ( qf_ferm_op_get_groups() un valor por cada término no agrupado ) en el lado del llamante.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

 1uint64_t num_terms = 4;
 2uint64_t num_actions = 8;
 3bool actions[8] = {true, false, true, false, true, false, true, false};
 4uint32_t modes[8] = {0, 1, 2, 3, 1, 0, 3, 2};
 5QkComplex64 coeffs[4] = {{1.0, 0.0}, {2.0, 0.0}, {-1.0, 0.0}, {-2.0, 0.0}};
 6uint32_t boundaries[5] = {0, 2, 4, 6, 8};
 7QfFermionOperator *op =
 8    qf_ferm_op_new(num_terms, num_actions, coeffs, actions, modes, boundaries);
 9
10uint32_t groups_in[4] = {0, 1, 0, 1};
11qf_ferm_op_set_groups(op, groups_in, num_terms);
12
13double weights[2];
14qf_ferm_op_group_weights(op, weights);
15
16assert(weights[0] == 1.0);
17assert(weights[1] == 2.0);
Nota

Un índice de grupo que ningún término tiene asignado tiene un peso de 0.0, lo que hace que quede fuera de la muestra.

Parámetros

  • op : un puntero al operador fermiónico cuyos pesos de grupo se van a calcular.
  • weights_out – Un puntero a la matriz de valores de tipo double en la que se escribirán los pesos. Debe tener el tamaño adecuado para :c:funcqf_ferm_op_num_groups:.

qf_ferm_op_get_groups

void qf_ferm_op_get_groups(const QfFermionOperator *op, uint32_t **groups_out, uint64_t *groups_len)

Obtiene los índices de grupo de todos los términos del operador.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

1QfFermionOperator *op = ...;
2uint32_t *groups_out;
3uint32_t groups_len;
4
5qf_ferm_op_get_groups(op, &groups_out, &groups_len);

Parámetros

  • op : un puntero al operador fermiónico cuyos índices de grupo se desean obtener.
  • groups_out – Un puntero a la matriz de enteros en la que se escribirán los índices de los grupos.
  • groups_len – Un puntero al entero en el que se escribirá la longitud de la matriz de salida.

qf_ferm_op_set_groups

void qf_ferm_op_set_groups(QfFermionOperator *op, const uint32_t *groups_in, uint64_t groups_len)

Establece el atributo groups del operador indicado.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

1QfFermionOperator *op = ...;
2
3uint32_t num_terms = 4;
4uint32_t groups_in[4] = {0, 1, 0, 1};
5qf_ferm_op_set_groups(op, groups_in, num_terms);

Parámetros

  • op – Un puntero al operador fermiónico cuyo atributo groups se va a escribir.
  • groups_in – Un puntero a la matriz de enteros groups en la que se va a escribir el operador.
  • groups_len – El número de elementos del matriz groups_in .

qf_ferm_op_del_groups

void qf_ferm_op_del_groups(QfFermionOperator *op)

Elimina el atributo groups del operador indicado.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

1QfFermionOperator *op = ...;
2
3qf_ferm_op_del_groups(op);

Parámetros

  • op : un puntero al operador fermiónico cuyo atributo groups se va a eliminar.

qf_ferm_op_split_out_groups

void qf_ferm_op_split_out_groups(const QfFermionOperator *op, const uint32_t *group_indices, uint64_t num_indices, QfFermionOperator **group_ops_out)

Divide este operador en una lista de nuevos operadores en función de su groups atributo.

Un índice duplicado en group_indices se escribe una vez por cada aparición en group_ops_out. Solicitar solo un pequeño número de grupos de entre un total mucho mayor resulta considerablemente más barato que solicitarlos todos, ya que los términos que pertenecen a un grupo que no se ha solicitado se omiten, en lugar de añadirse en cualquier lugar.

Consulte también

Explicación de los términos relacionados con los operadores de grupo: utiliza la estructura de operadores.

Ejemplo

 1uint64_t num_terms = 4;
 2uint64_t num_actions = 8;
 3bool actions[8] = {true, false, true, false, true, false, true, false};
 4uint32_t modes[8] = {0, 1, 2, 3, 1, 0, 3, 2};
 5QkComplex64 coeffs[4] = {{1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}};
 6uint32_t boundaries[5] = {0, 2, 4, 6, 8};
 7QfFermionOperator *op =
 8    qf_ferm_op_new(num_terms, num_actions, coeffs, actions, modes, boundaries);
 9
10uint32_t groups_in[4] = {0, 1, 0, 1};
11qf_ferm_op_set_groups(op, groups_in, num_terms);
12
13// build every group, in index order
14QfFermionOperator *group_ops[2];
15qf_ferm_op_split_out_groups(op, NULL, 0, group_ops);
16
17// build only group 1
18uint32_t group_indices[1] = {1};
19QfFermionOperator *group_op[1];
20qf_ferm_op_split_out_groups(op, group_indices, 1, group_op);

Parámetros

  • op – Un puntero al operador fermiónico del que se va groups a extraer.
  • group_indices – Un puntero a la matriz de índices de grupo para los que se van a crear operadores, en el orden de salida deseado. Puede que sí NULL; en ese caso, cada grupo se construye por orden de índice (lo que equivale a pasar cada índice desde 0 hasta :c:func:qf_ferm_op_num_groups - 1).
  • num_indices : el número de índices del matriz group_indices . Se ignora si es group_indices NULL.
  • group_ops_out – Un puntero a la matriz de :c:struct:QfFermionOperator en la que se escribirán los operadores de cada grupo solicitado. Debe ajustarse a num_indices cuando no group_indices sea NULL, o a :c:func:qf_ferm_op_num_groups cuando sea NULL.

qf_ferm_op_add_term

void qf_ferm_op_add_term(QfFermionOperator *op, uint64_t num_actions, const bool *actions, const uint32_t *modes, const QkComplex64 *coeff)

Añade un término a un operador ya existente.

Cualquiera de los argumentos de tipo puntero puede ser NULL si y solo si su longitud correspondiente es cero.

Precaución

Esta función restablece el atributo groups del operador a NULL.

Ejemplo

 1QfFermionOperator *one = qf_ferm_op_one();
 2
 3QfFermionOperator *op = qf_ferm_op_zero();
 4bool actions[0] = {};
 5uint32_t modes[0] = {};
 6QkComplex64 coeff = {1.0, 0.0};
 7
 8qf_ferm_op_add_term(op, 0, actions, modes, &coeff);
 9
10assert(qf_ferm_op_equal(op, one));

Parámetros

  • op : un puntero al operador fermiónico que se va a modificar.
  • num_actions : la longitud de la matriz de acciones.
  • acciones : un puntero a una matriz de acciones. La longitud de este array debería ser num_actions.
  • modos : un puntero a una matriz de modos de acción. La longitud de este array debería ser num_actions.
  • coeff : un puntero al coeficiente complejo.

qf_ferm_op_add

QfFermionOperator *qf_ferm_op_add(const QfFermionOperator *left, const QfFermionOperator *right)

Suma dos operadores.

Ejemplo

1QfFermionOperator *one = qf_ferm_op_one();
2QfFermionOperator *zero = qf_ferm_op_zero();
3
4QfFermionOperator *result = qf_ferm_op_add(one, zero);
5
6assert(qf_ferm_op_equal(result, one));

Parámetros

  • izquierda – Un puntero al operador de izquierda.
  • derecha – Un puntero al operador «derecha».

Devuelve

Un puntero al operador resultante.

qf_ferm_op_mul

QfFermionOperator *qf_ferm_op_mul(const QfFermionOperator *op, const QkComplex64 *scalar)

Multiplica un operador por un escalar.

Ejemplo

 1QfFermionOperator *one = qf_ferm_op_one();
 2QkComplex64 coeff = {2.0, 0.0};
 3QfFermionOperator *result = qf_ferm_op_mul(one, &coeff);
 4
 5QfFermionOperator *expected = qf_ferm_op_zero();
 6bool actions[0] = {};
 7uint32_t modes[0] = {};
 8qf_ferm_op_add_term(expected, 0, actions, modes, &coeff);
 9
10assert(qf_ferm_op_equal(result, expected));

Parámetros

  • op : un puntero al operador.
  • escalar : un puntero al escalar.

Devuelve

Un puntero al operador resultante.

qf_ferm_op_compose

QfFermionOperator *qf_ferm_op_compose(const QfFermionOperator *left, const QfFermionOperator *right)

Combina dos operadores entre sí.

Ejemplo

1QfFermionOperator *one = qf_ferm_op_one();
2QfFermionOperator *zero = qf_ferm_op_zero();
3
4QfFermionOperator *result = qf_ferm_op_compose(one, zero);
5
6assert(qf_ferm_op_equal(result, zero));

Parámetros

  • izquierda – Un puntero al operador de izquierda.
  • derecha – Un puntero al operador «derecha».

Devuelve

Un puntero al operador resultante.

qf_ferm_op_adjoint

QfFermionOperator *qf_ferm_op_adjoint(const QfFermionOperator *op)

Devuelve el conjugado hermitiano (o adjunto) de un operador.

Esto afecta a los términos y coeficientes de la siguiente manera:

  • las acciones de cada término invierten su orden y alternan entre la creación y la aniquilación
  • los coeficientes son conjugados complejos

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions[0] = {};
 3uint32_t modes[0] = {};
 4QkComplex64 coeff = {0.0, 1.0};
 5qf_ferm_op_add_term(op, 0, actions, modes, &coeff);
 6
 7QfFermionOperator *adjoint = qf_ferm_op_adjoint(op);
 8
 9QfFermionOperator *expected = qf_ferm_op_zero();
10QkComplex64 coeff_adj = {0.0, -1.0};
11qf_ferm_op_add_term(expected, 0, actions, modes, &coeff_adj);
12
13assert(qf_ferm_op_equal(adjoint, expected));

Parámetros

  • op : un puntero al operador.

Devuelve

Un puntero al operador creado.

qf_ferm_op_ichop

void qf_ferm_op_ichop(QfFermionOperator *op, double atol)

Elimina los términos cuyo coeficiente sea inferior al umbral indicado.

Precaución

¡Esta función trunca los coeficientes de forma «glotona»! Si el operador sobre el que se realiza la operación pudiera contener coeficientes distintos para términos duplicados, ¡considera la posibilidad de llamar a qf_ferm_op_simplify() en su lugar!

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions[0] = {};
 3uint32_t modes[0] = {};
 4QkComplex64 coeff = {1e-8};
 5qf_ferm_op_add_term(op, 0, actions, modes, &coeff);
 6
 7qf_ferm_op_ichop(op, 1e-6);
 8
 9QfFermionOperator *expected = qf_ferm_op_zero();
10
11assert(qf_ferm_op_equal(op, expected));

Parámetros

  • op : un puntero al operador.
  • atol – La tolerancia absoluta para el truncamiento de coeficientes.

qf_ferm_op_simplify

QfFermionOperator *qf_ferm_op_simplify(const QfFermionOperator *op, double atol)

Devuelve un operador equivalente pero simplificado.

El proceso de simplificación suma primero todos los coeficientes que pertenecen a términos iguales y, a continuación, solo conserva aquellos cuyo coeficiente total supera la tolerancia especificada (al igual que qf_ferm_op_ichop()).

Cuando un operador haya sido manipulado aritméticamente o construido de tal forma que no garantice la unicidad de los términos, se debe llamar a este método antes de aplicar cualquier método que filtre los coeficientes numéricamente pequeños, con el fin de evitar la pérdida de información. Observa el ejemplo siguiente, que muestra cómo se qf_ferm_op_ichop() pueden truncar términos cuya suma da como resultado una magnitud de coeficiente total que no debería truncarse:

 1uint64_t num_terms = 100000;
 2uint64_t num_actions = 0;
 3bool actions[0] = {};
 4uint32_t modes[0] = {};
 5QkComplex64 coeffs[100000];
 6uint32_t boundaries[100001];
 7for (int i = 0; i < 100000; i++) {
 8  coeffs[i].re = 1e-5;
 9  coeffs[i].im = 0.0;
10  boundaries[i] = 0;
11}
12boundaries[100000] = 0;
13QfFermionOperator *op = qf_ferm_op_new(num_terms, num_actions, coeffs,
14                                       actions, modes, boundaries);
15
16QfFermionOperator *canon = qf_ferm_op_simplify(op, 1e-4);
17
18QfFermionOperator *one = qf_ferm_op_one();
19bool canon_is_equal = qf_ferm_op_equiv(canon, one, 1e-6);
20
21qf_ferm_op_ichop(op, 1e-4);
22
23QfFermionOperator *zero = qf_ferm_op_zero();
24bool ichop_is_equal = qf_ferm_op_equiv(op, zero, 1e-6);

Parámetros

  • op : un puntero al operador fermiónico que se va a simplificar.
  • atol – La tolerancia absoluta para el truncamiento de coeficientes.

Devuelve

Un operador equivalente, pero simplificado.

qf_ferm_op_normal_ordered

QfFermionOperator *qf_ferm_op_normal_ordered(const QfFermionOperator *op, const bool *sandwich)

Devuelve un operador equivalente con términos ordenados de forma habitual.

El orden normal de un término de operador se define de tal manera que todas las acciones de creación aparezcan antes que todas las acciones de aniquilación. Dentro de cada grupo, los modos sobre los que se actúa se ordenan lexicográficamente. Que el orden sea ascendente o descendente depende del valor del argumento sandwich :

  • NULL: ambos grupos están ordenados en orden lexicográfico descendente (p. ej., +_1 +_0 -_1 -_0)
  • True: los índices más grandes aparecen hacia el centro, es decir, las acciones de creación siguen un orden lexicográfico ascendente, mientras que las de aniquilación siguen un orden descendente (p. ej., +_0 +_1 -_1 -_0)
  • False: los índices más pequeños aparecen hacia el centro, es decir, las acciones de creación se ordenan en orden descendente según el orden lexicográfico, mientras que las de aniquilación se ordenan en orden ascendente (p. ej., +_1 +_0 -_0 -_1)

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions[4] = {false, true, false, true};
 3uint32_t modes[4] = {1, 1, 0, 0};
 4QkComplex64 coeff = {1.0, 0.0};
 5qf_ferm_op_add_term(op, 4, actions, modes, &coeff);
 6
 7QfFermionOperator *normal_ordered = qf_ferm_op_normal_ordered(op, NULL);
 8
 9uint64_t num_terms = 4;
10uint64_t num_actions = 8;
11bool actions_exp[8] = {true, false, true, false, true, true, false, false};
12uint32_t modes_exp[8] = {0, 0, 1, 1, 1, 0, 1, 0};
13QkComplex64 coeffs_exp[4] = {
14    {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}};
15uint32_t boundaries_exp[5] = {0, 0, 2, 4, 8};
16QfFermionOperator *expected =
17    qf_ferm_op_new(num_terms, num_actions, coeffs_exp, actions_exp,
18                   modes_exp, boundaries_exp);
19
20assert(qf_ferm_op_equal(normal_ordered, expected));
Nota

Cuando se reordena un término, hay que tener en cuenta las relaciones de anticomutación, aiaj=δijajaia_i a^\dagger_j = \delta_{ij} - a^\dagger_j a^i, lo que implica que el número de términos podría variar.

Parámetros

  • op : un puntero al operador.
  • sandwich – Un puntero a un valor booleano. Este puntero puede ser NULL.

Devuelve

Un puntero al operador creado.

qf_ferm_op_is_hermitian

bool qf_ferm_op_is_hermitian(const QfFermionOperator *op, double atol)

Comprueba si un operador es hermitiano.

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions1[2] = {true, false};
 3uint32_t modes1[2] = {0, 1};
 4QkComplex64 coeff1 = {0.0, 1.00001};
 5qf_ferm_op_add_term(op, 2, actions1, modes1, &coeff1);
 6bool actions2[2] = {true, false};
 7uint32_t modes2[2] = {1, 0};
 8QkComplex64 coeff2 = {0.0, -1};
 9qf_ferm_op_add_term(op, 2, actions2, modes2, &coeff1);
10
11assert(qf_ferm_op_is_hermitian(op, 1e-4));
12assert(!qf_ferm_op_is_hermitian(op, 1e-8));
Nota

Esta comprobación se lleva a qf_ferm_op_equiv() cabo utilizando la qf_ferm_op_normal_ordered() diferencia entre op y sus y qf_ferm_op_adjoint() qf_ferm_op_zero().

Parámetros

  • op : un puntero al operador fermiónico que se va a comprobar.
  • atol – La tolerancia absoluta hasta la cual se considera que los coeficientes son iguales.

Devuelve

Si el operador dado es hermitiano.

qf_ferm_op_max_rank

uint32_t qf_ferm_op_max_rank(const QfFermionOperator *op)

Comprueba el rango máximo de un operador.

Ejemplo

1QfFermionOperator *op = qf_ferm_op_zero();
2bool actions[4] = {true, false, true, false};
3uint32_t modes[4] = {0, 1, 2, 3};
4QkComplex64 coeff = {1.0, 0.0};
5qf_ferm_op_add_term(op, 4, actions, modes, &coeff);
6
7assert(qf_ferm_op_max_rank(op), 4);
Nota

La longitud del término más largo puede depender de la forma del operador, lo que significa que (por ejemplo) la simplificación del operador o el orden normal pueden dar lugar a un rango máximo diferente.

Parámetros

  • op : un puntero al operador fermiónico que se va a comprobar.

Devuelve

El rango máximo del operador.

qf_ferm_op_conserves_particle_number

bool qf_ferm_op_conserves_particle_number(const QfFermionOperator *op)

Comprueba si un operador conserva el número de partículas.

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions1[2] = {true, false};
 3uint32_t modes1[2] = {0, 1};
 4QkComplex64 coeff1 = {0.0, 1.00001};
 5qf_ferm_op_add_term(op, 2, actions1, modes1, &coeff1);
 6bool actions2[2] = {true, false};
 7uint32_t modes2[2] = {1, 0};
 8QkComplex64 coeff2 = {0.0, -1};
 9qf_ferm_op_add_term(op, 2, actions2, modes2, &coeff2);
10
11assert(qf_ferm_op_is_hermitian(op, 1e-4));
12assert(!qf_ferm_op_is_hermitian(op, 1e-8));

Parámetros

  • op : un puntero al operador fermiónico que se va a comprobar.

Devuelve

Si el operador proporcionado conserva el número de partículas.

qf_ferm_op_equal

bool qf_ferm_op_equal(const QfFermionOperator *left, const QfFermionOperator *right)

Compara dos operadores para ver si son iguales.

Ejemplo

1QfFermionOperator *one = qf_ferm_op_one();
2QfFermionOperator *zero = qf_ferm_op_zero();
3
4assert(qf_ferm_op_equal(one, one));
5assert(!qf_ferm_op_equal(one, zero));

Parámetros

  • izquierda – Un puntero al operador de izquierda.
  • derecha – Un puntero al operador «derecha».

Devuelve

Si los dos operadores son iguales.

qf_ferm_op_equiv

bool qf_ferm_op_equiv(const QfFermionOperator *left, const QfFermionOperator *right, double atol)

Compara dos operadores para comprobar si son equivalentes.

En este contexto, «equivalencia» significa igualdad aproximada dentro de los límites de la tolerancia absoluta especificada. Para ser más precisos, este método devuelve True, cuando todos los valores absolutos de los coeficientes de la diferencia other - self son inferiores al umbral especificado atol.

Ejemplo

 1QfFermionOperator *zero = qf_ferm_op_zero();
 2
 3QfFermionOperator *op = qf_ferm_op_zero();
 4bool actions[0] = {};
 5uint32_t modes[0] = {};
 6QkComplex64 coeff = {1e-7, 0.0};
 7qf_ferm_op_add_term(op, 0, actions, modes, &coeff);
 8
 9assert(qf_ferm_op_equiv(op, zero, 1e-6));
10assert(!qf_ferm_op_equiv(op, zero, 1e-8));

Parámetros

  • izquierda – Un puntero al operador de izquierda.
  • derecha – Un puntero al operador «derecha».
  • atol – La tolerancia absoluta para la equivalencia de coeficientes.

Devuelve

Si los dos operadores son equivalentes.

qf_ferm_op_len

size_t qf_ferm_op_len(const QfFermionOperator *op)

Devuelve la longitud (o el número de términos) del operador proporcionado.

Ejemplo

1QfFermionOperator *op = qf_ferm_op_zero();
2bool actions[4] = {true, false, true, false};
3uint32_t modes[4] = {0, 1, 2, 3};
4QkComplex64 coeff = {1.0, 0.0};
5qf_ferm_op_add_term(op, 4, actions, modes, &coeff);
6
7assert(qf_ferm_op_len(op) == 1);

Parámetros

  • op : un puntero al operador fermiónico.

Devuelve

La longitud (o el número de términos) del operador.

qf_ferm_op_relabel_modes

QfExitCode qf_ferm_op_relabel_modes(QfFermionOperator *op, uint64_t num_modes, const uint32_t *permutation)

Reetiqueta los índices del operador proporcionado.

Ejemplo

 1QfFermionOperator *op = qf_ferm_op_zero();
 2bool actions[4] = {true, false, true, false};
 3uint32_t indices[4] = {0, 1, 2, 3};
 4QkComplex64 coeff = {1.0, 0.0};
 5qf_ferm_op_add_term(op, 4, actions, indices, &coeff);
 6
 7uint32_t permutation[4] = {3, 2, 1, 0};
 8
 9QfExitCode exit = qf_ferm_op_relabel_modes(op, 4, permutation);
10
11assert(exit == QfExitCode_Success);

Parámetros

  • op : un puntero al operador fermiónico.
  • num_modes : el número de índices de modo en la lista de permutaciones facilitada.
  • permutación – La lista de permutaciones de índices.

Devuelve

Un código de salida.

  • QfExitCode_Success en caso de éxito
  • QfExitCode_DuplicateIndexError si se han encontrado índices duplicados en la permutación
  • QfExitCode_IndexError para cualquier otro error relacionado con los índices, como los índices no válidos.
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.