Skip to main content
IBM Quantum Platform

QfMajoranaOperator

QfMajoranaOperator

struct QfMajoranaOperator

Un opérateur de fermion de Majorana.

Remarque

Il s'agit d'une structure de données opaque pour l'API C, dont le fonctionnement interne est entièrement implémenté en Rust. La suite de cette page décrit la conception et les fonctions associées permettant d'utiliser cette structure.



Définition

Cet opérateur est défini par une combinaison linéaire de produits d'opérateurs de Majorana [1], qui peuvent être définis en termes d'opérateurs de création et d'annihilation fermioniques classiques de la seconde quantification (voir également .QfFermionOperator) :

γ=a+a  and  γ=i(aa)\gamma = a^\dagger + a ~~\text{and}~~ \gamma' = i(a^\dagger - a)

La propriété essentielle d'un fermion de Majorana, à savoir qu'il est sa propre antiparticule, apparaît immédiatement :

γi=γi  and  γi2=(γi)2=1\gamma_i = \gamma_i^\dagger ~~\text{and}~~ \gamma_i^2 = (\gamma_i^\dagger)^2 = 1

Il en résulte les relations d'anti-commutation suivantes pour les fermions de Major 2n2n :

{γi,γj}=2δij\left\{\gamma_i,\gamma_j\right\} = 2\delta_{ij}

La définition de l'opérateur dans son ensemble est donc la suivante :

MajoranaOperator=icijγj^,\text{\texttt{MajoranaOperator}} = \sum_i c_i \bigotimes_j \hat{\gamma_j} \, ,

cic_i est le coefficient (complexe) constituant la combinaison linéaire des produits de γj\gamma_j. L'indice jj peut prendre n'importe quelle valeur comprise entre 0 et le nombre de modes fermioniques de Majorana sur lesquels agit l'opérateur, moins 1.



Implémentation

Cette structure 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 :

coeffsUn vecteur de coefficients complexes composé de deux nombres à virgule flottante de 64 bits.
modesUn vecteur d'entiers de 32 bits contenant les indices des modes de Majorana sur lesquels l'opération a été effectuée.
boundariesUn vecteur d'entiers indiquant les limites dans actions et indices.

Les entiers de l'indice modes correspondent aux modes de Majorana, jj. Lorsque l'on utilise la fonction de commodité gamma(), on utilise des indices pairs (impairs) pour les γ\gamma ( γ\gamma' ).

Remarque

Vous pouvez accéder à des copies en lecture seule de ces tableaux internes via leurs fonctions respectives :

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 à tout moment contenir des termes en double. Ces problèmes doivent être résolus manuellement à l'aide de qf_maj_op_simplify().

Construction

Il est possible de créer un nouvel opérateur directement en spécifiant les tableaux correspondants décrits ci-dessus. Sinon, un vide QfMajoranaOperator peut être initialisé avec qf_maj_op_zero() et des termes peuvent être ajoutés de manière itérative via qf_maj_op_add_term().

qf_maj_op_new()Crée un nouvel opérateur à partir des tableaux fournis.
qf_maj_op_zero()Construit l'opérateur d'identité additive.
qf_maj_op_one()Construit l'opérateur d'identité multiplicative.
qf_maj_op_add_term()Ajoute un terme à un fichier existant QfMajoranaOperator.
Remarque

On QfMajoranaOperator peut libérer A à l'aide de qf_maj_op_free().

Arithmétique

Les fonctions suivantes permettent d'effectuer des opérations arithmétiques :

qf_maj_op_add()Additionne deux opérandes.
qf_maj_op_mul()Multiplie un opérateur par un scalaire.
qf_maj_op_compose()Combine deux opérateurs entre eux.
qf_maj_op_adjoint()Renvoie l'opérateur conjugué hermitien.

manipulation

Les fonctions suivantes fournissent la logique de manipulation des opérateurs :

qf_maj_op_ichop()Supprime les termes dont les coefficients ont une faible valeur absolue.
qf_maj_op_simplify()Renvoie un opérateur équivalent mais simplifié.
qf_maj_op_normal_ordered()Renvoie un opérateur équivalent dont les termes sont classés selon l'ordre habituel.
qf_maj_op_relabel_modes()Renomme les modes d'un opérateur.

Propriétés

Les fonctions suivantes permettent de vérifier certaines propriétés d’un opérateur.

qf_maj_op_is_hermitian()Indique si un opérateur est hermitien.
qf_maj_op_max_rank()Renvoie le rang maximal des termes de cet opérateur.
qf_maj_op_is_even()Indique si un opérateur est pair.

[ 1 ]

https://en.wikipedia.org/wiki/Majorana _fermion


Membres

qf_maj_op_new

QfMajoranaOperator *qf_maj_op_new(uint64_t num_terms, uint64_t num_modes, const QkComplex64 *coeffs, const uint32_t *modes, const uint32_t *boundaries)

Crée un nouvel opérateur.

Un argument de type pointeur peut être NULL si et seulement si sa longueur correspondante est nulle.

Exemple

1uint64_t num_terms = 3;
2uint64_t num_modes = 4;
3uint32_t modes[4] = {0, 1, 2, 3};
4QkComplex64 coeffs[3] = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, -1.0}};
5uint32_t boundaries[4] = {0, 0, 2, 4};
6QfMajoranaOperator *op = qf_maj_op_new(num_terms, num_modes, coeffs,
7                                       modes, boundaries);

