Skip to main content
IBM Quantum Platform

QfFermionOperator

QfFermionOperator

struct QfFermionOperator

스핀이 없는 페르미온 연산자.

참고

이는 C API에 대해서는 불투명한 데이터 구조이며, 내부 구현은 전적으로 Rust로 이루어져 있습니다. 이 페이지의 나머지 부분에서는 이 구조체를 다루기 위한 설계 및 관련 기능에 대해 설명합니다.



정의

이 연산자는 스핀이 없는 페르미온 모드에 작용하는 페르미온 생성 연산자와 소멸 연산자의 곱에 대한 선형 조합으로 정의된다. 즉, 각 항은 다음과 같은 반교환 관계를 만족한다: [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} \, ,

여기서 iijj 는 인덱스로 지정된 페르미온 모드의 스핀 종류를 구분하지 않는다.

이로써 연산자 전체의 정의는 다음과 같이 됩니다:

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

여기서 Aj^{aj,aj}\hat{A_j} \in \{ a_j, a^\dagger_j \} 이며, cic_i 는 곱의 선형 조합을 구성하는 (복소수) 계수이다. jj 의 지수는 0부터 연산자가 작용하는 페르미온 모드의 개수에서 1을 뺀 값 사이의 임의의 값을 가질 수 있다.



구현

이 구조체는 희소 행렬에 흔히 사용되는 압축 희소 행 (compressed sparse row) 형식과 유사하게, 항과 계수를 여러 개의 희소 벡터에 저장합니다. 좀 더 구체적으로 말하자면, 하나의 연산자에는 4개의 배열이 포함되어 있습니다:

칼럼 1
칼럼 2
coeffs두 개의 64비트 부동소수점 숫자로 구성된 복소수 계수 벡터입니다.
actions2차 양자화 작업의 특성을 저장하는 부울 값 벡터.
modes작동이 적용된 페르미온 모드 인덱스를 저장하는 32비트 정수 벡터.
boundariesactions 에서 경계를 나타내는 정수 벡터 modes.

()로 표시된 항목은 True (False)에 의한 생성(소멸) 연산자를 나타냅니다 actions . 로 인덱싱된 페르미온 모드는 스핀이 없는 것으로 간주됩니다 modes .

참고

각 내부 배열의 읽기 전용 복사본은 해당 함수를 통해 액세스할 수 있습니다:

이 데이터 구조를 사용하면 연산자를 매우 효율적으로 생성하고 조작할 수 있습니다. 그러나 이는 연산자에 언제든지 중복된 용어가 포함될 수 있음을 시사한다. 이러한 문제는 다음을 사용하여 수동으로 해결해야 합니다 qf_ferm_op_simplify().

건설

위에서 설명한 해당 배열을 지정함으로써 새로운 연산자를 직접 생성할 수 있습니다. 또는 빈 을 으로 초기화한 다음 qf_ferm_op_zero() , 를 통해 항을 반복적으로 추가할 수도 있습니다 QfFermionOperatorqf_ferm_op_add_term() .

칼럼 1
칼럼 2
qf_ferm_op_new()지정된 배열을 사용하여 새로운 연산자를 생성합니다.
qf_ferm_op_zero()가법 항등 연산자를 생성합니다.
qf_ferm_op_one()곱셈 항등 연산자를 생성합니다.
qf_ferm_op_add_term()기존에 용어를 추가합니다 QfFermionOperator.
참고

A는.을 사용하여 해제할 QfFermionOperator 수 있습니다 qf_ferm_op_free().

산술

다음 함수들은 산술 연산을 수행합니다:

칼럼 1
칼럼 2
qf_ferm_op_add()두 연산자를 더합니다.
qf_ferm_op_mul()연산자에 스칼라를 곱합니다.
qf_ferm_op_compose()두 연산자를 서로 결합합니다.
qf_ferm_op_adjoint()헤르미트 공액 연산자를 반환합니다.

조작

다음 함수들은 연산자 조작 로직을 제공합니다:

칼럼 1
칼럼 2
qf_ferm_op_ichop()계수의 크기가 작은 항을 제거합니다.
qf_ferm_op_simplify()동등하지만 단순화된 연산자를 반환합니다.
qf_ferm_op_normal_ordered()일반 순서를 가진 항을 갖는 등가 연산자를 반환합니다.
qf_ferm_op_relabel_modes()연산자의 모드에 새로운 이름을 지정합니다.

특성

연산자의 특정 속성을 확인하기 위한 다음과 같은 함수들이 있습니다.

