QfMajoranaOperator
QfMajoranaOperator
struct QfMajoranaOperator
Um operador de férmion de Majorana.
Trata-se de uma estrutura de dados opaca para a API do C, cujo funcionamento interno é implementado inteiramente em Rust. O restante desta página descreve o projeto e as funções relacionadas para trabalhar com essa estrutura.
Definição
Esse operador é definido por uma combinação linear de produtos de operadores de Majorana [1], que podem ser definidos em termos dos operadores padrão de criação e aniquilação da segunda quantização fermiónica (ver também .QfFermionOperator):
A propriedade fundamental de que um férmion de Majorana é sua própria antipartícula torna-se imediatamente evidente:
Isso resulta nas seguintes relações de anticomutação para os férmions de Major :
Isso faz com que a definição do operador completo seja a seguinte:
onde é o coeficiente (complexo) que compõe a combinação linear dos produtos de . O índice pode assumir qualquer valor entre 0 e o número de modos fermiónicos de Majorana sobre os quais o operador atua, menos 1.
implementação
Essa estrutura armazena os termos e os coeficientes em vários vetores esparsos, de forma semelhante ao formato de linha esparsa compactada comumente utilizado para matrizes esparsas. Mais especificamente, um único operador contém 4 matrizes:
coeffs | Um vetor de coeficientes complexos composto por dois números de ponto flutuante de 64 bits. |
modes | Um vetor de inteiros de 32 bits que armazena os índices dos modos de Majorana sobre os quais se atuou. |
boundaries | Um vetor de números inteiros que indica os limites em e actions indices. |
Os números inteiros no modes indexam os modos de Majorana, . Ao utilizar a função de conveniência gamma(), índices pares (ímpares) são usados para ( ).
É possível acessar cópias somente para leitura desses arrays internos por meio de suas respectivas funções:
Essa estrutura de dados permite a construção e a manipulação de operadores de maneira muito eficiente. No entanto, isso implica que um operador pode conter termos duplicados a qualquer momento. Esses problemas devem ser resolvidos manualmente por meio do uso de qf_maj_op_simplify().
Construção
É possível construir um novo operador diretamente, especificando os matrizes correspondentes descritos acima. Como alternativa, um vazio QfMajoranaOperator pode ser inicializado com e qf_maj_op_zero() os termos podem ser adicionados iterativamente por meio de qf_maj_op_add_term().
qf_maj_op_new() | Cria um novo operador a partir das matrizes fornecidas. |
qf_maj_op_zero() | Constrói o operador de identidade aditiva. |
qf_maj_op_one() | Constrói o operador de identidade multiplicativa. |
qf_maj_op_add_term() | Adiciona um termo a um já existente QfMajoranaOperator. |
A QfMajoranaOperator pode ser liberada com qf_maj_op_free().
Aritmética
As funções a seguir permitem a realização de operações aritméticas:
qf_maj_op_add() | Soma dois operadores. |
qf_maj_op_mul() | Multiplica um operador por um escalar. |
qf_maj_op_compose() | Combina dois operadores entre si. |
qf_maj_op_adjoint() | Retorna o operador conjugado hermitiano. |
manipulação
As funções a seguir fornecem a lógica de manipulação do operador:
qf_maj_op_ichop() | Remove termos com coeficientes de pequena magnitude. |
qf_maj_op_simplify() | Retorna um operador equivalente, porém simplificado. |
qf_maj_op_normal_ordered() | Retorna um operador equivalente com termos ordenados normalmente. |
qf_maj_op_relabel_modes() | Reetiqueta os modos de um operador. |
Propriedades
Existem as seguintes funções para verificar determinadas propriedades de um operador.
qf_maj_op_is_hermitian() | Retorna se um operador é hermitiano. |
qf_maj_op_max_rank() | Retorna a classificação máxima dos termos neste operador. |
qf_maj_op_is_even() | Retorna se um operador é par. |
[ 1 ]
https://en.wikipedia.org/wiki/Majorana _fermion
Membros
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)
Cria um novo operador.
Qualquer um dos argumentos do tipo ponteiro pode ser NULL se, e somente se, seu comprimento correspondente for zero.
Exemplo
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);Parâmetros
- num_terms – O número de termos no operador.
- num_modes – O número de modos somados em todos os termos.
- coeffs – Um ponteiro para uma matriz de coeficientes de termos. O comprimento dessa matriz deve ser
num_terms. - modos – Um ponteiro para uma matriz de modos que abrange todos os termos. O comprimento dessa matriz deve ser
num_modes. - limites – Um ponteiro para uma matriz contendo os limites entre os termos. O comprimento dessa matriz deve ser
num_terms + 1.
qf_maj_op_free
void qf_maj_op_free(QfMajoranaOperator *op)
Libera um operador existente.
Exemplo
1QfMajoranaOperator *op = qf_maj_op_one();
2qf_maj_op_free(op);Parâmetros
- op – Um ponteiro para o operador de Majorana a ser liberado.
qf_maj_op_get_coeffs
void qf_maj_op_get_coeffs(const QfMajoranaOperator *op, QkComplex64 **coeffs_out, uint64_t *coeffs_len)
Oferece acesso somente para leitura aos coeficientes do operador.
A explicação sobre a estrutura interna dos dados está aqui.
Exemplo
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);Essa função retorna uma cópia dos dados internos.
Parâmetros
- op – Um ponteiro para o operador de Majorana cujos coeficientes devem ser acessados.
- coeffs_out – Um ponteiro para a matriz de valores complexos na qual os coeficientes devem ser gravados.
- coeffs_len – Um ponteiro para o inteiro no qual deve ser gravado o comprimento da matriz de saída.
qf_maj_op_get_modes
void qf_maj_op_get_modes(const QfMajoranaOperator *op, uint32_t **modes_out, uint64_t *modes_len)
Fornece acesso somente para leitura aos índices de modo afetados pelo operador.
A explicação sobre a estrutura interna dos dados está aqui.
Exemplo
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);Essa função retorna uma cópia dos dados internos.
Parâmetros
- op – Um ponteiro para o operador de Majorana cujos modos devem ser acessados.
- modes_out – Um ponteiro para a matriz de valores booleanos na qual os modos serão gravados.
- modes_len – Um ponteiro para o inteiro no qual será gravado o comprimento da matriz de saída.
qf_maj_op_get_boundaries
void qf_maj_op_get_boundaries(const QfMajoranaOperator *op, size_t **boundaries_out, uint64_t *boundaries_len)
Oferece acesso somente para leitura aos índices que indicam os limites entre os termos do operador.
A explicação sobre a estrutura interna dos dados está aqui.
Exemplo
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);Essa função retorna uma cópia dos dados internos.
Parâmetros
- op – Um ponteiro para o operador de Majorana cujos limites devem ser acessados.
- boundaries_out – Um ponteiro para a matriz de valores booleanos na qual os limites devem ser gravados.
- boundaries_len – Um ponteiro para o inteiro no qual será gravado o comprimento da matriz de saída.
qf_maj_op_zero
QfMajoranaOperator *qf_maj_op_zero(void)
Constrói o operador de identidade aditiva.
Adicionar o operador criado por esse método a outro não produz nenhum efeito.
Exemplo
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));Retorna
Um ponteiro para o operador criado.
qf_maj_op_one
QfMajoranaOperator *qf_maj_op_one(void)
Constrói o operador de identidade multiplicativa.
A composição do operador construído por esse método com outro operador não produz nenhum efeito.
Exemplo
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));Retorna
Um ponteiro para o operador criado.
qf_maj_op_has_groups
bool qf_maj_op_has_groups(const QfMajoranaOperator *op)
Verifica se este operador rastreia índices de grupo.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
1QfMajoranaOperator *op = ...;
2
3bool has_groups = qf_maj_op_has_groups(op);Parâmetros
- op – Um ponteiro para o operador de Majorana a ser verificado.
Retorna
Se o operador fornecido possui um atributo groups .
qf_maj_op_num_groups
uint32_t qf_maj_op_num_groups(const QfMajoranaOperator *op)
Obtém o número de grupos de um operador.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
1QfMajoranaOperator *op = ...;
2
3uint32_t num_groups = qf_maj_op_num_groups(op);O número de grupos é calculado de forma preguiçosa como o maior índice de grupo encontrado mais 1.
Parâmetros
- op – Um ponteiro para o operador de Majorana cujo número de grupos deve ser obtido.
Retorna
O número de índices de grupo a partir do atributo groups do operador.
qf_maj_op_group_weights
void qf_maj_op_group_weights(const QfMajoranaOperator *op, double *weights_out)
Calcula a média da magnitude absoluta do coeficiente de cada grupo.
A i-ésima entrada é a soma de abs(coeff) sobre os termos do grupo i, dividida pelo número de termos desse grupo. Este é o peso de amostragem de uma fórmula de produto aleatória (por exemplo, qDRIFT ) que seleciona grupos inteiros em vez de termos individuais, e é calculado em uma única passagem pelo operador, em vez de ser obtido pela redução de e qf_maj_op_get_coeffs() ( qf_maj_op_get_groups() um valor por termo não agrupado cada) no lado do chamador.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
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);Um índice de grupo que nenhum termo possui tem peso 0.0, o que o exclui da amostra.
Parâmetros
- op – Um ponteiro para o operador de Majorana cujos pesos de grupo devem ser calculados.
- weights_out – Um ponteiro para a matriz de valores do tipo double na qual os pesos devem ser gravados. Deve ter o tamanho de :c:func
qf_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)
Obtém os índices de grupo para todos os termos do operador.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
1QfMajoranaOperator *op = ...;
2uint32_t *groups_out;
3uint32_t groups_len;
4
5qf_maj_op_get_groups(op, &groups_out, &groups_len);Parâmetros
- op – Um ponteiro para o operador de Majorana cujos índices de grupo devem ser obtidos.
- groups_out – Um ponteiro para a matriz de inteiros na qual os índices dos grupos devem ser gravados.
- groups_len – Um ponteiro para o inteiro no qual será gravado o comprimento da matriz de saída.
qf_maj_op_set_groups
void qf_maj_op_set_groups(QfMajoranaOperator *op, const uint32_t *groups_in, uint64_t groups_len)
Define o atributo groups do operador fornecido.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
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);Parâmetros
- op – Um ponteiro para o operador de Majorana cujo atributo
groupsdeve ser gravado. - groups_in – Um ponteiro para a matriz de inteiros
groupsna qual o operador deve gravar. - groups_len – O número de elementos na
groups_inmatriz.
qf_maj_op_del_groups
void qf_maj_op_del_groups(QfMajoranaOperator *op)
Exclui o atributo groups do operador indicado.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
1QfMajoranaOperator *op = ...;
2
3qf_maj_op_del_groups(op);Parâmetros
- op – Um ponteiro para o operador de Majorana cujo
groupsatributo deve ser excluído.
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)
Divide esse operador em uma lista de novos operadores com base em seu groups atributo.
Um índice duplicado em group_indices é gravado uma vez por ocorrência em group_ops_out. Solicitar apenas um pequeno número de grupos de um total muito maior é significativamente mais barato do que solicitar todos eles, já que os termos pertencentes a um grupo que não foi solicitado são ignorados, em vez de serem anexados em qualquer lugar.
Explicação sobre os termos dos operadores de grupo: utilize a estrutura dos operadores.
Exemplo
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);Parâmetros
- op – Um ponteiro para o operador de Majorana cuja divisão
groupsdeve ser realizada. - group_indices – Um ponteiro para a matriz de índices de grupos para os quais se deve construir os operadores, na ordem de saída desejada. Talvez
NULL; nesse caso, cada grupo é construído em ordem de índice (o que equivale a passar todos os índices de0até :c:func:qf_maj_op_num_groups- 1). - num_indices – O número de índices na
group_indicesmatriz. Ignorado segroup_indicesforNULL. - group_ops_out – Um ponteiro para a matriz de :c:struct:
QfMajoranaOperatorna qual devem ser gravados os operadores para cada grupo solicitado. Deve ser dimensionado paranum_indicesquando nãogroup_indicesforNULL, ou para :c:func:qf_maj_op_num_groupsquando forNULL.
qf_maj_op_add_term
void qf_maj_op_add_term(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *modes, const QkComplex64 *coeff)
Adiciona um termo a um operador já existente.
Qualquer um dos argumentos do tipo ponteiro pode ser NULL se, e somente se, seu comprimento correspondente for zero.
Esta função redefine o atributo groups do operador para NULL.
Exemplo
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));Parâmetros
- op – Um ponteiro para o operador de Majorana a ser modificado.
- num_modes – O tamanho da matriz de modos.
- modos – Um ponteiro para uma matriz de índices de modo. O comprimento dessa matriz deve ser
num_modes. - coeff – Um ponteiro para o coeficiente complexo.
qf_maj_op_add
QfMajoranaOperator *qf_maj_op_add(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Soma dois operadores.
Exemplo
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));Parâmetros
- esquerda – Um ponteiro para o operador de esquerda.
- direita – Um ponteiro para o operador de direita.
Retorna
Um ponteiro para o operador resultante.
qf_maj_op_mul
QfMajoranaOperator *qf_maj_op_mul(const QfMajoranaOperator *op, const QkComplex64 *scalar)
Multiplica um operador por um escalar.
Exemplo
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));Parâmetros
- op – Um ponteiro para o operador.
- escalar – Um ponteiro para o escalar.
Retorna
Um ponteiro para o operador resultante.
qf_maj_op_compose
QfMajoranaOperator *qf_maj_op_compose(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Combina dois operadores entre si.
Exemplo
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));Parâmetros
- esquerda – Um ponteiro para o operador de esquerda.
- direita – Um ponteiro para o operador de direita.
Retorna
Um ponteiro para o operador resultante.
qf_maj_op_adjoint
QfMajoranaOperator *qf_maj_op_adjoint(const QfMajoranaOperator *op)
Retorna o conjugado hermitiano (ou adjunto) de um operador.
Isso afeta os termos e coeficientes da seguinte forma:
- as ações em cada termo invertem sua ordem
- os coeficientes são conjugados complexos
Exemplo
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));Parâmetros
- op – Um ponteiro para o operador.
Retorna
Um ponteiro para o operador criado.
qf_maj_op_ichop
void qf_maj_op_ichop(QfMajoranaOperator *op, double atol)
Remove termos cuja magnitude do coeficiente seja inferior ao limite especificado.
Essa função trunca os coeficientes de forma avarenta! Se o operador sobre o qual a operação é realizada puder conter coeficientes distintos para termos duplicados, considere chamar qf_maj_op_simplify() em vez disso!
Exemplo
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));Parâmetros
- op – Um ponteiro para o operador.
- atol – A tolerância absoluta para o truncamento do coeficiente.
qf_maj_op_simplify
QfMajoranaOperator *qf_maj_op_simplify(const QfMajoranaOperator *op, double atol)
Retorna um operador equivalente, porém simplificado.
O processo de simplificação soma, primeiro, todos os coeficientes que pertencem a termos iguais e, em seguida, retém apenas aqueles cujo coeficiente total exceda a tolerância especificada (exatamente como qf_maj_op_ichop()).
Quando um operador tiver sido manipulado aritmeticamente ou construído de forma que não garanta a unicidade dos termos, esse método deve ser chamado antes da aplicação de qualquer método que filtre coeficientes numericamente pequenos, a fim de evitar a perda de informação. Veja o exemplo abaixo, que mostra como qf_maj_op_ichop() pode truncar termos cuja soma resulta em um coeficiente de magnitude total que não deveria ser truncado:
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);Parâmetros
- op – Um ponteiro para o operador de Majorana a ser simplificado.
- atol – A tolerância absoluta para o truncamento do coeficiente.
Retorna
Um operador equivalente, porém simplificado.
qf_maj_op_normal_ordered
QfMajoranaOperator *qf_maj_op_normal_ordered(const QfMajoranaOperator *op, bool ascending, bool reduce)
Retorna um operador equivalente com termos ordenados normalmente.
A ordem normal de um termo de operador é definida de forma que todas as ações sejam ordenadas lexicograficamente. O fato de subirem ou descerem depende do valor do parâmetro ascending .
Exemplo
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));Parâmetros
- op – Um ponteiro para o operador.
- ascendente – Se os índices devem subir ou descer.
- reduzir – Se cada termo deve ser reduzido à sua forma mínima, removendo os termos cujo quadrado é igual à identidade.
Retorna
Um ponteiro para o operador criado.
qf_maj_op_is_hermitian
bool qf_maj_op_is_hermitian(const QfMajoranaOperator *op, double atol)
Verifica se um operador é hermitiano.
Exemplo
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));Essa verificação é implementada com qf_maj_op_equiv() base na diferença qf_maj_op_normal_ordered() entre e op seus e qf_maj_op_adjoint() qf_maj_op_zero().
Parâmetros
- op – Um ponteiro para o operador de Majorana a ser verificado.
- atol – A tolerância absoluta até a qual os coeficientes são considerados iguais.
Retorna
Se o operador fornecido é hermitiano.
qf_maj_op_max_rank
uint32_t qf_maj_op_max_rank(const QfMajoranaOperator *op)
Verifica a ordem máxima de um operador.
Exemplo
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);O comprimento do termo mais longo pode depender da forma do operador, o que significa que (por exemplo) a simplificação do operador ou a ordenação normal podem resultar em um grau máximo diferente.
Parâmetros
- op – Um ponteiro para o operador de Majorana a ser verificado.
Retorna
A classificação máxima do operador.
qf_maj_op_is_even
bool qf_maj_op_is_even(const QfMajoranaOperator *op)
Verifica se um operador é par.
Exemplo
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));Um operador é considerado par mesmo quando todos os seus termos contêm um número par de ações.
Parâmetros
- op – Um ponteiro para o operador de Majorana a ser verificado.
Retorna
Se o operador fornecido é par.
qf_maj_op_equal
bool qf_maj_op_equal(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Compare dois operadores para verificar se são iguais.
Exemplo
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));Parâmetros
- esquerda – Um ponteiro para o operador de esquerda.
- direita – Um ponteiro para o operador de direita.
Retorna
Se os dois operadores são iguais.
qf_maj_op_equiv
bool qf_maj_op_equiv(const QfMajoranaOperator *left, const QfMajoranaOperator *right, double atol)
Compare dois operadores para verificar se são equivalentes.
Equivalência, neste contexto, significa igualdade aproximada dentro da tolerância absoluta especificada. Para ser mais preciso, esse método retorna True, quando todos os valores absolutos dos coeficientes da diferença other - self estão abaixo do limite especificado atol.
Exemplo
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));Parâmetros
- esquerda – Um ponteiro para o operador de esquerda.
- direita – Um ponteiro para o operador de direita.
- atol – A tolerância absoluta para a equivalência de coeficientes.
Retorna
Se os dois operadores são equivalentes.
qf_maj_op_len
size_t qf_maj_op_len(const QfMajoranaOperator *op)
Retorna o comprimento (ou o número de termos) do operador fornecido.
Exemplo
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);Parâmetros
- op – Um ponteiro para o operador de Majorana.
Retorna
O comprimento (ou número de termos) do operador.
qf_maj_op_relabel_modes
QfExitCode qf_maj_op_relabel_modes(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *permutation)
Re-rotula os modos do operador fornecido.
Exemplo
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);Parâmetros
- op – Um ponteiro para o operador de Majorana.
- num_modes – O número de índices de modo na lista de permutações fornecida.
- permutação – A lista de permutações de índices.
Retorna
Um código de saída.
QfExitCode_Successem caso de sucessoQfExitCode_DuplicateIndexErrorse forem encontrados índices duplicados na permutaçãoQfExitCode_IndexErrorpara quaisquer outros erros de índice, como índices inválidos.