Paramètres

  • num_terms – Le nombre de termes dans l'opérateur.
  • num_modes – Nombre de modes, somme de tous les termes.
  • coeffs – Un pointeur vers un tableau de coefficients de termes. La longueur de ce tableau devrait être de num_terms.
  • modes – Un pointeur vers un tableau de modes couvrant tous les termes. La longueur de ce tableau devrait être de num_modes.
  • limites – Un pointeur vers un tableau contenant les limites entre les termes. La longueur de ce tableau devrait être de num_terms + 1.

qf_maj_op_free

void qf_maj_op_free(QfMajoranaOperator *op)

Libère un opérateur existant.

Exemple

1QfMajoranaOperator *op = qf_maj_op_one();
2qf_maj_op_free(op);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à libérer.

qf_maj_op_get_coeffs

void qf_maj_op_get_coeffs(const QfMajoranaOperator *op, QkComplex64 **coeffs_out, uint64_t *coeffs_len)

Permet d'accéder aux coefficients de l'opérateur en lecture seule.

Voir aussi

Vous trouverez ici une explication de la structure interne des données.

Exemple

 1uint64_t num_terms = 2;
 2uint64_t num_modes = 0;
 3QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 4uint32_t boundaries[3] = {0, 0, 0};
 5QfMajoranaOperator *op =
 6    qf_maj_op_new(num_terms, num_modes, coeffs, NULL, boundaries);
 7
 8QkComplex64 *coeffs_out;
 9uint64_t *coeffs_len;
10
11qf_maj_op_get_coeffs(op, &coeffs_out, &coeffs_len);
12
13assert(coeffs_len == 2);
Remarque

Cette fonction renvoie une copie des données internes.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont on souhaite accéder aux coefficients.
  • coeffs_out – Un pointeur vers le tableau de valeurs complexes dans lequel les coefficients doivent être écrits.
  • coeffs_len – Un pointeur vers l'entier dans lequel doit être écrite la longueur du tableau de sortie.

qf_maj_op_get_modes

void qf_maj_op_get_modes(const QfMajoranaOperator *op, uint32_t **modes_out, uint64_t *modes_len)

Fournit un accès en lecture seule aux indices de mode sur lesquels l'opérateur agit.

Voir aussi

Vous trouverez ici une explication de la structure interne des données.

Exemple

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

Cette fonction renvoie une copie des données internes.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont on souhaite accéder aux modes.
  • modes_out – Un pointeur vers le tableau de valeurs booléennes dans lequel les modes doivent être écrits.
  • modes_len – Un pointeur vers l'entier dans lequel écrire la longueur du tableau de sortie.

qf_maj_op_get_boundaries

void qf_maj_op_get_boundaries(const QfMajoranaOperator *op, size_t **boundaries_out, uint64_t *boundaries_len)

Permet un accès en lecture seule aux index indiquant les limites entre les termes d'opérateur.

Voir aussi

Vous trouverez ici une explication de la structure interne des données.

