변분 양자 고유값 해법기 (VQE)
이 모듈을 사용하려면 학생은 Python 환경이 작동하고 다음 패키지의 최신 버전이 설치되어 있어야 합니다:
qiskitqiskit_ibm_runtimeqiskit-aerqiskit.visualizationnumpypylatexenc
이러한 패키지를 설정하고 설치하려면 키스킷 설치 가이드를 참조하세요. 실제 양자 컴퓨터에서 작업을 실행하려면 학생은 IBM Cloud 계정 설정 가이드의 단계에 따라 IBM Cloud 계정을 설정해야 합니다.
이 모듈은 약 8분 동안 QPU를 테스트하고 사용했습니다. 이는 추정치이며 실제 사용량은 다를 수 있습니다.
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'소개
20세기 초 양자역학 모델이 개발된 이후 과학자들은 전자가 원자핵 주변의 고정된 경로를 따르는 것이 아니라 궤도라는 확률 영역에 존재한다는 사실을 이해하게 되었습니다. 이러한 궤도는 전자가 점유할 수 있는 특정한 개별 에너지 레벨에 해당합니다. 전자는 자연적으로 가장 낮은 에너지 레벨에 존재하며, 이를 기저 상태라고 합니다. 그러나 전자가 충분한 에너지를 흡수하면 더 높은 에너지 준위로 점프하여 여기 상태로 들어갈 수 있습니다. 이 여기 상태는 일시적이며 전자는 결국 더 낮은 에너지 준위로 돌아가 흡수한 에너지를 빛의 형태로 방출합니다. 에너지 흡수와 방출이라는 기본적인 과정은 원자가 어떻게 상호작용하고 결합을 형성하는지를 이해하는 데 중요합니다.
원자가 모여 분자를 형성할 때 원자 궤도는 결합하여 분자 궤도를 형성합니다. 이러한 분자 궤도 내의 전자의 배열과 에너지 준위는 결과 분자의 특성과 화학 결합의 강도를 결정합니다. 예를 들어, 두 개의 개별 수소 원자로부터 수소 분자( )가 형성될 때 각 원자의 전자는 원자 궤도를 차지합니다. 원자들이 서로 접근함에 따라 이러한 원자 궤도는 겹치고 결합하여 새로운 분자 궤도, 즉 낮은 에너지(결합 궤도)와 높은 에너지(반결합 궤도)를 형성합니다. 각 수소 원자에서 하나씩 나온 두 개의 전자는 에너지가 낮은 결합 궤도를 우선적으로 차지하여 분자를 함께 고정하는 안정적인 공유 결합을 형성합니다. 분리된 원자와 형성된 분자 사이의 에너지 차이, 특히 분자 궤도에 있는 전자의 에너지가 결합의 안정성과 특성을 결정합니다.
다음 섹션에서는 분자를 중심으로 이러한 분자 형성 과정을 살펴봅니다. 이 간단하지만 근본적인 프로세스의 에너지를 찾기 위해 고전적인 최적화 기법과 결합된 실제 양자 컴퓨터를 사용할 것입니다. 이 실험은 양자 계산이 계산 화학의 문제를 해결하는 데 어떻게 적용될 수 있는지에 대한 실질적인 시연을 통해 전자 에너지의 역할에 대한 통찰력을 제공할 것입니다.
VQE - 고유값 문제를 위한 변분 양자 알고리즘
화학 근사 기법 - 변분 원리와 기저 함수 집합
에르빈 슈뢰딩거의 양자역학에 대한 공헌은 새로운 전자 모델을 도입하는 데 그치지 않고, 근본적으로 유명한 시간 의존 슈뢰딩거 방정식을 개발하여 파동 역학을 확립했습니다:
여기서 은 시스템의 총 에너지를 나타내는 해밀턴 연산자이고 은 시스템의 양자 상태에 대한 모든 정보를 담고 있는 파동 함수입니다. (참고: 은 총 시간 도함수이며, 여기에는 에너지 고유값 을 명시적으로 포함하지 않습니다.)
그러나 원자와 분자의 허용 에너지 준위를 결정하는 것과 같은 많은 실제 응용 분야에서는 정지 상태를 가정하여 시간 의존적 형태에서 파생된 시간 독립적 슈뢰딩거 방정식(에너지 고유값 방정식)을 대신 사용합니다. 정지 상태는 공간의 특정 지점에서 입자를 발견할 확률 밀도가 시간에 따라 변하지 않는 양자 상태입니다.
이 형식에서 는 양자 상태 에 해당하는 에너지 고유값을 나타냅니다. 해밀턴은 전자와 핵의 운동 에너지, 전자와 핵 사이의 인력, 전자 사이의 반발력 등 다양한 에너지 기여도를 포함합니다.
에너지 고유값 방정식을 풀면 원자 및 분자 시스템의 양자화된 에너지 레벨을 계산할 수 있습니다. 그러나 분자의 경우 전자의 공간 분포를 설명하는 파동 함수 가 복잡하고 고차원적이기 때문에 이를 정확히 푸는 것은 어렵습니다.
그 결과 과학자들은 실용적이고 정확한 솔루션을 얻기 위해 근사 기법을 사용합니다. 이 작업에서는 두 가지 주요 방법에 초점을 맞출 것입니다:
-
변형 원리
이 방법은 파동 함수를 근사화하여 목표 에너지(일반적으로 시스템의 기저 상태 에너지)에 최대한 근접하도록 조정합니다. 변형 원리의 핵심 아이디어는 간단합니다:
- 파동 함수 ("시험 함수")를 추측하면 이 함수를 통해 계산된 에너지는 항상 시스템의 기저 상태 에너지( )와 같거나 더 높습니다.
- 평가판 함수( )에서 파라미터 를 조정하면 접지 상태 에너지에 대한 더 나은 근사치를 얻을 수 있습니다.
- 정확도는 시험 파동 함수의 선택에 따라 크게 달라집니다 . 시험 함수를 잘못 선택하면 에너지 추정치가 정확하지 않을 수 있습니다.
-
기준 집합 근사치
두 번째 근사화 방법은 파동 함수를 구성하는 단계인 기저 집합 접근법입니다. 양자 화학에서 분자에 대한 슈뢰딩거 방정식을 정확히 푸는 것은 거의 불가능합니다. 대신, 미리 정의된 간단한 수학 함수로 복잡한 다중 전자 파동 함수를 구축하여 근사치를 구합니다. 기저 집합은 본질적으로 이러한 알려진 수학 함수의 모음으로, 일반적으로 분자의 원자를 중심으로 시스템에서 전자의 모양과 동작을 표현하는 빌딩 블록으로 사용됩니다. 표준 레고 브릭 모음만을 사용하여 세밀한 조각품을 재현하는 것과 같다고 생각하세요. 브릭의 종류와 크기가 많을수록(기본 세트가 클수록) 원래 모양에 더 정확하게 근접할 수 있습니다.
이러한 기저 함수는 수소 원자와 같은 단순한 시스템의 분석 솔루션에서 영감을 받은 경우가 많으며, 가우스 또는 슬레이터형 함수와 같은 형태를 취하지만 여전히 근사치입니다. 이론적으로 "정확"하지만 다루기 어려운 전체 분자 궤도를 사용하는 대신 이러한 기저함수의 선형 조합(계수가 포함된 합)으로 표현합니다. 기본 함수가 원자 궤도와 유사한 경우 이 방법을 원자 궤도의 선형 조합(LCAO) 접근법이라고 합니다. 이 선형 조합의 계수를 최적화하면 선택한 기저 집합의 한계 내에서 가능한 가장 근사한 파동 함수와 에너지를 찾을 수 있습니다.
- 기저 집합에 포함된 함수가 많을수록 근사치가 더 좋아지지만, 계산 노력이 더 많이 드는 대신 그 대가가 따릅니다.
- 작은 기초 집합은 대략적인 추정치를 제공하는 반면, 큰 기초 집합은 더 많은 계산 리소스를 필요로 하는 대신 더 정확한 결과를 제공합니다.
요약하자면, 계산을 가능하게 하고 계산 비용을 줄이기 위해 파동 함수를 근사화하여 계산 복잡성을 줄이고 반복적인 최적화를 통해 에너지를 최소화하는 변동 원리를 사용한다는 것입니다. 반면 기저 집합 접근 방식은 연속 파동 함수를 직접 풀지 않고 원자 궤도를 미리 정의된 함수의 조합으로 표현하여 계산을 단순화합니다.
이해도 점검
시험 파동 함수 에서 은 정규화 상수이고 는 조정 가능한 매개변수입니다.
(a) 를 구하여, 가 되도록 시련 파동 함수를 정규화한다.
주어진 시험 파동 함수를 정규화하려면:
가우스 적분을 사용합니다:
를 설정한 다음 get:
(b) 다음 식으로 주어진 해밀토니안 의 기대값을 구하시오. 여기서 이며, 이는 단순 조화 진동자 잠재력에 해당한다.
조화 진동자의 해밀토니안은 다음과 같습니다:
운동 에너지의 기대값
두 번째 도함수를 취합니다:
그러므로 다음이 적용됩니다.
표준 가우스 적분 결과를 사용합니다:
위치 에너지의 기대값
사용 중:
우리는 얻습니다:
총 에너지 기대값
(c) 변분 원리를 이용하여 을 최소화함으로써 최적 해 를 구하라.
최소 에너지화를 위해 최적화
구별
해결:
을 으로 바꾸기 :
는 정확한 양자 고조파 발진기 기저 상태 에너지와 일치합니다.
VQE (변분 양자 고유값 해법기)
가변 양자 아이겐솔버(VQE)는 프로세스를 살펴보는 데 사용할 주요 방법이며, 여기서는 VQE가 무엇이고 어떻게 작동하는지 살펴보겠습니다. 하지만 먼저 잠시 멈춰서 체크인 질문을 통해 매우 중요한 한 가지를 살펴봅시다.
이해도 점검
화학 문제에 대한 전략이 이미 그렇게 많은데 왜 양자 컴퓨터가 필요할까요? 양자 컴퓨터와 기존 컴퓨터를 함께 사용하는 목적은 무엇일까요?
양자 컴퓨팅은 양자 상태의 기하급수적인 확장으로 인해 기존 컴퓨터가 어려움을 겪고 있는 문제를 해결함으로써 화학에 혁명을 일으킬 수 있는 기회를 제공합니다. 리처드 파인만은 자연을 시뮬레이션하려면 계산도 양자 [참조 1이어야] 한다는 유명한 말을 남겼습니다.
예를 들어, 가장 단순한 기저 집합( STO-3G )으로 카페인을 시뮬레이션하려면 관측 가능한 우주의 총 별 수( [ 참조 2] )보다 훨씬 많은 비트가 필요합니다. 양자 컴퓨터는 160개의 큐비트로 카페인의 전자 궤도를 설명할 수 있습니다.
양자 컴퓨터는 중첩과 얽힘을 사용하여 양자 상호작용을 자연스럽게 처리하므로 정확한 분자 시뮬레이션을 가능하게 하는 유망한 방법을 제공합니다. 또한 양자 컴퓨터(전자 시뮬레이션)와 기존 컴퓨터(데이터 전/후처리, 알고리즘 프로세스 관리, 최적화 등)의 장점을 모두 결합할 수 있습니다. 이를 통해 물질 발견, 약물 설계 및 반응 예측을 개선하여 비용이 많이 드는 시행착오 실험을 줄일 수 있을 것으로 기대됩니다. [참조 3][ref 4]
화학 문제에 양자 컴퓨터가 필요한 이유와 양자 및 기존 컴퓨팅 리소스를 모두 사용해야 하는 이유를 알고 싶으시다면 다음 기사를 확인하세요:
이제 VQE로 돌아가 보겠습니다.
VQE는 기본적으로 시스템의 기저 상태 에너지를 얻기 위해 변형 원리를 사용하는 양자 컴퓨터의 성능을 클래식 컴퓨터와 결합합니다. VQE를 이해하려면 먼저 세 부분으로 나눠서 설명합니다:
(양자) 관측량: 분자 해밀토니안(분자의 에너지)
VQE에서 분자/원자 해밀턴은 관측 가능하므로 실험을 통해 그 값을 측정할 수 있습니다. 우리의 목표는 분자의 가능한 가장 낮은 에너지(기저 상태 에너지)를 찾는 것입니다. 이를 위해 매개변수화된 양자 회로(ansatz)로 생성된 시험적 양자 상태를 사용합니다. 관측 가능한 양자 상태를 측정하고 가능한 가장 낮은 에너지에 도달할 때까지 양자 상태를 최적화합니다.
분자 해밀턴에 사용되는 기저 집합은 필요한 큐비트 수를 결정하고 VQE의 정확도에 직접적인 영향을 미칩니다. 올바른 기준 집합을 선택하는 것은 효율성과 정확성의 균형을 맞추는 데 매우 중요합니다. 기저 집합을 변경하지 않고 계산을 단순화하기 위해 대칭성 부과 및 능동적 공간 축소와 같은 전략을 사용할 수 있습니다. 많은 분자는 나비나 눈송이처럼 대칭적인 모양을 가지고 있으며, 이는 일부 부분이 같은 방식으로 작동한다는 의미입니다. 모든 것을 개별적으로 계산하는 대신 고유한 부분에만 집중하여 양자 리소스를 절약함으로써 대칭성을 활용할 수 있습니다. 능동 공간 감소에서는 모든 전자가 분자 에너지에 큰 영향을 미치는 것은 아니므로 중요한 궤도만 고려합니다. 핵에 가까운 전자는 대부분 변하지 않는 반면, 다른 전자는 결합에 영향을 미칩니다. 이러한 방법을 적용하면 정확도를 유지하면서 VQE의 효율성을 높일 수 있습니다.
위의 적절한 기저 집합과 전략을 사용해 분자 해밀턴을 구했다면, 이 해밀턴을 양자 컴퓨터에 적합한 해밀턴으로 변환해야 합니다. 폴리 연산자에게 문제를 매핑하는 것은 매우 복잡할 수 있습니다. 큐비트는 구별할 수 있는 입자(전자)로 작동하는 양자 화학에서는 특히 그렇습니다. 여기서는 매핑에 대한 자세한 내용은 다루지 않겠지만 다음 리소스를 참조하시기 바랍니다. 문제를 양자 연산자에 매핑하는 일반적인 논의는 실제로 양자 컴퓨팅에서 찾을 수 있습니다. 화학 문제를 양자 연산자로 매핑하는 방법에 대한 더 자세한 논의는 VQE를 사용한 양자 화학에서 확인할 수 있습니다.
이 모듈에서는 양자 컴퓨터 사용에 집중할 수 있도록 및 에 적합한 (1-큐비트) 해밀턴을 제공합니다. 이 1 큐비트 해밀턴은 기저 집합과 요르단-위그너 매핑을 사용하여 준비됩니다 STO-6G 기저 집합과 요르단-위그너 매핑을 사용하여 작성되는데, 이는 하나의 스핀 궤도의 점유를 하나의 큐비트의 점유로 매핑하기 때문에 가장 간단한 물리적 해석을 가진 가장 간단한 매핑입니다. 또한, 우리는 해밀토니안의 대칭성을 이용한 큐비트 감소 기법을 사용했는데, 이는 스핀 점유의 행동 패턴을 이용하여 큐비트 수를 줄이는 기법입니다. 분자의 경우 두 수소 원자 사이의 거리가 0.735 이라고 가정합니다.
(양자) 접근법: 시험 파동함수 (양자 회로로 사소한 양자 상태를 구축하는 방법)
VQE의 경우, 안사츠(복수형: ansätze)는 두 가지 주요 구성 요소로 이루어져 있습니다. 첫 번째는 초기 상태 준비로, 변동 매개변수 없이 양자 게이트를 적용해 큐비트의 상태를 설정합니다. 두 번째 구성 요소는 매개변수화된 양자 회로로, 라디오의 다이얼처럼 매개변수를 조정할 수 있는 특수 양자 회로입니다. 이러한 매개변수는 마지막 부분인 클래식 옵티마이저에 사용되어 가능한 최상의 접지 상태에 도달하는 데 도움이 됩니다.
가변 원리 섹션에서는 시험 상태의 품질이 가변 알고리즘의 결과 품질에 영향을 미친다는 것을 배웠습니다. 즉, VQE에서는 좋은 안사츠를 선택하는 것이 중요합니다. 다시 한 번 말하지만, 이것은 풍부하고 복잡한 주제입니다. 여기서는 다양한 유형의 안사츠나 그 기원에 대해서는 다루지 않겠습니다. 매개변수화된 양자 회로와 안자츠에 대해 더 자세히 알고 싶다면, 변분 알고리즘 설계 과정 에서 안자츠와 변분 형식 수업을 살펴보세요. 이 수업에서는 안자츠에 대한 자세한 설명과 예시를 제공합니다.
이 모듈에서는 1큐비트 해밀턴을 사용할 것이므로, 1큐비트 매개변수화된 양자 회로가 답으로 필요합니다. 다음 섹션에서는 세 가지 유형의 1큐비트 분석을 살펴보겠습니다. 이를 비교하고 안사츠를 선택할 때 고려해야 할 주요 사항을 논의해 보겠습니다.
(클래식) 최적화기: 양자 회로 미세 조정
양자 컴퓨터가 앙사츠에서 관측 가능성의 에너지를 측정하면, 앙사츠의 파라미터와 에너지 값은 튜닝을 위해 고전적 최적화 도구로 전송됩니다. 이 최적화 프로세스는 일반적으로 SciPy 과 같은 범용 과학 패키지를 사용하여 클래식 컴퓨터에서 수행됩니다.
기존 최적화 도구는 측정된 에너지를 비용 함수로 취급합니다. 최적화 문제에서 비용 함수(목적 함수라고도 함)는 특정 솔루션이 얼마나 '좋은지'를 측정하는 수학적 함수입니다. 최적화 도구의 목표는 이 비용 함수를 최소화하는 매개변수 집합을 찾는 것입니다. 분자의 기저 상태 에너지를 찾는 맥락에서 에너지 자체가 비용 함수 역할을 하며, 우리는 가능한 가장 낮은 에너지를 산출하는 양자 회로('솔루션')의 파라미터를 찾고자 합니다. 고전적인 최적화 도구는 이 측정된 에너지 값(비용)을 사용하여 양자 연산에 대한 다음 최적화 파라미터 세트를 결정합니다. 이렇게 업데이트된 파라미터는 다시 양자 회로로 전송되며, 이 과정이 반복됩니다. 각 반복마다 클래식 최적화 도구는 미리 정의된 수렴 기준을 충족할 때까지 에너지를 줄이기 위해(비용 함수를 최소화하기 위해) 파라미터를 조정하여 가능한 가장 낮은 에너지(해당 결합 거리 및 기저 집합에 대한 분자의 기저 상태에 해당)를 찾도록 합니다.
SciPy 과 같은 과학적 패키지에서 제공하는 많은 최적화 전략이 있습니다. 자세한 내용은 변형 알고리즘 설계 과정의 최적화 루프 레슨에서 확인할 수 있습니다. 여기서는 복잡한 에너지 환경에 적합한 최적화 알고리즘인 COBYLA(선형 근사법에 의한 제약 최적화)를 사용합니다. 특히 COBYLA는 연구 중인 함수의 기울기를 계산하지 않는데, 이를 기울기 없는 최적화 도구라고 합니다. 눈을 감고 산맥에서 가장 높은 봉우리를 찾으려고 한다고 상상해 보세요. 전체 풍경을 볼 수 없으므로 위쪽인지 아래쪽인지 확인하면서 다른 방향으로 조금씩 발걸음을 옮깁니다. COBYLA는 비슷한 방식으로 작동합니다. 매개변수 공간을 이동하며 다양한 값을 테스트하고 최적의 값을 찾을 때까지 결과를 점진적으로 개선합니다.
이제 VQE 계산을 수행할 준비가 되었습니다. 이를 위해 전체 프로세스를 요약한 아래 체크인 질문을 사용해 보세요.
이해도 점검
빈칸에 올바른 용어를 채워 VQE 절차에 대한 요약을 완성한 후, 클릭하여 정답을 확인하세요.
VQE는 (1) _________와 고전 컴퓨팅의 힘을 결합한 변형 양자 알고리즘으로, 분자의 (2) ________를 찾는 데 사용됩니다. 이 과정은 시스템의 총 에너지를 나타내며 양자 측정에서 관측 가능한 역할을 하는 (3) _________를 정의하는 것으로 시작됩니다. 다음으로, 분자의 시험 파동 함수를 나타내는 파라미터를 조절할 수 있는 (4)____________ 양자 회로인 _____를 준비합니다. 이러한 파라미터는 측정된 에너지를 최소화하기 위해 파라미터를 반복적으로 조정하는 고전적인 알고리즘인 (5) ___________를 사용하여 최적화됩니다. 위의 논의에서는 (6) ___________ 최적화 프로그램을 사용했는데, 이는 파생 계산 없이도 ansatz 파라미터를 구체화하는 최적화 프로그램입니다. 이 과정은 (7) ___________에 도달할 때까지 계속되며, 이는 분자의 가능한 가장 낮은 에너지를 찾았음을 의미합니다.
단어 은행:
- 클래식 옵티마이저
- 접지 상태 에너지
- 하드웨어 효율성
- 답변
- 분자 해밀턴
- COBYLA
- 양자 컴퓨팅
- 수렴
1 → 양자 컴퓨팅
2 → 접지 상태 에너지
3 → 분자 해밀턴
4 → 답변
5 → 클래식 옵티마이저
6 → COBYLA
7 → 융합
VQE를 사용하여 수소 원자의 기저 상태 에너지를 계산하십시오
이제 배운 내용을 사용하여 수소 원자의 기저 상태 에너지를 계산해 보겠습니다. 이 모듈에서는 워크플로우를 다음 단계로 분류하는 "키스킷 패턴"이라는 양자 컴퓨팅 프레임워크를 사용합니다:
- 1단계: 기존 입력을 양자 문제에 매핑하기
- 2단계: 양자 실행을 위한 문제 최적화
- 3단계:
IBM Quantum기본 함수를 사용하여 실행하기 - 4단계: 후처리 및 고전적 분석
일반적으로 다음 단계를 따릅니다.
먼저 IBM Quantum 기본 요소를 포함하여 필요한 패키지들을 불러오는 것부터 시작해 봅시다. 또한 우리가 이용할 수 있는 양자 컴퓨터 중에서 부하가 가장 적은 것을 선정할 것입니다.
처음 사용할 때 자격 증명을 저장하는 코드는 아래에 있습니다. 노트북을 공유할 때 실수로 자격 증명이 공유되지 않도록 노트북을 환경에 저장한 후 이 정보를 노트북에서 삭제해야 합니다. 자세한 안내는 IBM Cloud 계정 설정하기 및 신뢰할 수 없는 환경에서 서비스 초기화를 참조하세요.
# Load IBM Quantum Compute Service
from qiskit_ibm_runtime import QiskitRuntimeService
# Load the Runtime primitive and session
from qiskit_ibm_runtime import EstimatorV2 as Estimator
# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform',
# instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')
# Load saved credentials
service = QiskitRuntimeService()
# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)Output:
ibm_brisbane
아래 셀을 사용하면 노트북 전체에서 시뮬레이터 또는 실제 하드웨어 사용 간에 전환할 수 있습니다. 지금 실행하는 것이 좋습니다:
# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel
# Alternatively, load a fake backend with generic properties and define a simulator.
noise_model = NoiseModel.from_backend(backend)
# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)1단계: 문제를 양자 회로와 연산자로 매핑하기
VQE 계산을 시작하기 위해, 특정 결합 거리에서 수소 분자( )의 해밀토니안을 정의합니다. 이 해밀토니안은 표준 절차를 통해 분자 계로부터 도출 및 매핑된 것으로, 큐비트 연산자를 사용하여 계의 총 에너지를 나타냅니다. 이 절차는 다음과 같습니다: 1) STO-6G 기저 집합(전자 궤도를 근사화하는 데 사용되는 특정 수학적 함수 모음)을 활용하고, 2) 조던-위그너 매핑(전자를 설명하는 페르미온 연산자를 큐비트 연산자로 변환하는 기법)을 적용하고, 3) 문제를 단순화하기 위해 해밀토니안의 패리티를 이용한 큐비트 축소를 수행하는 것이다.
앞서 설명했듯이 계산된 기저 상태 에너지는 기저 집합 선택과 분자 기하학(예: 결합 거리)에 따라 크게 달라집니다. 이 특정 구성과 이러한 변환 후의 결과 큐비트 해밀턴은 간단합니다:
여기서 은 ID 연산자를 나타내고 은 단일 큐비트에서 작동하는 폴리-Z 연산자를 나타냅니다. 계수는 이 특정 결합 거리에서 적절한 변환을 통해 설정된 STO-6G 기저를 사용하여 계산된 적분에서 파생됩니다.
이 해밀턴이 정의되었으므로 이제 VQE를 사용하여 접지 상태 에너지를 계산할 수 있습니다. 계산된 접지 상태 에너지를 예상 값과 비교하는 것이 유용합니다. 고립된 단일 수소 원자(H)의 경우, 기저 상태 에너지는 정확히 -0.5 하트리(상대론적 효과가 없는 경우)입니다. 위에서 정의한 특정 큐비트 해밀턴의 정확한 기저 상태 에너지를 계산하고 이를 알려진 값과 비교해 보겠습니다.
from qiskit.quantum_info import SparsePauliOp
import numpy as np
# Qubit Hamiltonian of the hydrogen atom generated by using STO-3G basis set and parity mapping
Hamiltonian = SparsePauliOp.from_list([("I", -0.2355), ("Z", 0.2355)])
# exact ground state energy of Hamiltonian
A = np.array(Hamiltonian)
eigenvalues, eigenvectors = np.linalg.eig(A)
print(
"The exact ground state energy of the Hamiltonian is ",
min(eigenvalues).real,
"hartree",
)
h = min(eigenvalues.real)Output:
The exact ground state energy of the Hamiltonian is -0.471 hartree
다음으로, 접지 상태에 대한 시험 파동 함수 를 준비하기 위해 파라미터화된 양자 회로인 안사츠가 필요합니다. 목표는 에너지 기대값 을 최소화하는 매개변수 를 찾는 것입니다. 안사츠의 선택은 회로가 준비할 수 있는 가능한 양자 상태의 집합을 결정하기 때문에 매우 중요합니다. "좋은" 안사츠는 우리가 연구하는 해밀턴의 실제 기저 상태에 매우 가까운 상태를 나타낼 수 있을 만큼 유연하지만, 현재 양자 컴퓨터에서 너무 많은 매개변수나 너무 깊은 회로를 필요로 할 정도로 복잡하지는 않은 상태입니다.
여기서는 세 가지 다른 1큐비트 분석을 시도하여 어떤 분석이 단일 큐비트가 있을 수 있는 가능한 양자 상태에 대해 더 나은 "커버리지"를 제공하는지 알아보겠습니다. '커버리지'는 안사츠 회로가 파라미터를 변경하여 생성할 수 있는 양자 상태의 범위를 의미합니다.
단일 큐비트 회전 게이트의 서로 다른 조합을 기반으로 하는 세 가지 분석을 사용하겠습니다:
- 1축 회전 게이트 안식: 이 안식에서는 단일 축을 중심으로만 회전을 사용합니다( ). 블로흐 구체에서 이것은 특정 원을 따라만 이동하는 것에 해당합니다. 이는 유연성이 가장 낮으며 제한된 상태 집합을 다룹니다.
- 두 개의 2축 회전 게이트 안테: 이 안테는 서로 다른 두 축을 중심으로 회전을 결합합니다( 및 ). 이를 통해 단일 축 회전과 비교하여 블로흐 구의 더 많은 부분에 도달할 수 있습니다.
이 세 가지 안사츠로 얻은 VQE 결과를 비교하면 안사츠의 유연성과 상태 공간 커버리지가 단순화된 해밀턴의 실제 기저 상태 에너지를 찾는 능력에 어떤 영향을 미치는지 알 수 있습니다. 보다 유연한 안사츠는 더 나은 근사치를 찾을 가능성이 있지만, 고전적인 최적화 도구로는 더 어려울 수도 있습니다.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import Statevector, DensityMatrix, Pauli
theta = Parameter("θ")
phi = Parameter("φ")
lam = Parameter("λ")
ansatz1 = QuantumCircuit(1)
ansatz1.rx(theta, 0)
ansatz2 = QuantumCircuit(1)
ansatz2.rx(theta, 0)
ansatz2.rz(phi, 0)
ansatz3 = QuantumCircuit(1)
ansatz3.rx(theta, 0)
ansatz3.rz(phi, 0)
ansatz3.rx(lam, 0)Output:
<qiskit.circuit.instructionset.InstructionSet at 0x1059def80>
이제 각 매개변수에 대해 5000개의 난수를 생성하고 이 무작위 매개변수로 세 가지 분석에 의해 생성된 무작위 양자 상태의 분포를 그래프로 그려 보겠습니다. 이러한 매개변수는 구형 표면의 여러 축을 중심으로 회전하는 것과 같다고 생각하면 됩니다. 양자 상태의 분포를 보기 위해 단일 큐비트의 상태를 보여주는 3차원 구체인 블로흐 구(Bloch Sphere) 를 사용하겠습니다. 구의 모든 점은 큐비트의 가능한 상태를 나타내며, 북극과 남극은 고전적인 "0"과 "1"과 같지만 큐비트는 중첩과 같은 특별한 양자 특성을 보여주는 그 사이 어디든 있을 수 있습니다. 먼저 3D 블로흐 구를 그리는 데 필요한 함수를 준비하고 5000개의 무작위 매개 변수를 준비합니다.
import matplotlib.pyplot as plt
def plot_bloch(bloch_vectors):
# Extract X, Y, Z coordinates for 3D projection
X_coords = bloch_vectors[:, 0]
Z_coords = bloch_vectors[:, 2]
# Compute Y coordinates from X and Z to approximate the full Bloch sphere projection
Y_coords = bloch_vectors[:, 1]
# Create 3D plot
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection="3d")
ax.scatter(X_coords, Y_coords, Z_coords, color="blue", alpha=0.6)
# Labels and title
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Parameterized 1-Qubit Circuit on 3D Bloch Sphere")
# Set axis limits and make them equal
ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
# Ensure equal aspect ratio for all axes
ax.set_box_aspect([1, 1, 1]) # Equal scaling for x, y, z axes
# Show grid
ax.grid(True)
plt.show()
num_samples = 5000 # Number of random states
theta_vals = np.random.uniform(0, 2 * np.pi, num_samples)
phi_vals = np.random.uniform(0, 2 * np.pi, num_samples)
lam_vals = np.random.uniform(0, 2 * np.pi, num_samples)첫 번째 안사츠가 어떻게 작동하는지 살펴봅시다.
# List to store Bloch Sphere XZ coordinates
bloch_vectors = []
# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
# Create a circuit and bind parameters
qc = ansatz1
bound_qc = qc.assign_parameters({theta: theta_vals[i]}) # , lam: lam_vals[i]})
state = Statevector.from_instruction(bound_qc)
rho = DensityMatrix(state)
X = rho.expectation_value(Pauli("X")).real
Y = rho.expectation_value(Pauli("Y")).real
Z = rho.expectation_value(Pauli("Z")).real
bloch_vectors.append([X, Y, Z]) # Store X, Z components
# Convert to a numpy array for plotting
bloch_vectors = np.array(bloch_vectors)
plot_bloch(bloch_vectors)Output:
첫 번째 안사츠가 블로흐 구의 고리 모양의 분산 양자 상태를 반환하는 것을 볼 수 있습니다. 이는 안사츠에 회전 매개변수를 하나만 부여했기 때문에 당연한 결과입니다. 따라서 한 축을 중심으로 회전된 상태만 생성할 수 있습니다. 지점에서 시작하여 한 축을 중심으로 회전하면 항상 링이 만들어집니다. 그런 다음 두 개의 직교 회전 게이트가 있는 두 번째 안사츠( Rx 및 Rz)를 확인해 보겠습니다.
bloch_vectors = []
# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
# Create circuit and bind parameters
qc = ansatz2
bound_qc = qc.assign_parameters(
{theta: theta_vals[i], phi: phi_vals[i]}
) # , lam: lam_vals[i]})
state = Statevector.from_instruction(bound_qc)
rho = DensityMatrix(state)
X = rho.expectation_value(Pauli("X")).real
Y = rho.expectation_value(Pauli("Y")).real
Z = rho.expectation_value(Pauli("Z")).real
bloch_vectors.append([X, Y, Z]) # Store X, Z components
# Convert to numpy array for plotting
bloch_vectors = np.array(bloch_vectors)
plot_bloch(bloch_vectors)Output:
여기서 두 번째 안사츠가 블로흐 구의 더 많은 부분을 차지하고 있음을 알 수 있지만, 점이 극 주변에 더 집중되어 있고 적도 주변으로 더 퍼져 있음을 알 수 있습니다. 이제 마지막 궁금증을 확인할 차례입니다.
bloch_vectors = []
# Generate quantum states and extract Bloch vectors
for i in range(num_samples):
# Create circuit and bind parameters
qc = ansatz3
bound_qc = qc.assign_parameters(
{theta: theta_vals[i], phi: phi_vals[i], lam: lam_vals[i]}
)
state = Statevector.from_instruction(bound_qc)
rho = DensityMatrix(state)
X = rho.expectation_value(Pauli("X")).real
Y = rho.expectation_value(Pauli("Y")).real
Z = rho.expectation_value(Pauli("Z")).real
bloch_vectors.append([X, Y, Z]) # Store X, Z components
# Convert to numpy array for plotting
bloch_vectors = np.array(bloch_vectors)
plot_bloch(bloch_vectors)Output:
여기에서 마지막 안사츠에서 생성된 양자 상태가 더 고르게 분포된 것을 볼 수 있습니다.
앞서 언급했듯이 가장 좋은 방법은 찾고자 하는 접지 상태에 대한 지식을 습득하고 해당 접지 상태에 가까운 상태를 조사하는 데 적합한 앤사츠를 사용하는 것입니다. 예를 들어, 접지 상태가 극 근처에 있다는 것을 알고 있다면 ansatz 2를 선택할 수 있습니다. 간단히 설명하기 위해 전체 블로흐 구체를 균일하게 조사하는 ansatz 3을 사용하겠습니다.
이제 안사츠를 선택했으니 회로를 그려보겠습니다.
# Pre-defined ansatz circuit and operator class for Hamiltonian
ansatz = ansatz3
num_params = ansatz.num_parameters
print("This circuit has ", num_params, "parameters")
ansatz.draw("mpl", style="iqp")Output:
This circuit has 3 parameters
2단계: 대상 하드웨어에 최적화하기
실제 양자 컴퓨터에서 계산을 실행할 때는 양자 회로의 로직만 신경 쓰는 것이 아닙니다. 또한 특정 양자 컴퓨터가 어떤 연산을 수행할 수 있는지, 양자 컴퓨터의 큐비트는 어디에 있는지 등에도 관심을 기울입니다. 서로 바로 옆에 있나요? 멀리 떨어져 있나요? 따라서 다음 단계는 우리가 사용할 양자 컴퓨터에 자연스러운 게이트를 사용하고 큐비트 레이아웃을 고려하여 회로를 다시 작성하는 것입니다. transpilation - 이 과정이 끝나면 간단한 안사츠가 다른 게이트 집합으로 변환되고 추상 큐비트가 실제 양자 컴퓨터에서 물리적 큐비트로 매핑되는 것을 볼 수 있습니다.
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
config = backend.configuration()
print("Backend: {config.backend_name}")
print("Native gates: ", config.supported_instructions, ",")
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
ansatz_isa = pm.run(ansatz)
ansatz_isa.draw(output="mpl", idle_wires=False, style="iqp")Output:
Backend: {config.backend_name}
Native gates: ['ecr', 'id', 'delay', 'measure', 'reset', 'rz', 'sx', 'x'] ,
안사츠의 rx, rz 게이트가 백엔드의 기본 게이트인 일련의 rz, sx 게이트로 변환된 것을 볼 수 있습니다. 또한 q0 에서 다섯 번째 물리적 큐비트에 매핑된 것을 확인할 수 있습니다. 또한 다음 코드에서와 같이 이러한 변경 사항에 따라 해밀턴을 매핑해야 합니다:
Hamiltonian_isa = Hamiltonian.apply_layout(layout=ansatz_isa.layout)3단계: 대상 하드웨어에서 실행
이제 실제 QPU에서 VQE를 실행할 차례입니다. 이를 위해서는 먼저 최적화 프로세스를 위한 비용 함수가 필요한데, 이는 안사츠에 의해 생성된 양자 상태를 가진 해밀턴의 기대값을 평가하는 것입니다. 걱정하지 마십시오! 모든 것을 혼자서 코딩할 필요는 없습니다. 이를 위한 함수를 준비했으며, 아래 셀을 실행하기만 하면 됩니다.
def cost_func(params, ansatz, hamiltonian, estimator):
"""Return estimate of energy from estimator
Parameters:
params (ndarray): Array of ansatz parameters
ansatz (QuantumCircuit): Parameterized ansatz circuit
hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
estimator (EstimatorV2): Estimator primitive instance
cost_history_dict: Dictionary for storing intermediate results
Returns:
float: Energy estimate
"""
pub = (ansatz, [hamiltonian], [params])
result = estimator.run(pubs=[pub]).result()
energy = result[0].data.evs[0]
cost_history_dict["iters"] += 1
cost_history_dict["prev_vector"] = params
cost_history_dict["cost_history"].append(energy)
print(f"Iters. done: {cost_history_dict['iters']} [Current cost: {energy}]")
return energy마지막으로, 안사츠와 최적화 프로세스를 위한 초기 파라미터를 준비합니다. 모든 0 또는 임의의 값을 사용할 수 있습니다. 아래에서 초기 매개변수를 선택했지만, 셀의 줄에 주석을 달거나 주석 처리를 해제하여 0에서 까지 균일하게 무작위로 매개변수를 샘플링할 수 있습니다.
# x0 = np.random.uniform(0, 2*pi, 3)
x0 = [1, 1, 0]# QPU Est. 2min for ibm_brisbane
from scipy.optimize import minimize
from qiskit_ibm_runtime import Batch
batch = Batch(backend=backend)
cost_history_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 10000
res = minimize(
cost_func,
x0,
args=(ansatz_isa, Hamiltonian_isa, estimator),
method="cobyla",
options={"maxiter": 10, "tol": 0.01},
)
batch.close()Output:
Iters. done: 1 [Current cost: -0.3361517318448143]
Iters. done: 2 [Current cost: -0.4682546422099432]
Iters. done: 3 [Current cost: -0.38985802144149584]
Iters. done: 4 [Current cost: -0.38319217316749354]
Iters. done: 5 [Current cost: -0.4628720756579032]
Iters. done: 6 [Current cost: -0.4683301936226905]
Iters. done: 7 [Current cost: -0.45480498699294747]
Iters. done: 8 [Current cost: -0.4690533242050814]
Iters. done: 9 [Current cost: -0.465867415110354]
Iters. done: 10 [Current cost: -0.4606882723137227]
h_vqe = res.fun
print("The reference ground state energy is ", min(eigenvalues))
print("The computed ground state energy is ", h_vqe)Output:
The reference ground state energy is (-0.471+0j)
The computed ground state energy is -0.4690533242050814
축하합니다! 첫 번째 양자 화학 실험을 성공적으로 마쳤습니다. 해밀턴의 정확한 기저 상태 에너지와 우리의 기저 상태 에너지 사이에 차이가 있음을 알 수 있지만, 기본 오류 완화 기법(판독 오류를 수정하는 기법)을 사용했기 때문에 그 차이는 미미합니다. 아주 좋은 시작입니다!
참고: 을 사용하여 오류 완화 수준을 설정하면 더 resilience_level나은 결과를 얻을 수 있습니다. 기본값은 1이며, 이보다 큰 값을 설정하면 QPU 사용 시간이 늘어나지만 더 나은 결과를 얻을 수도 있습니다.
4단계: 후처리
이제 클래식 옵티마이저의 작동 방식을 살펴볼 차례입니다. 아래 셀을 실행하여 수렴 패턴을 확인합니다.
fig, ax = plt.subplots()
x = np.linspace(0, 10, 10)
# Define the constant function
y_constant = np.full_like(x, h)
ax.plot(
range(cost_history_dict["iters"]), cost_history_dict["cost_history"], label="VQE"
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
ax.plot(y_constant, label="Target")
plt.legend()
plt.draw()Output:
우리는 상당히 좋은 초기값으로 시작하여 단 10단계 만에 좋은 최종값을 얻었습니다. 크고 작은 봉우리를 볼 수 있으며, 이는 COBYLA 옵티마이저의 대표적인 기능으로, 마치 지형이 보이지 않는 것처럼 공간을 검색하고 측정할 때마다 스텝 크기를 조정합니다.
이해도 점검
어떤 점을 관찰하셨나요? 위의 과정 중 이론 값에 더 가깝거나 해밀턴의 정확한 기저 상태 에너지에 더 가까운 결과를 얻기 위해 개선할 수 있는 부분은 어느 것입니까? 이를 위해 고려해야 할 사항은 무엇인가요?
가장 먼저 고려해야 할 것은 분자의 해밀턴을 계산하는 데 사용되는 염기 집합의 변화입니다. 앞서 언급했듯이 H 원자의 기저 상태 에너지는 잘 알려진 바와 같이 -0.5 하트리이며, 우리가 선택한 STO-6G 기준으로는 이 값을 정확하게 도출하기에 충분하지 않습니다.
더 복잡한 종류의 기저를 선택하면 해밀턴이 사용하는 큐비트 수가 증가하므로 화학 문제에 더 복잡하고 적합한 안사츠를 선택해야 합니다.
다음으로 최적화해야 할 부분은 QPU의 노이즈 관리입니다. 고급 오류 완화 기술은 더 나은 결과를 제공하지만 사용하는 데 시간이 더 오래 걸릴 수 있습니다. 또한
shot_number이 결과에 어떤 영향을 미치는지 고려하세요.마지막으로, 다양한 최적화 도구를 사용해 더 나은 컨버전스 성능을 얻을 수도 있습니다.
VQE를 사용하여 수소 분자의 기저 상태 에너지를 계산하십시오
이제 원자를 사용하여 VQE의 전반적인 과정을 살펴봤으니 이제 분자의 기저 상태 에너지를 더 빠르게 계산해 보겠습니다.
1단계: 문제를 양자 회로와 연산자로 매핑하기
여기에서는 해밀턴의 대칭을 사용하여 큐비트 감소와 함께 STO-6G 기초와 Jordan-Wigner 변환을 사용하는 1큐비트 해밀턴도 제공합니다. 두 수소 원자 사이의 원자 거리는 0.735 을 사용했습니다.
단일 수소 원자의 계산( )과 달리 수소 분자의 기저 상태( )를 계산하려면 전자 궤도와 관련된 에너지 외에도 두 수소 원자의 핵 사이에 작용하는 반발력도 고려해야 합니다. 이 단계에서는 이 값을 상수로 지정하고 실제로 체크인 문제에서 이 값을 계산할 것입니다.
h2_hamiltonian = SparsePauliOp.from_list(
[("I", -1.04886087), ("Z", -0.7967368), ("X", 0.18121804)]
)
# exact ground state energy of hamiltonian
nuclear_repulsion = 0.71997
A = np.array(h2_hamiltonian)
eigenvalues, eigenvectors = np.linalg.eig(A)
print("Electronic ground state energy (Hartree): ", min(eigenvalues).real)
print("Nuclear repulsion energy (Hartree): ", nuclear_repulsion)
print(
"Total ground state energy (Hartree): ", min(eigenvalues).real + nuclear_repulsion
)
h2 = min(eigenvalues).real + nuclear_repulsionOutput:
Electronic ground state energy (Hartree): -1.8659468547627318
Nuclear repulsion energy (Hartree): 0.71997
Total ground state energy (Hartree): -1.1459768547627318
2단계: 대상 하드웨어에 최적화하기
기존 VQE와 해밀턴이 사용하는 큐비트 수는 실행에 사용되는 백엔드와 동일하므로, 기존 안사츠와 그 최적화된 형태를 사용하겠습니다.
h2_hamiltonian_isa = h2_hamiltonian.apply_layout(layout=ansatz_isa.layout)3단계: 대상 하드웨어에서 실행
이제 실제 QPU에 대한 계산을 해볼 차례입니다. 거의 모든 것이 동일하지만 해밀턴에 맞게 적절한 초기점을 사용할 것입니다. 또한 반복적인 부분에서는 QPU에서 해밀턴의 기대치를 계산하는 데 사용되는 Estimator 의 일부 설정이 이전 계산과 약간 다르게 설정됩니다. 이 변경 사항에 대해서는 체크인 질문에서 자세히 설명하겠습니다.
x0 = [2, 0, 0]# QPU time 4min for ibm_brisbane
batch = Batch(backend=backend)
cost_history_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 10000
res = minimize(
cost_func,
x0,
args=(ansatz_isa, h2_hamiltonian_isa, estimator),
method="cobyla",
options={"maxiter": 15},
)
batch.close()Output:
Iters. done: 1 [Current cost: -0.710621837568328]
Iters. done: 2 [Current cost: -0.2603208441168329]
Iters. done: 3 [Current cost: -0.25548711201326424]
Iters. done: 4 [Current cost: -0.581129450619904]
Iters. done: 5 [Current cost: -1.722920997605439]
Iters. done: 6 [Current cost: -1.6633324849371915]
Iters. done: 7 [Current cost: -1.8066989598929164]
Iters. done: 8 [Current cost: -1.8051093803839542]
Iters. done: 9 [Current cost: -1.802692217571555]
Iters. done: 10 [Current cost: -1.8233585485263144]
Iters. done: 11 [Current cost: -1.6904116652617205]
Iters. done: 12 [Current cost: -1.8245120321245392]
Iters. done: 13 [Current cost: -1.6837021361383608]
Iters. done: 14 [Current cost: -1.8166632606115467]
Iters. done: 15 [Current cost: -1.863446212658907]
h2_vqe = res.fun + nuclear_repulsion
print(
"The reference ground state energy is ", min(eigenvalues).real + nuclear_repulsion
)
print("The computed ground state energy is ", h2_vqe)Output:
The reference ground state energy is -1.1459768547627318
The computed ground state energy is -1.143476212658907
VQE는 이론적으로 실제 기저 상태 에너지의 상한을 제공하지만, 실제 또는 잡음이 많은 시뮬레이션 양자 하드웨어에서의 실제 구현과 해밀턴을 준비할 때의 근사치(기저 집합 또는 큐비트 감소 등)는 때때로 정확한 이론 값이나 특정 수치 기준보다 약간 낮은 측정 에너지를 초래하는 오류를 발생시킬 수 있습니다. 약간의 오류는 있지만, 특히 적은 수의 단계를 고려할 때 결과는 만족스러운 것 같습니다. 이제 최적화 도구가 어떻게 작동했는지 살펴봄으로써 이 VQE 계산을 마무리하겠습니다.
4단계: 후처리
fig, ax = plt.subplots()
x = np.linspace(0, 5, 15)
# Define the constant function
y_constant = np.full_like(x, min(eigenvalues))
ax.plot(
range(cost_history_dict["iters"]), cost_history_dict["cost_history"], label="VQE"
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
ax.plot(y_constant, label="Target")
plt.legend()
plt.draw()Output:
이해도 점검
상수 값으로 포함시킨 분자의 핵 반발 에너지를 계산해 보겠습니다( 0.71997 Hartree).
쿨롱의 법칙 과 원자 단위를 사용하여 값을 구하십시오. Hartree
두 수소 핵은 모두 양전하를 띠기 때문에 정전기력으로 인해 서로 밀어냅니다. 이러한 반발력은 쿨롱의 법칙으로 설명할 수 있습니다:
여기서 은 양성자의 전하, 은 진공 투자율, 은 두 핵 사이의 거리(미터 또는 줄(J) 단위의 보어 반경)를 나타냅니다.
이 에너지를 하트리로 계산하려면 위의 방정식을 원자 단위(AU) 시스템으로 변환해야 합니다. AU에서는 , 및 보어 반경( )이 1이며 AU의 기본 길이 척도가 됩니다. 이러한 단순화를 통해 쿨롱의 법칙은 다음과 같이 축소됩니다:
여기서 는 보어 반경으로 측정해야 합니다( ).
에서 주어진 핵 분리를 로 변환하려면 이 변환 관계가 필요합니다:
따라서 은 이 됩니다.
따라서 주어진 의 핵 반발 에너지는 다음과 같습니다
의 반응 에너지를 계산하라
이제 우리가 얻은 것을 사용해보자! 가변 양자 아이겐 솔버인 VQE를 사용하여 원자와 분자의 기저 상태 에너지를 계산했습니다. 남은 것은 계산된 값을 사용하여 프로세스의 반응 에너지를 구하는 것입니다.
반응 에너지는 물질이 반응하여 새로운 물질을 형성할 때 발생하는 에너지 변화입니다. 블록을 쌓는 것처럼 에너지를 투입해야 할 때도 있고, 내리막길에서 굴러가는 공처럼 에너지를 방출해야 할 때도 있습니다. 화학에서 반응은 에너지를 흡수(흡열)하거나 에너지를 방출(발열)합니다.
프로세스의 반응 에너지는 다음 공식으로 계산할 수 있습니다:
아래 셀을 실행하여 이를 시각적으로 확인해 보겠습니다. 여기서는 각 해밀턴의 정확한 기저 상태 값을 사용하고, 정확한 해의 반응 에너지와 VQE 결과를 비교하겠습니다.
# Theoretical values
E_H_theo = h.real
E_H2_theo = h2
# Experimental values
E_H_exp = h_vqe
E_H2_exp = h2_vqe
# Calculate reaction energies
E_reaction_theo = E_H2_theo - (2 * E_H_theo)
E_reaction_exp = E_H2_exp - (2 * E_H_exp)
# Set up the plot
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 3)
ax.set_ylim(-1.16, -0.93) # Adjust y-axis range to highlight differences
ax.set_xticks([])
ax.set_ylabel("Energy (Hartree)")
ax.set_title("H + H → H₂ Reaction Energy Diagram")
# Plot theoretical energy levels
ax.hlines(
y=2 * E_H_theo, xmin=0.5, xmax=1.3, linewidth=2, color="r", label="2H (Exact)"
)
ax.hlines(y=E_H2_theo, xmin=1.3, xmax=2, linewidth=2, color="b", label="H₂ (Exact)")
# Plot experimental energy levels
ax.hlines(
y=2 * E_H_exp,
xmin=0.5,
xmax=1.5,
linewidth=2,
color="r",
linestyle="dashed",
label="2H (VQE)",
)
ax.hlines(
y=E_H2_exp,
xmin=1.5,
xmax=2.5,
linewidth=2,
color="b",
linestyle="dashed",
label="H₂ (VQE)",
)
# Add labels
ax.text(
1,
2 * E_H_theo,
f"2H: {2*E_H_theo:.4f}",
verticalalignment="top",
horizontalalignment="left",
)
ax.text(
2,
E_H2_theo,
f"H₂: {E_H2_theo:.4f}",
verticalalignment="top",
horizontalalignment="left",
)
ax.text(
1,
2 * E_H_exp,
f"2H_VQE: {2*E_H_exp:.4f}",
verticalalignment="bottom",
horizontalalignment="right",
)
ax.text(
2,
E_H2_exp,
f"H₂_VQE: {E_H2_exp:.4f}",
verticalalignment="bottom",
horizontalalignment="right",
)
# Add arrows for reaction energy with ΔE label in the middle
mid_y_theo = (2 * E_H_theo + E_H2_theo) / 2
mid_y_exp = (2 * E_H_exp + E_H2_exp) / 2
ax.annotate(
"",
xy=(1.3, E_H2_theo),
xytext=(1.3, 2 * E_H_theo),
arrowprops=dict(arrowstyle="<->", color="g"),
)
ax.text(
1.35, mid_y_theo, f"ΔE: {E_reaction_theo:.4f}", color="g", verticalalignment="top"
)
ax.annotate(
"",
xy=(1.5, E_H2_exp),
xytext=(1.5, 2 * E_H_exp),
arrowprops=dict(arrowstyle="<->", color="g", linestyle="dashed"),
)
ax.text(
1.55,
mid_y_exp,
f"ΔE_VQE: {E_reaction_exp:.4f}",
color="g",
verticalalignment="center",
)
# Add legend
ax.legend()
plt.show()Output:
그림에서 볼 수 있듯이 약간의 오차가 있지만 해밀턴의 정확한 기저 상태 에너지와 VQE 결과를 사용하여 계산한 반응 에너지는 -0.2 Hartree에 근접할 정도로 유사합니다.
이 과정의 반응 에너지는 음의 값을 가지며, 이는 과정을 통해 에너지가 방출되고 결과 분자는 두 개의 단일 원자보다 낮은 에너지를 갖는다는 것을 의미합니다.
- 결론
지금까지 배운 내용을 요약해 보겠습니다.
먼저 양자 화학 문제를 푸는 데 필요한 두 가지 중요한 근사 기법, 즉 변형 원리와 기저 집합 선택에 대해 살펴봤습니다. 우리는 단순 고조파 발진기의 기저 상태 에너지를 계산하면서 변이 원리를 직접 탐구했습니다.
다음으로, 양자 시스템의 기저 상태 에너지를 계산하는 데 널리 사용되는 알고리즘인 VQE에 대해 살펴보았습니다. 원자 수소( )와 수소 분자( )의 기저 상태 에너지를 계산하는 코드를 실행했습니다. 특히 시스템에 적합한 분자 해밀턴을 구하고 이를 양자 컴퓨터에서 실행 가능한 형태로 변환하는 것이 필요하다는 것을 알게 되었습니다. 또한 VQE 내에서 시험 양자 상태를 준비하기 위해 매개변수화된 양자 회로인 안사츠가 필요하다는 것을 확인했으며, 적절한 안사츠 회로 구조를 선택하는 것의 중요성에 대해 논의했습니다. 또한 VQE는 양자 회로가 가장 낮은 에너지 상태를 찾도록 유도하는 고전적인 컴퓨터를 사용한 반복적인 최적화 프로세스에 의존한다는 사실을 알게 되었고, 그 프로세스가 어떻게 수렴하는지도 확인했습니다.
마지막으로, VQE를 통해 얻은 및 의 계산된 기저 상태 에너지를 사용하여 공정의 반응 에너지를 계산했습니다 .
VQE는 강력한 단기 양자 알고리즘이지만, 그 한계를 인식하는 것이 중요합니다. 더 크고 복잡한 분자의 경우 실제 기저 상태를 정확하게 나타낼 수 있는 효율적으로 준비할 수 있는 안사츠를 찾는 것이 어렵기 때문에 VQE의 성능은 안사츠 선택에 크게 좌우됩니다. 또한, 현재의 양자 하드웨어는 노이즈에 취약하여 특히 더 깊은 회로나 더 많은 수의 큐비트에서 VQE 결과의 정확도에 영향을 미칠 수 있습니다. 이러한 어려움에도 불구하고 VQE는 기본 알고리즘으로 사용되고 있으며, 단기 양자 컴퓨터에서 양자 화학의 한계를 뛰어넘기 위해 보다 정교한 변형 방법과 오류 완화 기술을 모색하는 연구가 진행 중입니다. 예를 들어, 양자 회로에서 얻은 샘플을 하위 공간의 고전적 대각선화와 결합하여 에너지 추정을 개선하고 특히 측정 효율 및 잡음 견고성과 관련하여 VQE가 직면한 일부 한계를 해결하기 위해 샘플 기반 양자 대각선화(SQD)와 같은 알고리즘이 개발되고 있습니다.
검토 및 질문
핵심 개념:
- 가변 양자 알고리즘은 기존 컴퓨터와 양자 컴퓨터가 협력하여 문제를 해결하는 컴퓨팅 패러다임입니다.
- VQE에서는 시스템의 해밀턴으로 시작하여 양자 컴퓨터에서 실행하기 위해 큐비트에 매핑합니다. 매개변수화된 양자 회로인 안사츠를 선택하고 가장 낮은 에너지 값에 도달할 때까지 안사츠의 매개변수를 변화시키며 반복적으로 측정합니다. 매개변수 공간을 통한 검색은 기존 최적화 프로그램을 사용하여 수행됩니다. 좋은 결과를 얻으려면 좋은 안사츠와 적절한 옵티마이저를 선택해야 합니다.
- 반응 에너지는 화학 반응의 총 에너지 변화량으로, 반응물과 생성물의 에너지 차이에 의해 결정됩니다.
true/false
- 변동 원리에 따르면 모든 시험 파동 함수에 대한 에너지의 기대값은 항상 실제 기저 상태 에너지보다 크거나 같아야 합니다.
- 기저 집합은 양자 파동 함수를 근사화하는 데 사용되는 함수의 집합입니다.
- VQE는 주어진 해밀턴에 대한 슈뢰딩거 방정식을 정확히 푸는 데 사용되는 양자 알고리즘입니다.
- VQE에서는 파라미터화된 양자 회로(안사츠)를 사용하여 시험 파동 함수를 준비합니다.
- VQE에서 선택한 최적화 도구(예: COBYLA, SPSA 또는 ADAM)는 결과 품질에 영향을 미치지 않습니다.
- 키스킷의
Estimator은 VQE에서 해밀턴의 기대값을 직접 계산하는 데 사용됩니다.
객관식 문제:
- VQE에서 해밀턴의 목적은 무엇인가요?
- A) 임의의 양자 상태를 생성하려면
- B) 양자 상태의 에너지를 결정하려면
- C) 양자 회로를 최적화하려면
- D) 얽힘을 만들려면
- VQE 알고리즘의 주요 목적은 무엇인가요?
- A) 해밀턴의 기저 상태 에너지 구하기
- B) 큐비트 간 얽힘 생성하기
- C) Grover의 검색을 수행하려면
- D) RSA 암호화를 해제하려면
- 이 노트북에서 안사츠를 비교하기 위해 생성되는 양자 상태는 몇 개인가요?
- A) 100
- B) 1000
- C) 5000
- D) 10,000
- VQE에 클래식 옵티마이저가 필요한 이유는 무엇인가요?
- A) 양자 측정을 수행하려면
- B) 에너지 최소화를 위해 안사츠 매개변수 업데이트
- C) 큐비트 얽히기
- D) 양자 무작위성 생성하기
- 안사츠가 매개변수화되도록 설계된 이유는 무엇인가요?
- A) 양자 상태 준비를 허용하려면
- B) 양자 상태의 넓은 공간을 검색할 수 있도록 하기 위해
- C) 회로 복잡성을 줄이려면
- D) 고유값을 직접 측정하려면
- 다음 중 좋은 안사츠를 선택하는 방법에 대한 가장 올바른 설명은 무엇인가요?
- A) 안사츠는 블로흐 구체에 균등하게 분포된 상태를 생성해야 하며, 그렇지 않으면 실패합니다.
- B) 안사츠는 접지 상태에 가까운 상태를 생성할 수 있도록 시스템에 맞게 조정해야 합니다.
- C) 안사츠는 변형 매개변수를 사용하여 임의의 상태를 생성해야 합니다.
- D) 더 나은 애널리틱스에는 항상 더 많은 가변 매개변수가 있습니다.
(선택 사항) 부록: 가정 복잡도에 따른 최적화기 오버헤드
VQE는 몇 가지 잘 알려진 과제에 직면해 있으며[ [6] ], 다음은 위에서 배운 내용과 관련된 내용입니다.
- 안사츠 선택 과제
올바른 변형 안사츠를 선택하는 데는 내재적인 어려움이 있습니다. 화학에서 영감을 얻은 분석법(예: UCCSD)은 물리적 정확도를 제공하지만 깊은 회로가 필요하고, 하드웨어에서 영감을 얻은 분석법은 회로는 얕지만 물리적 해석 가능성이 부족할 수 있습니다. 또한 많은 분석이 정확도 향상에는 거의 기여하지 않지만 최적화 난이도를 크게 높이는 과도한 변형 매개 변수를 도입합니다.
- 최적화의 어려움
VQE의 최적화 환경에는 기울기가 기하급수적으로 사라지는 영역(불모의 고원)이 있을 수 있어 기존 최적화 도구로는 가변 파라미터를 효율적으로 업데이트하기 어렵습니다. 이를 위해 연구원들은 그라데이션 기반 및 그라데이션이 없는 다양한 유형의 옵티마이저를 사용하려고 시도했지만 둘 다 문제에 직면했습니다. 그래디언트 기반 최적화 도구는 불모지나 다름없고, 그래디언트가 없는 방법은 많은 수의 함수 평가가 필요합니다.
- 옵티마이저 오버헤드
또 하나의 잘 알려진 과제는 문제의 규모와 관련된 최적화 오버헤드입니다. VQE에 필요한 양자 회로는 문제 크기가 커질수록 깊이와 복잡성이 증가하며, 일반적으로 최적화해야 할 매개변수의 수도 증가합니다. 매개변수의 수가 증가함에 따라 최적화 프로세스가 어려워져 수렴이 느려지고 최적의 솔루션을 찾는 데 어려움을 겪게 됩니다.
여기서는 두 가지 유형의 분석과 함께 분자에 대한 VQE를 사용하여 이러한 문제를 살펴보겠습니다.
(참고: 이 작업에는 더 많은 QPU 시간이 소요될 수 있으므로 시간이 충분하지 않은 경우 시뮬레이터를 사용하세요.)
from qiskit.circuit import ParameterVector
num_iter = 4
alpha = ParameterVector("alpha", 3)
beta = ParameterVector("beta", 3 * num_iter)
# step1: Map problem to quantum circuits and operators
hamiltonian = SparsePauliOp.from_list(
[("I", -1.04886087), ("Z", -0.7967368), ("X", 0.18121804)]
)
ansatz_1 = ansatz3
ansatz_2 = QuantumCircuit(1)
for i in range(num_iter):
ansatz_2.rx(beta[i * 3 + 0], 0)
ansatz_2.rz(beta[i * 3 + 1], 0)
ansatz_2.rx(beta[i * 3 + 2], 0)ansatz_1.draw("mpl")Output:
ansatz_2.draw("mpl")Output:
# Step 2: Optimize for target hardware
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
ansatz_isa_1 = pm.run(ansatz_1)
ansatz_isa_2 = pm.run(ansatz_2)
hamiltonian_isa_1 = hamiltonian.apply_layout(layout=ansatz_isa_1.layout)
hamiltonian_isa_2 = hamiltonian.apply_layout(layout=ansatz_isa_2.layout)이제 모든 점을 초기점으로 하여 최대 20단계의 VQE를 실행하고 두 실행의 수렴을 비교해 보겠습니다.
# QPU time 3m 40s for ibm_brisbane
# Step 3: Execute on target hardware
from scipy.optimize import minimize
x0 = np.ones(ansatz_1.num_parameters)
batch = Batch(backend=backend)
cost_history_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 2048
res = minimize(
cost_func,
x0,
args=(ansatz_isa_1, hamiltonian_isa_1, estimator),
method="cobyla",
options={"maxiter": 20},
)
batch.close()Output:
Iters. done: 1 [Current cost: -0.8782202668652658]
Iters. done: 2 [Current cost: -0.43473160695469165]
Iters. done: 3 [Current cost: -0.4076372093159749]
Iters. done: 4 [Current cost: -1.3587839859772106]
Iters. done: 5 [Current cost: -1.774529906754082]
Iters. done: 6 [Current cost: -1.541934983115727]
Iters. done: 7 [Current cost: -1.2732403113465345]
Iters. done: 8 [Current cost: -1.820842221085785]
Iters. done: 9 [Current cost: -1.8065762857059005]
Iters. done: 10 [Current cost: -1.8126394095981146]
Iters. done: 11 [Current cost: -1.8205831886180421]
Iters. done: 12 [Current cost: -1.8086715778994924]
Iters. done: 13 [Current cost: -1.8307676638629322]
Iters. done: 14 [Current cost: -1.8177328827556327]
Iters. done: 15 [Current cost: -1.8179426218088064]
Iters. done: 16 [Current cost: -1.8109239667991088]
Iters. done: 17 [Current cost: -1.824271872489647]
Iters. done: 18 [Current cost: -1.813167587671394]
Iters. done: 19 [Current cost: -1.824647343397313]
Iters. done: 20 [Current cost: -1.8219785311686143]
# Save Cost_history as a new list
ansatz_1_history = cost_history_dict["cost_history"]# QPU time 3m 40s for ibm_brisbane
x0 = np.ones(ansatz_2.num_parameters)
batch = Batch(backend=backend)
cost_history_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
}
estimator = Estimator(mode=batch)
estimator.options.default_shots = 2048
res = minimize(
cost_func,
x0,
args=(ansatz_isa_2, hamiltonian_isa_2, estimator),
method="cobyla",
options={"maxiter": 20},
)
batch.close()Output:
Iters. done: 1 [Current cost: -0.738191173881188]
Iters. done: 2 [Current cost: -0.42636037194506304]
Iters. done: 3 [Current cost: -1.3503788613797374]
Iters. done: 4 [Current cost: -0.9109204349776897]
Iters. done: 5 [Current cost: -0.9060873157510835]
Iters. done: 6 [Current cost: -0.7735065414083984]
Iters. done: 7 [Current cost: -1.586889197437709]
Iters. done: 8 [Current cost: -1.659215191584943]
Iters. done: 9 [Current cost: -1.245445981794618]
Iters. done: 10 [Current cost: -1.1608385766138023]
Iters. done: 11 [Current cost: -1.1551733876027737]
Iters. done: 12 [Current cost: -1.8143337768286332]
Iters. done: 13 [Current cost: -1.2510951563756598]
Iters. done: 14 [Current cost: -1.6918311531865413]
Iters. done: 15 [Current cost: -1.8163783305531838]
Iters. done: 16 [Current cost: -1.8434877732947152]
Iters. done: 17 [Current cost: -1.8461898233304472]
Iters. done: 18 [Current cost: -1.0346471214915485]
Iters. done: 19 [Current cost: -1.8322518854150687]
Iters. done: 20 [Current cost: -1.717144678705999]
ansatz_2_history = cost_history_dict["cost_history"]fig, ax = plt.subplots()
# Define the constant function)
ax.plot(
range(cost_history_dict["iters"]),
ansatz_1_history,
label="Ansatz with 3 parameters",
)
ax.plot(
range(cost_history_dict["iters"]),
ansatz_2_history,
label="Ansatz with 12 parameters",
)
ax.set_xlabel("Iterations")
ax.set_ylabel("Cost (Hartree)")
plt.legend()
plt.draw()Output:
위의 그래프를 보면 변수가 많을수록 안정적인 수렴에 도달하는 데 더 많은 시간이 소요된다는 것을 알 수 있습니다.
단순한 단일 큐비트 회로와 간단한 분석에 의존하기보다는 더 큰 양자 회로와 더 복잡한 구조의 분석이 필요할 때 최적화의 복잡성이 증가합니다. 이는 VQE에서 잘 알려진 문제인 옵티마이저의 오버헤드를 강조합니다.
연구자들은 화학 문제에 양자 컴퓨터를 활용할 수 있는 다양한 첨단 방법론을 지속적으로 개발하고 있다. 다양한 교육 자료를 에서 이용할 수 IBM Quantum Learning 있습니다.
참조
- [ 참고 1 ] Richard P. Feynman, 컴퓨터를 이용한 물리학 시뮬레이션, 국제 이론 물리학 저널, 1982.
- [참고 2] Marov, M.Y. (2015). 우주의 구조. In: 현대 천체 물리학의 기초. 스프링거, 뉴욕, 뉴욕.
- [ 참고 3 ] 양자 컴퓨팅으로 어려운 화학 공학 문제를 해결하는 방법, IBM 연구 블로그, 2023.
- [참고 4 ] Y. 카오, J. 로메로와 A. Aspuru-Guzik, "신약 개발을 위한 양자 컴퓨팅의 잠재력", IBM Journal of Research and Development, 62권 6호, 6:1-6:20, 1 Nov.-Dec
- [참고 5 ] 분자 구조 계산의 현재 상태, REv. Mod. 실제 32, 170, 1960
- [참고 6 ] Fedorov, D.A.., Peng, B., Govind, N. et al. VQE 방법: 간단한 설문조사 및 최근 개발 사항. 물질 이론 6, 2 (2022)