이 패키지가 ffsim과 어떤 관련이 있는지
이 가이드에 소개된 개념은 Python API에서만 사용할 수 있습니다.
ffsim과 이 패키지는 중복되지 않고, 하나의 선을 따라 작업을 분담합니다:
ffsim은 ~을(를) 소유하고 있다 | qiskit-fermions 소유 |
|---|---|
결합 클러스터 진폭이나 매개변수 벡터로 구성된 고차원 안자츠 연산자 (UCJOpSpinBalanced, UCCSDOpRestrictedReal 및 그 계열들) | 페르미온 회로 (FermionicCircuit)에서 해당 연산자들이 어떻게 변환되는지, 그리고 임의의 페르미온-큐비트 인코딩 방식에 따른 큐비트 회로로의 변환 과정 |
| 콤팩트한 고정 입자 수 공간에서의 고속 시뮬레이션 | 회로를 구성하는 매퍼 프레임워크와 연산자 데이터 구조 |
그 실질적인 결과는 양방향으로 나타납니다. ansatz 수학은 ffsim에 구현되어 있으므로, UCJ 와 는 ffsim 연산자를 직접 입력으로 받습니다 UCC . 반대로, ffsim 고유의 Qiskit 게이트는 조던-위그너 변환에 특화되어 있으므로, 다른 인코딩 방식을 통해 ansatz 연산자 중 하나를 단순화하는 것이 바로 이 방식을 도입함으로써 얻을 수 있는 이점입니다.
시뮬레이션은 이 두 가지가 만나는 지점이며, 이 가이드에서는 그 방법을 설명합니다. ffsim은 이 패키지의 시뮬레이션 백엔드로, 래퍼를 통하지 않고 자체 프로토콜을 통해 접근됩니다. SKQD 가이드에서는 변환 단계 없이 FermionicCircuit객체와 FermionOperator객체에 대해 ffsim.apply_unitary(), ffsim.linear_operator(), 및 를 직접 ffsim.sample_state_vector() 호출합니다.
ffsim의 시뮬레이션 인터페이스에 연결하기
ffsim은 페르미온 양자 회로를 위한 고성능 시뮬레이터로, 입자 수와 스핀-Z 보존 법칙을 활용하여 일반적인 차원 큐비트 상태 벡터보다 더 간결하게 상태 벡터를 표현합니다. 이 패키지는 모든 객체가 시뮬레이션 메커니즘에 참여하기 위해 구현할 수 있는 프로토콜을 정의합니다(동일한 설계 방식을 따르는 이 패키지 고유의 프로토콜에 대해서는 qiskit_fermions.protocols 다음을 참조하십시오):
ffsim.SupportsApplyUnitary, 해당 방법을 통해_apply_unitary_(vec, norb, nelec, copy), 고정된 입자 수를 갖는 상태 벡터에 해당 객체를 유니터리로 적용함으로써ffsim.SupportsLinearOperator, 해당 방법을 통해_linear_operator_(norb, nelec), 동일한 섹터에 있는 객체의scipy.sparse.linalg.LinearOperator뷰를 반환합니다ffsim.SupportsTrace, 해당 방법을 통해_trace_(norb, nelec), 해당 섹터에 대한 객체의 트레이스를 반환합니다.
이 패키지는 해당 인터페이스를 구현합니다. 의 모든 페르미온 게이트는 를 제공하며 qiskit_fermions.circuit.library_apply_unitary_ , 는 와 _linear_operator_ 를 제공합니다 FermionOperator_trace_ . 바로 이 점 덕분에 이 패키지의 연산자와 회로가 ffsim과 호환되 므로, 해당 도구를 별도의 변환 단계 없이 바로 사용할 수 있습니다. ffsim.apply_unitary() FermionicCircuit end-to-end 시뮬레이션이 가능하며, 대각화할 ffsim.linear_operator() 수 있고 FermionOperator, ( SKQD 가이드에서 시뮬레이션된 상태 벡터를 측정 횟수로 변환하는 데 사용되는) ffsim.sample_state_vector() 과 같은 샘플링 유틸리티는 수정 없이 바로 사용할 수 있습니다.
반환되는 _linear_operator_ 값은 일반적인 SciPy 이므로 LinearOperator, 및 scipy.sparse.linalg.eigsh() 관련 함수들도 이 객체에 대해 작동합니다.
>>> import ffsim
>>> import numpy as np
>>>
>>> from qiskit_fermions.circuit import FermionicCircuit
>>> from qiskit_fermions.circuit.library import Evolution
>>> from qiskit_fermions.operators import FermionOperator, ann, cre
>>>
>>> norb, nelec = 2, (1, 1)
>>> hamiltonian = FermionOperator.from_terms([
... ([cre(0), ann(1)], 0.5),
... ([cre(1), ann(0)], 0.5),
... ])
>>>
>>> circuit = FermionicCircuit(2 * norb)
>>> circuit.append(Evolution(2 * norb, hamiltonian, time=1.0), circuit.modes)
>>>
>>> reference = ffsim.hartree_fock_state(norb, nelec)
>>> state = ffsim.apply_unitary(reference, circuit, norb=norb, nelec=nelec) # native ffsim callffsim의 프로토콜을 통한 연동 덕분에 이러한 이점이 실현됩니다. 활발히 개발되고 있는 시뮬레이션 및 샘플링 유틸리티 생태계가 이 패키지의 회로와 연산자에 그대로 적용되며, 이미 ffsim을 사용하고 있는 사용자는 별도의 시뮬레이션 API를 새로 익히지 않고도 이 패키지의 게이트와 연산자를 혼합하여 사용할 수 있습니다.
ffsim은 선택적 종속성입니다
ffsim은 선택적 추가 요소(pip install "qiskit-fermions[ffsim]", 또는 전이적으로 [all])로 선언되며, ( HAS_FFSIM 위에서 보여준 바와 같이) 런타임 시 에 의해 보호됩니다. 이 패키지를 설치하면 시뮬레이션 기능이 활성화됩니다. ffsim.SupportsLinearOperator 와 는 이 패키지의 를 로 FermionOperator 변환하여 구현되므로 ffsim.SupportsTraceffsim.FermionOperator , ffsim이 없으면 오류가 발생합니다 MissingOptionalLibraryError. 시뮬레이션과 관련이 없는 모든 작업(빌딩 연산자, 연산자 매핑, 그리고 결과 회로의 트랜스파일링)에는 이 모든 것이 전혀 필요하지 않습니다.
ffsim은 PySCF 에 전이적으로 의존하는데, PySCF는 Windows를 지원하지 않기 때문에 Windows에서는 설치 실패가 발생하기보다는 extra가 아무 작업도 수행하지 않는 상태( sys_platform 마커를 통한 무음 no-op)로 처리됩니다. 시뮬레이션을 원하는 Windows 사용자는 당분간 ‘ Linux 용 Windows 서브시스템(WSS) ’을 통해 시뮬레이션을 수행할 수 있습니다.
페르미온 시뮬레이션은 고정된 입자 수 영역에서 이루어진다
와 _apply_unitary_ 모두 nelec 인수를 _linear_operator_ 취하며, 해당 (norb, nelec) 섹터에 대한 고정 입자 수 행렬식 기저를 기반으로 한 상태 벡터를 나타냅니다. 이는 일반적인 큐비트 시뮬레이터가 사용하는 전체 차원 공간이 아닌, ffsim(그리고 전이적으로 PySCF’s )의 FCI 공간 설정을 반영한 것입니다. 이 공간은 훨씬 더 작지만(그 크기는 2의 거듭제곱이 아니라 이항계수의 곱으로 표현된다), 엄격한 제약 조건이 따릅니다. 입자 수(스핀이 존재하는 경우, 각 스핀 종류의 입자 수를 개별적으로 포함)를 보존하는 연산자와 게이트만이 이 체계에서 표현될 수 있다. 진폭을 다른 입자 번호로 이동시키는 연산자는 그 진폭을 둘 곳이 없습니다.
ffsim은 이러한 연산자를 아예 거부함으로써 이 문제를 해결합니다. 즉, 해당 연산자를 선형 연산자로 변환하면 어떤 보존 법칙이 성립하지 ValueError 않는다는 오류가 발생합니다. 그것이 올바른 기본 설정입니다. 왜냐하면, 입자 보존 항이 포함되지 않은 해밀토니안 에 를 적용할 경우, 본래 유니터리였을 법한 매핑이 비유니터리이며 물리적으로 무의미한 매핑으로 변해버리기 때문입니다.
Evolution운영자로부터 거절당하는 상황이 발생하면, 그 상황은 점차 발전해 나간다.OrbitalRotation스핀이 존재하는 경우, (내장된) 회전 행렬이 알파/베타 분할에 따라 블록 대각 행렬인지 확인하고, 스핀 영역이 혼합되어ValueError있으면 예외를 발생시킵니다.
>>> from qiskit_fermions.circuit.library import Evolution
>>>
>>> non_conserving = FermionOperator.from_terms([([cre(0), cre(1)], 1.0)]) # creates 2 particles
>>> gate = Evolution(2 * norb, non_conserving, time=1.0)
>>>
>>> try:
... gate._apply_unitary_(reference, norb, nelec, copy=True)
... except ValueError as exc:
... print("rejected:", exc)
rejected: The given FermionOperator could not be converted to a LinearOperator because it does not conserve particle number and the z component of spin. Conserves particle number: False Conserves spin z: False따라서 고정 부문 표현의 구조상, 페르미온 공간에서는 입자 보존을 보장하지 않는 시뮬레이션이 불가능하며, 이것이 바로 페르미온 시뮬레이션을 애초에 가능하게 만든 콤팩트 FCI 공간의 대가이다. 알고리즘에 입자 수 위반 연산자(예: 큐비트 고유 오류 채널이나, 항별로 입자 수를 보존하지 않는 매핑된 해밀토니안을 위해 구축된 연산자 등)가 필요한 경우, 먼저 큐비트로 변환한 다음 큐비트 수준 시뮬레이터를 사용하여 QuantumCircuit 그 결과를 시뮬레이션하십시오. 이 경우에는 어떤 트랜스필레이션 경로라도 사용할 수 있습니다. 페르미온 회로 및 트랜스필레이션 안내서에서 더 자세히 다루고 있지만, 는 합리적인 기본 선택지입니다 generate_preset_jw_pass_manager() .
스핀을 갖는계에 대한 블록-스핀 규칙
nelec 이 값이 입력되며 int | tuple[int, int], 별도의 플래그가 아닌 이 값의 유형에 따라 지원되는 모드 레이아웃 중 하나가 선택됩니다:
- int 는 스핀이 없는 해석을 선택합니다. 이
norb모드들은 스핀이 없는 궤도로 직접 취급되며, 는 총 입자 수이다nelec. - 한 쌍은 고정된 블록-스핀 관례 하에서
2 * norb모드의 스핀 기반 해석을(n_alpha, n_beta)선택한다. 모드 는 알파(스핀 업) 궤도이며0 .. norb, 모드 는 베타(스핀 다운) 궤도이다norb .. 2 * norb. 각 스핀 종은 독립적으로 보존됩니다. 알파 전용 항은 전자를 알파 모드 간에 이동시킬 수는 있지만, 베타 모드로 이동시킬 수는 없으며, 그 반대의 경우도 마찬가지입니다.
이 디스패치는 이 패키지의 모든 ffsim-protocol 진입점(게이트 생성자, _apply_unitary_placed_ 구현체, 그리고 네이티브 Rust 커널의 섹터 컴파일)에서 발생하며, 이는 LUCJ 및 SKQD 가이드 전반에 걸쳐 사용되는 관례입니다(예를 들어, 알파 점유는 모드에 0 .. n_alpha , 베타 점유는 모드에 InitializeModes.from_hartree_fock() 채워집니다 norb .. norb + n_beta). 이는 본질적인 스핀 의미론이 없는 일반 모드 인덱스를 사용하는 모듈 qiskit_fermions.operators 및 일반적인 FermionicCircuit 경우와 대조해 볼 가치가 있습니다( 페르미온 회로 가이드 참조). 블록 스핀의 의미는 시뮬레이션 호출에 스핀이 포함된 값이 전달될 nelec 때만 부여되며, 연산자나 회로 표현 자체에 내재되어 있는 것은 아닙니다.
>>> from qiskit_fermions.circuit.library import InitializeModes
>>>
>>> norb, nelec = 3, (2, 1)
>>> init = InitializeModes.from_hartree_fock(norb, nelec)
>>> print([bool(occ) for occ in init.occupation]) # alpha modes 0,1; beta mode 3 (= norb + 0)
[True, True, False, True, False, False]다음 단계
-
SKQD 가이드를 살펴보시면, 이 패키지의 게이트로 구성된 회로를 시뮬레이션하기 위해 와
ffsim.apply_unitary()가 함께 사용되는ffsim.sample_state_vector()방식과, 를 통해 해밀토니안의 기대값을 평가하는 방법(ffsim.linear_operator()이 방법은 본 문서에서 설명한 것과 동일한 프로토콜_linear_operator_방식을 기반으로 합니다)을 확인하실 수 있습니다. -
이야기의 나머지 절반, 즉 ffsim ansatz 연산자를 이 패키지의 트랜스파일레이션 파이프라인을 거쳐 장치 결합 맵으로 전달하는 과정을 LUCJ 가이드를 통해 살펴보세요.
-
시뮬레이션 호출 외부에서 사용되는, 스핀에 구애받지 않는 일반적인 모드 인덱싱에 대해서는 페르미온 회로 가이드를 참조하십시오.
-
페르미온 공간을 떠나는 방법에 대해서는 변환 가이드를 참고하세요
그리고 큐비트에서 시뮬레이션을 수행하는데, 이는 비입자 보존 연산자에 필수적이다.
-
이 패키지에서 정의하는 프로토콜의 전체 목록을 살펴보세요
qiskit_fermions.protocols. 여기에는 ffsim과 관련이 없는 변환 프로토콜(SupportsFermionOperator,SupportsMajoranaOperator)도 포함됩니다. -
ffsim이 제공하는 워크플로우에 대해서는 ffsim의 가이드를 참고하시기 바랍니다. 특히 UCJ 안자츠를 구축하고 변분법을 통해 이를 최적화하는 방법에 대해 자세히 알아보세요. 해당 가이드가 제어하는 매개변수 벡터는
UCJ와 가, 이들이 구성하는 연산자를 통해 받아들이는UCC값입니다.