Exemple

 1uint64_t num_terms = 2;
 2uint64_t num_modes = 2;
 3uint32_t modes[2] = {0, 1};
 4QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
 5uint32_t boundaries[3] = {0, 0, 2};
 6QfMajoranaOperator *op =
 7    qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
 8
 9QkComplex64 *boundaries_out;
10uint64_t *boundaries_len;
11
12qf_maj_op_get_boundaries(op, &boundaries_out, &boundaries_len);
13
14assert(boundaries_len == 3);
Remarque

Cette fonction renvoie une copie des données internes.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont on souhaite accéder aux limites.
  • boundaries_out – Un pointeur vers le tableau de valeurs booléennes dans lequel écrire les limites.
  • boundaries_len – Un pointeur vers l'entier dans lequel écrire la longueur du tableau de sortie.

qf_maj_op_zero

QfMajoranaOperator *qf_maj_op_zero(void)

Construit l'opérateur d'identité additive.

L'ajout de l'opérateur ainsi créé à un autre opérateur n'a aucun effet.

Exemple

1QfMajoranaOperator *zero = qf_maj_op_zero();
2
3QfMajoranaOperator *op_plus_zero = qf_maj_op_add(op, zero);
4
5assert(qf_maj_op_equal(op, op_plus_zero));

Retours

Un pointeur vers l'opérateur créé.

qf_maj_op_one

QfMajoranaOperator *qf_maj_op_one(void)

Construit l'opérateur d'identité multiplicative.

La composition de l'opérateur ainsi construit avec un autre opérateur n'a aucun effet.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2
3QfMajoranaOperator *op_times_one = qf_maj_op_compose(op, one);
4
5assert(qf_maj_op_equal(op, op_times_one));

Retours

Un pointeur vers l'opérateur créé.

qf_maj_op_has_groups

bool qf_maj_op_has_groups(const QfMajoranaOperator *op)

Vérifie si cet opérateur prend en compte les indices de groupe.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

1QfMajoranaOperator *op = ...;
2
3bool has_groups = qf_maj_op_has_groups(op);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à vérifier.

Retours

Vérifier si l'opérateur fourni possède un attribut groups .

qf_maj_op_num_groups

uint32_t qf_maj_op_num_groups(const QfMajoranaOperator *op)

Récupère le nombre de groupes d'un opérateur.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

1QfMajoranaOperator *op = ...;
2
3uint32_t num_groups = qf_maj_op_num_groups(op);
Remarque

Le nombre de groupes est évalué de manière paresseuse : il correspond à l'indice du plus grand groupe rencontré, augmenté de 1.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont on souhaite obtenir le nombre de groupes.

Retours

Le nombre d'indices de groupe issus de l'attribut groups de l'opérateur.

qf_maj_op_group_weights

void qf_maj_op_group_weights(const QfMajoranaOperator *op, double *weights_out)

Calcule la moyenne de la valeur absolue du coefficient de chaque groupe.

La i-ième entrée correspond à la somme de abs(coeff) sur les termes du groupe i, divisée par le nombre de termes de ce groupe. Il s'agit du poids d'échantillonnage d'une formule de produit aléatoire (par exemple qDRIFT ) qui prélève des groupes entiers plutôt que des termes individuels, et qui est calculé en un seul passage sur l'opérateur plutôt qu'en réduisant qf_maj_op_get_coeffs() et qf_maj_op_get_groups() (une valeur par terme non regroupé ) du côté de l'appelant.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

 1uint64_t num_terms = 4;
 2uint64_t num_modes = 8;
 3uint32_t modes[8] = {0, 1, 2, 3, 1, 0, 3, 2};
 4QkComplex64 coeffs[4] = {{1.0, 0.0}, {2.0, 0.0}, {-1.0, 0.0}, {-2.0, 0.0}};
 5uint32_t boundaries[5] = {0, 2, 4, 6, 8};
 6QfMajoranaOperator *op = qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
 7
 8uint32_t groups_in[4] = {0, 1, 0, 1};
 9qf_maj_op_set_groups(op, groups_in, num_terms);
10
11double weights[2];
12qf_maj_op_group_weights(op, weights);
13
14assert(weights[0] == 1.0);
15assert(weights[1] == 2.0);
Remarque