칼럼 1
칼럼 2
qf_ferm_op_is_hermitian()연산자가 헤르미트 연산자인지 여부를 반환합니다.
qf_ferm_op_max_rank()이 연산자에 포함된 항들의 최대 차수를 반환합니다.
qf_ferm_op_conserves_particle_number()해당 연산자가 입자 수 보존성을 갖는지 여부를 반환합니다.

[ 1 ]

https://en.wikipedia.org/wiki/Second _quantization#Fermion_creation_and_annihilation_operators


멤버

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)

새로운 연산자를 생성합니다.

포인터 인자 중 어느 것이든, 해당 인자의 길이가 0일 때만 if NULL 가 될 수 있다.

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);

매개변수

  • num_terms – 연산자에 포함된 항의 개수.
  • num_actions – 모든 항에 대해 합산된 작업의 개수.
  • coeffs – 항 계수 배열을 가리키는 포인터. 이 배열의 길이는 여야 합니다 num_terms.
  • 액션 – 모든 항에 대한 액션 배열을 가리키는 포인터. 이 배열의 길이는 여야 합니다 num_actions.
  • 모드 – 모든 항에 대한 액션 모드 배열을 가리키는 포인터. 이 배열의 길이는 여야 합니다 num_actions.
  • 경계 – 항들 사이의 경계를 담은 배열을 가리키는 포인터입니다. 이 배열의 길이는 여야 합니다 num_terms + 1.

qf_ferm_op_free

void qf_ferm_op_free(QfFermionOperator *op)

기존 연산자를 해제합니다.

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

매개변수

  • op – 해제할 페르미온 연산자에 대한 포인터.

qf_ferm_op_get_coeffs

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

연산자의 계수에 대한 읽기 전용 액세스 권한을 제공합니다.

관련 참조

내부 데이터 구조에 대한 설명은 여기에서 확인할 수 있습니다.

 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);
참고

이 함수는 내부 데이터의 복사본 을 반환합니다.

매개변수

  • op – 접근할 계수가 포함된 페르미온 연산자에 대한 포인터.
  • coeffs_out – 계수를 기록할 복소수 값 배열을 가리키는 포인터입니다.
  • coeffs_len – 출력 배열의 길이를 기록할 정수 변수에 대한 포인터입니다.

qf_ferm_op_get_actions

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

운영자의 작업에 대한 읽기 전용 액세스 권한을 제공합니다.

관련 참조

내부 데이터 구조에 대한 설명은 여기에서 확인할 수 있습니다.

 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);
참고

이 함수는 내부 데이터의 복사본 을 반환합니다.

매개변수

  • op – 액세스할 연산을 가진 페르미온 연산자에 대한 포인터.
  • actions_out – 동작을 기록할 부울 값 배열을 가리키는 포인터.
  • actions_len – 출력 배열의 길이를 기록할 정수 변수에 대한 포인터입니다.

qf_ferm_op_get_modes

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

연산자의 적용 대상 모드 인덱스에 대한 읽기 전용 액세스 권한을 제공합니다.

관련 참조

내부 데이터 구조에 대한 설명은 여기에서 확인할 수 있습니다.

 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);
참고

이 함수는 내부 데이터의 복사본 을 반환합니다.

매개변수

  • op – 접근할 모드를 가진 페르미온 연산자에 대한 포인터.
  • modes_out – 모드를 기록할 부울 값 배열을 가리키는 포인터입니다.
  • modes_len – 출력 배열의 길이를 기록할 정수 변수에 대한 포인터입니다.

qf_ferm_op_get_boundaries

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

연산자 항들 간의 경계를 나타내는 인덱스에 대한 읽기 전용 액세스 권한을 제공합니다.

관련 참조

내부 데이터 구조에 대한 설명은 여기에서 확인할 수 있습니다.

 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);
참고

이 함수는 내부 데이터의 복사본 을 반환합니다.

매개변수

  • op – 접근할 경계를 가진 페르미온 연산자에 대한 포인터.
  • boundaries_out – 경계를 기록할 부울 값 배열을 가리키는 포인터입니다.
  • boundaries_len – 출력 배열의 길이를 기록할 정수형 변수에 대한 포인터입니다.

qf_ferm_op_zero

QfFermionOperator *qf_ferm_op_zero(void)

가법 항등 연산자를 생성합니다.

이 방법으로 생성된 연산자를 다른 연산자에 더해도 아무런 효과가 없습니다.

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));

리턴

생성된 연산자에 대한 포인터.

qf_ferm_op_one

QfFermionOperator *qf_ferm_op_one(void)

곱셈 항등 연산자를 생성합니다.

이 방법으로 생성된 연산자를 다른 연산자와 결합해도 아무런 효과가 없습니다.

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));

리턴

생성된 연산자에 대한 포인터.

qf_ferm_op_has_groups

bool qf_ferm_op_has_groups(const QfFermionOperator *op)

이 연산자가 그룹 인덱스를 추적하는지 여부를 확인합니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

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);

매개변수

  • op – 검사할 페르미온 연산자에 대한 포인터.

리턴

지정된 연산자에 속성이 groups 있는지 여부.

qf_ferm_op_num_groups

uint32_t qf_ferm_op_num_groups(const QfFermionOperator *op)

연산자로부터 그룹 수를 가져옵니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

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);
참고

그룹의 개수는 가장 큰 그룹 인덱스에 1을 더한 값으로 지연 평가됩니다.

매개변수

  • op – 구할 군의 수를 가진 페르미온 연산자에 대한 포인터.

리턴

연산자의 groups 속성에서 파생된 그룹 인덱스의 개수.

qf_ferm_op_group_weights

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

각 그룹의 평균 절대 계수 크기를 구합니다.

i-번째 항은 그룹 의 항들에 대한 abs(coeff) 의 합을 i 해당 그룹의 항 개수로 나눈 값이다. 이는 개별 항이 아닌 전체 그룹을 추출하는 무작위 산출식(예: qDRIFT )의 표본 가중치로, 호출자 측에서 qf_ferm_op_get_coeffs() 와 ( qf_ferm_op_get_groups()* 그룹화되지* 않은 각 항당 하나의 값)을 축소하는 방식이 아니라, 연산자에 대한 단일 통과 과정에서 계산됩니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

 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);
참고

어떤 항도 포함하지 않는 그룹 인덱스의 가중치는 이므로 0.0, 이 인덱스는 표본에서 제외됩니다.

매개변수

  • op – 계산할 군 가중치를 갖는 페르미온 연산자에 대한 포인터.
  • weights_out – 가중치를 기록할 double형 배열을 가리키는 포인터입니다. :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)

모든 연산자 항에 대한 그룹 인덱스를 가져옵니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

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

매개변수

  • op – 그룹 지수를 구할 페르미온 연산자에 대한 포인터.
  • groups_out – 그룹 인덱스를 기록할 정수 배열을 가리키는 포인터.
  • groups_len – 출력 배열의 길이를 저장할 정수형 변수에 대한 포인터입니다.

qf_ferm_op_set_groups

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

지정된 연산자의 groups 속성을 설정합니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

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);

매개변수

  • op – 쓰기 대상 속성을 groups 가진 페르미온 연산자에 대한 포인터.
  • groups_in – 연산자에 쓰기 위한 정수 groups 배열을 가리키는 포인터입니다.
  • groups_lengroups_in 배열에 포함된 용어의 개수.

qf_ferm_op_del_groups

void qf_ferm_op_del_groups(QfFermionOperator *op)

지정된 연산자에서 속성을 groups 삭제합니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

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

매개변수

  • opgroups 속성을 삭제할 페르미온 연산자를 가리키는 포인터.

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)

이 연산자를 해당 속성을 groups 기준으로 새로운 연산자 목록으로 분할합니다.

의 중복 인덱스는 에서 나타나는 횟수만큼 한 번씩 기록됩니다 group_indices``group_ops_out . 전체 그룹 중 극히 일부만 요청하는 것은 모든 그룹을 요청하는 것보다 비용이 훨씬 저렴합니다. 요청되지 않은 그룹에 속한 용어들은 어디에도 추가되지 않고 건너뛰어지기 때문입니다.

관련 참조

그룹 연산자 용어 에 대한 설명: 연산자 구조를 활용하십시오.

 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);

매개변수

  • op – 분리할 groups 페르미온 연산자를 가리키는 포인터.
  • group_indices – 연산자를 생성할 그룹 인덱스 배열에 대한 포인터로, 원하는 출력 순서대로 정렬되어 있어야 합니다. 그럴 수도 있습니다 NULL. 이 경우 모든 그룹은 인덱스 순서대로 생성됩니다(이는 모든 인덱스를 :부터 :c:func:qf_ferm_op_num_groups 까지 0 전달하는 것과 동일합니다 - 1).
  • num_indices – 배열에 group_indices 포함된 인덱스의 개수. 가 일 group_indices 경우 무시됩니다 NULL.
  • group_ops_out – 요청된 각 그룹에 대한 연산자를 기록할 :c:struct:QfFermionOperator 배열을 가리키는 포인터입니다. 의 크기는 가 group_indices 가 아닐 num_indices 때는 로NULL, 일 때는 :c:func:qf_ferm_op_num_groups 로 설정되어야 합니다 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)