Un indice de groupe auquel aucun terme n'est associé a un poids de 0.0, ce qui l'exclut de l'échantillon.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont il faut calculer les poids de groupe.
  • weights_out – Un pointeur vers le tableau de nombres à virgule flottante de type double dans lequel les poids doivent être écrits. Doit être dimensionné pour :c:funcqf_maj_op_num_groups:.

qf_maj_op_get_groups

void qf_maj_op_get_groups(const QfMajoranaOperator *op, uint32_t **groups_out, uint64_t *groups_len)

Récupère les indices de groupe pour tous les termes de l'opérateur.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

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

Paramètres

  • op – Pointeur vers l'opérateur de Majorana dont on souhaite obtenir les indices de groupe.
  • groups_out – Un pointeur vers le tableau d'entiers dans lequel écrire les indices des groupes.
  • groups_len – Un pointeur vers l'entier dans lequel écrire la longueur du tableau de sortie.

qf_maj_op_set_groups

void qf_maj_op_set_groups(QfMajoranaOperator *op, const uint32_t *groups_in, uint64_t groups_len)

Définit l'attribut groups de l'opérateur fourni.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

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

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont l'attribut groups doit être écrit.
  • groups_in – Un pointeur vers le tableau d'entiers groups dans lequel l'opérateur doit écrire.
  • groups_len – Le nombre d'éléments du tableau groups_in .

qf_maj_op_del_groups

void qf_maj_op_del_groups(QfMajoranaOperator *op)

Supprime l'attribut groups de l'opérateur indiqué.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

1QfMajoranaOperator *op = ...;
2
3qf_maj_op_del_groups(op);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont l'attribut groups doit être supprimé.

qf_maj_op_split_out_groups

void qf_maj_op_split_out_groups(const QfMajoranaOperator *op, const uint32_t *group_indices, uint64_t num_indices, QfMajoranaOperator **group_ops_out)

Divise cet opérateur en une liste de nouveaux opérateurs en fonction de son attribut groups .

Un index en double dans group_indices est écrit une fois par occurrence dans group_ops_out. Demander uniquement un petit nombre de groupes parmi un ensemble beaucoup plus vaste revient nettement moins cher que de tous les demander, car les termes appartenant à un groupe qui n'est pas demandé sont ignorés plutôt que d'être ajoutés n'importe où.

Voir aussi

Explication des termes relatifs aux opérateurs de groupe : utilisez la structure des opérateurs.

Exemple

 1uint64_t num_terms = 4;
 2uint64_t num_modes = 8;
 3uint32_t modes[8] = {0, 1, 2, 3, 1, 0, 3, 2};
 4QkComplex64 coeffs[4] = {{1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}};
 5uint32_t boundaries[5] = {0, 2, 4, 6, 8};
 6QfMajoranaOperator *op = qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
 7
 8uint32_t groups_in[4] = {0, 1, 0, 1};
 9qf_maj_op_set_groups(op, groups_in, num_terms);
10
11// build every group, in index order
12QfMajoranaOperator *group_ops[2];
13qf_maj_op_split_out_groups(op, NULL, 0, group_ops);
14
15// build only group 1
16uint32_t group_indices[1] = {1};
17QfMajoranaOperator *group_op[1];
18qf_maj_op_split_out_groups(op, group_indices, 1, group_op);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana dont on groups souhaite extraire la composante.
  • group_indices – Un pointeur vers le tableau des indices de groupe pour lesquels il faut créer des opérateurs, dans l'ordre de sortie souhaité. C'est possible NULL; dans ce cas, chaque groupe est construit selon l'ordre des indices (ce qui revient à passer chaque indice de 0 à :c:func:qf_maj_op_num_groups - 1).
  • num_indices – Le nombre d'indices dans le tableau group_indices . Ignoré si group_indices est égal à NULL.
  • group_ops_out – Un pointeur vers le tableau de :c:struct:QfMajoranaOperator dans lequel doivent être écrits les opérateurs pour chaque groupe demandé. Doit être dimensionné à num_indices lorsque est group_indices différent de NULL, ou à :c:func:qf_maj_op_num_groups lorsqu'il est égal à NULL.

qf_maj_op_add_term

void qf_maj_op_add_term(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *modes, const QkComplex64 *coeff)