기존 연산자에 항을 추가합니다.

포인터 인자 중 어느 것이든, 해당 인자의 길이가 0일 때만 if NULL 가 될 수 있다.

주의

이 함수는 연산자의 속성을 groups 로 재설정합니다 NULL.

 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));

매개변수

  • op – 수정할 페르미온 연산자에 대한 포인터.
  • num_actions – actions 배열의 요소 개수.
  • 액션 – 액션 배열을 가리키는 포인터. 이 배열의 길이는 여야 합니다 num_actions.
  • 모드 – 액션 모드 배열을 가리키는 포인터입니다. 이 배열의 길이는 여야 합니다 num_actions.
  • coeff – 복소 계수에 대한 포인터.

qf_ferm_op_add

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

두 연산자를 더합니다.

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));

매개변수

  • left – left 연산자에 대한 포인터.
  • right – right 연산자에 대한 포인터.

리턴

결과 연산자를 가리키는 포인터.

qf_ferm_op_mul

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

연산자에 스칼라를 곱합니다.

 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));

매개변수

  • op – 연산자를 가리키는 포인터.
  • 스칼라 – 스칼라를 가리키는 포인터.

리턴

결과 연산자를 가리키는 포인터.

qf_ferm_op_compose

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

두 연산자를 서로 결합합니다.

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));

매개변수

  • left – left 연산자에 대한 포인터.
  • right – right 연산자에 대한 포인터.

리턴

결과 연산자를 가리키는 포인터.

qf_ferm_op_adjoint

QfFermionOperator *qf_ferm_op_adjoint(const QfFermionOperator *op)

연산자의 헤르미트 공액(또는 부연산자)을 반환합니다.

이는 항과 계수에 다음과 같은 영향을 미칩니다:

  • 각 항의 작용은 순서가 바뀌며, 생성と소멸 사이를 오간다
  • 계수들은 복소공액 관계에 있다

 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));

매개변수

  • op – 연산자를 가리키는 포인터.

리턴

생성된 연산자에 대한 포인터.

qf_ferm_op_ichop

void qf_ferm_op_ichop(QfFermionOperator *op, double atol)

지정된 임계값보다 작은 계수 크기를 가진 항을 제거합니다.

주의

이 함수는 계수를 탐욕적으로 잘라냅니다! 작동 대상 연산자에 중복 항에 대한 별도의 계수가 포함될 가능성이 있다면, 대신 qf_ferm_op_simplify() 를 호출하는 것을 고려해 보세요!

 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));

매개변수

  • op – 연산자를 가리키는 포인터.
  • atol – 계수 절삭에 대한 절대 허용 오차.

qf_ferm_op_simplify

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

동등하지만 단순화된 연산자를 반환합니다.

단순화 과정에서는 먼저 동일한 항에 속하는 모든 계수를 합산한 다음, 그 합계 계수가 지정된 허용 오차를 초과하는 계수들만 남겨둡니다 (와 마찬가지로 qf_ferm_op_ichop()).

연산자가 산술적으로 변형되거나, 고유한 항을 보장하지 않는 방식으로 구성된 경우, 정보 손실을 방지하기 위해 수치적으로 작은 계수를 걸러내는 어떤 방법을 적용하기 전에 이 방법을 호출해야 합니다. 아래 예시를 보면, 합산 계수의 절대값이 잘려서는 안 되는 값임에도 불구하고, 가 qf_ferm_op_ichop() 어떻게 해당 항들을 잘라내는지 확인할 수 있습니다:

 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);

매개변수

  • op – 단순화할 페르미온 연산자에 대한 포인터.
  • atol – 계수 절삭에 대한 절대 허용 오차.

리턴

동등하지만 단순화된 연산자.

qf_ferm_op_normal_ordered

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

일반 순서를 가진 항을 갖는 등가 연산자를 반환합니다.