Ajoute un terme à un opérateur existant.

Un argument de type pointeur peut être NULL si et seulement si sa longueur correspondante est nulle.

Attention

Cette fonction réinitialise l'attribut groups de l'opérateur à NULL.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2
3QfMajoranaOperator *op = qf_maj_op_zero();
4uint32_t modes[0] = {};
5QkComplex64 coeff = {1.0, 0.0};
6
7qf_maj_op_add_term(op, 0, modes, &coeff);
8
9assert(qf_maj_op_equal(op, one));

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à modifier.
  • num_modes – La longueur du tableau des modes.
  • modes – Un pointeur vers un tableau d’indices de mode. La longueur de ce tableau devrait être de num_modes.
  • coeff – Un pointeur vers le coefficient complexe.

qf_maj_op_add

QfMajoranaOperator *qf_maj_op_add(const QfMajoranaOperator *left, const QfMajoranaOperator *right)

Additionne deux opérandes.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4QfMajoranaOperator *result = qf_maj_op_add(one, zero);
5
6assert(qf_maj_op_equal(result, one));

Paramètres

  • gauche – Un pointeur vers l'opérateur gauche.
  • à droite – Un pointeur vers l'opérateur « à droite ».

Retours

Un pointeur vers l'opérateur obtenu.

qf_maj_op_mul

QfMajoranaOperator *qf_maj_op_mul(const QfMajoranaOperator *op, const QkComplex64 *scalar)

Multiplie un opérateur par un scalaire.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2QkComplex64 coeff = {2.0, 0.0};
3QfMajoranaOperator *result = qf_maj_op_mul(one, &coeff);
4
5QfMajoranaOperator *expected = qf_maj_op_zero();
6uint32_t modes[0] = {};
7qf_maj_op_add_term(expected, 0, modes, &coeff);
8
9assert(qf_maj_op_equal(result, expected));

Paramètres

  • op – Un pointeur vers l'opérateur.
  • scalaire – Un pointeur vers le scalaire.

Retours

Un pointeur vers l'opérateur obtenu.

qf_maj_op_compose

QfMajoranaOperator *qf_maj_op_compose(const QfMajoranaOperator *left, const QfMajoranaOperator *right)

Combine deux opérateurs entre eux.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4QfMajoranaOperator *result = qf_maj_op_compose(one, zero);
5
6assert(qf_maj_op_equal(result, zero));

Paramètres

  • gauche – Un pointeur vers l'opérateur gauche.
  • à droite – Un pointeur vers l'opérateur « à droite ».

Retours

Un pointeur vers l'opérateur obtenu.

qf_maj_op_adjoint

QfMajoranaOperator *qf_maj_op_adjoint(const QfMajoranaOperator *op)

Renvoie le conjugué hermitien (ou adjoint) d'un opérateur.

Cela a les conséquences suivantes sur les termes et les coefficients :

  • les actions de chaque trimestre changent d'ordre
  • les coefficients sont des nombres complexes conjugués

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2uint32_t modes[0] = {};
 3QkComplex64 coeff = {0.0, 1.0};
 4qf_maj_op_add_term(op, 0, modes, &coeff);
 5
 6QfMajoranaOperator *adjoint = qf_maj_op_adjoint(op);
 7
 8QfMajoranaOperator *expected = qf_maj_op_zero();
 9QkComplex64 coeff_adj = {0.0, -1.0};
10qf_maj_op_add_term(expected, 0, modes, &coeff_adj);
11
12assert(qf_maj_op_equal(adjoint, expected));

Paramètres

  • op – Un pointeur vers l'opérateur.

Retours

Un pointeur vers l'opérateur créé.

qf_maj_op_ichop

void qf_maj_op_ichop(QfMajoranaOperator *op, double atol)

Supprime les termes dont la valeur absolue du coefficient est inférieure au seuil indiqué.

Attention

Cette fonction tronque les coefficients de manière avide! Si l'opérateur sur lequel porte l'action est susceptible de contenir des coefficients distincts pour des termes identiques, pensez plutôt qf_maj_op_simplify() à utiliser!

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2uint32_t modes[0] = {};
 3QkComplex64 coeff = {1e-8};
 4qf_maj_op_add_term(op, 0, modes, &coeff);
 5
 6qf_maj_op_ichop(op, 1e-6);
 7
 8QfMajoranaOperator *expected = qf_maj_op_zero();
 9
10assert(qf_maj_op_equal(op, expected));

Paramètres

  • op – Un pointeur vers l'opérateur.
  • atol – Tolérance absolue pour la troncature des coefficients.

qf_maj_op_simplify

QfMajoranaOperator *qf_maj_op_simplify(const QfMajoranaOperator *op, double atol)

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 (tout comme qf_maj_op_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 peut qf_maj_op_ichop() tronquer des termes dont la somme donne une valeur absolue de coefficient qui ne devrait pas être tronquée :

 1uint64_t num_terms = 100000;
 2uint64_t num_modes = 0;
 3uint32_t modes[0] = {};
 4QkComplex64 coeffs[100000];
 5uint32_t boundaries[100001];
 6for (int i = 0; i < 100000; i++) {
 7  coeffs[i].re = 1e-5;
 8  coeffs[i].im = 0.0;
 9  boundaries[i] = 0;
10}
11boundaries[100000] = 0;
12QfMajoranaOperator *op =
13    qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
14
15QfMajoranaOperator *canon = qf_maj_op_simplify(op, 1e-4);
16
17QfMajoranaOperator *one = qf_maj_op_one();
18bool canon_is_equal = qf_maj_op_equiv(canon, one, 1e-6);
19
20qf_maj_op_ichop(op, 1e-4);
21
22QfMajoranaOperator *zero = qf_maj_op_zero();
23bool ichop_is_equal = qf_maj_op_equiv(op, zero, 1e-6);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à simplifier.
  • atol – Tolérance absolue pour la troncature des coefficients.

Retours

Un opérateur équivalent mais simplifié.

qf_maj_op_normal_ordered

QfMajoranaOperator *qf_maj_op_normal_ordered(const QfMajoranaOperator *op, bool ascending, bool reduce)

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 toutes les actions soient classées par ordre lexicographique. Le fait qu'ils montent ou descendent dépend de la valeur du paramètre ascending .

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2uint32_t modes[4] = {0, 2, 1, 3};
 3QkComplex64 coeff = {1.0, 0.0};
 4qf_maj_op_add_term(op, 4, modes, &coeff);
 5
 6QfMajoranaOperator *normal_ordered = qf_maj_op_normal_ordered(op, false, true);
 7
 8QkComplex64 coeff_minus = {-1.0, 0.0};
 9QfMajoranaOperator *expected = qf_maj_op_zero();
10uint32_t modes_exp[4] = {3, 2, 1, 0};
11qf_maj_op_add_term(expected, 4, modes_exp, &coeff_minus);
12
13assert(qf_maj_op_equal(normal_ordered, expected));

Paramètres

  • op – Un pointeur vers l'opérateur.
  • ascendant – Indique si les indices doivent augmenter ou diminuer.
  • réduire – Indique s'il faut réduire chaque terme à sa forme minimale en supprimant les actions dont le carré est égal à l'identité.

Retours

Un pointeur vers l'opérateur créé.

qf_maj_op_is_hermitian

bool qf_maj_op_is_hermitian(const QfMajoranaOperator *op, double atol)

Vérifie si un opérateur est hermitien.

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2uint32_t modes1[2] = {0, 1};
 3QkComplex64 coeff1 = {0.0, 1.00001};
 4qf_maj_op_add_term(op, 2, modes1, &coeff1);
 5uint32_t modes2[2] = {0, 1};
 6QkComplex64 coeff2 = {0.0, -1};
 7qf_maj_op_add_term(op, 2, modes2, &coeff2);
 8
 9assert(qf_maj_op_is_hermitian(op, 1e-4));
10assert(!qf_maj_op_is_hermitian(op, 1e-8));
Remarque

Cette vérification est effectuée qf_maj_op_equiv() en utilisant la différence qf_maj_op_normal_ordered() entre op et ses et qf_maj_op_adjoint() qf_maj_op_zero().

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à vérifier.
  • atol – Tolérance absolue au-delà de laquelle les coefficients ne sont plus considérés comme égaux.

Retours

Si l'opérateur donné est hermitien.

qf_maj_op_max_rank

uint32_t qf_maj_op_max_rank(const QfMajoranaOperator *op)

Vérifie le rang maximal d'un opérateur.

Exemple

1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 1, 2, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6assert(qf_maj_op_max_rank(op), 4);
Remarque

La longueur du terme le plus long peut dépendre de la forme de l’opérateur, ce qui signifie que (par exemple) la simplification de l’opérateur ou le rang normal peuvent aboutir à un rang maximal différent.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à vérifier.

Retours

Le rang maximal de l'opérateur.

qf_maj_op_is_even

bool qf_maj_op_is_even(const QfMajoranaOperator *op)

Vérifie si un opérateur est pair.

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2QkComplex64 coeff = {1.0, 0.0};
 3uint32_t modes1[2] = {0, 1};
 4qf_maj_op_add_term(op, 2, modes1, &coeff);
 5
 6assert(qf_maj_op_is_even(op));
 7
 8uint32_t modes2[1] = {2};
 9qf_maj_op_add_term(op, 2, modes2, &coeff);
10
11assert(!qf_maj_op_is_even(op));
Remarque

Un opérateur est considéré comme pair même lorsque tous ses termes contiennent un nombre pair d'actions.

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana à vérifier.

Retours

Vérifier si l'opérateur fourni est pair.

qf_maj_op_equal

bool qf_maj_op_equal(const QfMajoranaOperator *left, const QfMajoranaOperator *right)

Comparer deux opérateurs pour vérifier s'ils sont égaux.

Exemple

1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4assert(qf_maj_op_equal(one, one));
5assert(!qf_maj_op_equal(one, zero));

Paramètres

  • gauche – Un pointeur vers l'opérateur gauche.
  • à droite – Un pointeur vers l'opérateur « à droite ».

Retours

Si les deux opérateurs sont égaux.

qf_maj_op_equiv

bool qf_maj_op_equiv(const QfMajoranaOperator *left, const QfMajoranaOperator *right, double atol)

Comparer deux opérateurs pour vérifier s'ils sont équivalents.

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.

Exemple

1QfMajoranaOperator *zero = qf_maj_op_zero();
2
3QfMajoranaOperator *op = qf_maj_op_zero();
4uint32_t modes[0] = {};
5QkComplex64 coeff = {1e-7, 0.0};
6qf_maj_op_add_term(op, 0, modes, &coeff);
7
8assert(qf_maj_op_equiv(op, zero, 1e-6));
9assert(!qf_maj_op_equiv(op, zero, 1e-8));

Paramètres

  • gauche – Un pointeur vers l'opérateur gauche.
  • à droite – Un pointeur vers l'opérateur « à droite ».
  • atol – Tolérance absolue pour l'équivalence des coefficients.

Retours

Si les deux opérateurs sont équivalents.

qf_maj_op_len

size_t qf_maj_op_len(const QfMajoranaOperator *op)

Renvoie la longueur (ou le nombre de termes) de l'opérateur fourni.

Exemple

1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 1, 2, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6assert(qf_maj_op_len(op) == 1);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana.

Retours

La longueur (ou le nombre de termes) de l'opérateur.

qf_maj_op_relabel_modes

QfExitCode qf_maj_op_relabel_modes(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *permutation)

Renomme les modes de l'opérateur fourni.

Exemple

 1QfMajoranaOperator *op = qf_maj_op_zero();
 2uint32_t modes[4] = {0, 1, 2, 3};
 3QkComplex64 coeff = {1.0, 0.0};
 4qf_maj_op_add_term(op, 4, modes, &coeff);
 5
 6uint32_t permutation[4] = {3, 2, 1, 0};
 7
 8QfExitCode exit = qf_maj_op_relabel_modes(op, 4, permutation);
 9
10assert(exit == QfExitCode_Success);

Paramètres

  • op – Un pointeur vers l'opérateur de Majorana.
  • num_modes – Nombre d'indices de mode dans la liste de permutations fournie.
  • permutation – La liste des permutations d'index.

Retours

Un code de sortie.

  • QfExitCode_Success en cas de réussite
  • QfExitCode_DuplicateIndexError si des indices en double ont été détectés dans la permutation
  • QfExitCode_IndexError pour toute autre erreur liée aux index, telle que des index non valides.
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.