연산자 항의 정상 순서는 모든 생성 작용이 모든 소멸 작용보다 먼저 나타나도록 정의된다. 각 그룹 내에서, 작용받는 모드는 사전순으로 정렬됩니다. 순서가 오름차순인지 내림차순인지는 sandwich 인수의 값에 따라 달라집니다:

  • NULL: 두 그룹 모두 사전순으로 내림차순으로 정렬되어 있습니다 (예: +_1 +_0 -_1 -_0)
  • True: 인덱스가 클수록 중앙 쪽으로 위치하며, 즉 생성 작용은 사전순으로 오름차순이고 소멸 작용은 내림차순이다 (예: +_0 +_1 -_1 -_0)
  • False: 중간 쪽으로 갈수록 인덱스가 작아지는데, 즉 생성 연산은 사전순으로 내림차순으로, 소멸 연산은 오름차순으로 정렬되어 있다 (예: +_1 +_0 -_0 -_1)

 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));
참고

항의 순서를 재배열할 때는 반교환 관계( aiaj=δijajaia_i a^\dagger_j = \delta_{ij} - a^\dagger_j a^i )를 고려해야 하며, 이로 인해 항의 개수가 달라질 수 있다.

매개변수

  • op – 연산자를 가리키는 포인터.
  • sandwich – 부울 값을 가리키는 포인터. 이 포인터는 NULL.일 수 있습니다.

리턴

생성된 연산자에 대한 포인터.

qf_ferm_op_is_hermitian

bool qf_ferm_op_is_hermitian(const QfFermionOperator *op, double atol)

연산자가 헤르미트 연산자인지 확인합니다.

 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));
참고

이 검사는 op 와 그 qf_ferm_op_adjoint() 및 의 qf_ferm_op_normal_ordered() 차이에 대해 qf_ferm_op_equiv() 를 사용하여 구현됩니다 qf_ferm_op_zero().

매개변수

  • op – 검사할 페르미온 연산자에 대한 포인터.
  • atol – 계수들이 서로 같다고 간주되는 절대 허용 오차.

리턴

주어진 연산자가 헤르미트 연산자인지 여부.

qf_ferm_op_max_rank

uint32_t qf_ferm_op_max_rank(const QfFermionOperator *op)

연산자의 최대 순위를 확인합니다.

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);
참고

가장 긴 항의 길이는 연산자의 형태에 따라 달라질 수 있으며, 이는 (예를 들어) 연산자 단순화나 정규 순서 지정으로 인해 최대 랭크가 달라질 수 있음을 의미합니다.

매개변수

  • op – 검사할 페르미온 연산자에 대한 포인터.

리턴

연산자의 최대 순위.

qf_ferm_op_conserves_particle_number

bool qf_ferm_op_conserves_particle_number(const QfFermionOperator *op)

연산자가 입자 수 보존성을 갖는지 확인합니다.

 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));

매개변수

  • op – 검사할 페르미온 연산자에 대한 포인터.

리턴

주어진 연산자가 입자 수 보존성을 갖는지 여부.

qf_ferm_op_equal

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

두 연산자의 등가성을 비교합니다.

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));

매개변수

  • left – left 연산자에 대한 포인터.
  • right – right 연산자에 대한 포인터.

리턴

두 연산자가 같은지 여부.

qf_ferm_op_equiv

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

두 연산자가 동치인지 비교하십시오.

이 맥락에서 ‘등가성’이란 지정된 절대 허용오차 범위 내에서 대략적으로 같음을 의미합니다. 더 정확하게 말하면, 이 메서드는 차분 식의 계수들의 절대값이 모두 지정된 임계값 보다 작을 other - selfTrue를 반환합니다 atol.

 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));

매개변수

  • left – left 연산자에 대한 포인터.
  • right – right 연산자에 대한 포인터.
  • atol – 계수 등가성에 대한 절대 허용 오차.

리턴

두 연산자가 서로 동등한지 여부.

qf_ferm_op_len

size_t qf_ferm_op_len(const QfFermionOperator *op)

지정된 연산자의 길이(또는 항의 개수)를 반환합니다.

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);

매개변수

  • op – 페르미온 연산자를 가리키는 포인터.

리턴

연산자의 길이(또는 항의 개수).

qf_ferm_op_relabel_modes

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

지정된 연산자의 인덱스를 다시 지정합니다.

 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);

매개변수

  • op – 페르미온 연산자를 가리키는 포인터.
  • num_modes – 제공된 순열 목록에 포함된 모드 인덱스의 개수.
  • 순열 – 인덱스 순열 목록.

리턴

종료 코드.

  • QfExitCode_Success 성공 시
  • QfExitCode_DuplicateIndexError 순열에서 중복된 인덱스가 발견된 경우
  • QfExitCode_IndexError 무효 인덱스와 같은 기타 인덱스 오류의 경우.
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.