근사 양자 컴파일러
qiskit.synthesis.unitary.aqc
논문 [1] 에 기술된 대로 대략적인 양자 컴파일러의 구현.
인터페이스
이 모듈의 기본 공용 인터페이스는 unitary_synthesis_method='aqc' 를 transpile(). 이렇게 하면 합성 방법이 AQCSynthesisPlugin 을 사용하도록 바뀝니다. 개별 클래스는 다음과 같습니다:
AQC( [최적화기, 시드] ) | 근사치 양자 컴파일러의 일반적인 구현입니다. |
ApproximateCircuit(qubit 수[, 이름] ) | 대략적인 회로를 나타내는 베이스 클래스입니다. |
ApproximatingObjective() | 최적화 문제 정의를 위한 베이스 클래스입니다. |
CNOTUnitCircuit(num_qubits, cnots[, tol, name] ) | CNOT 단위 블록을 기반으로 대략적인 회로를 나타내는 클래스입니다. |
CNOTUnitObjective(num_qubits, cnots) | CNOT 단위를 기반으로 하는 문제 정의의 기본 클래스입니다. |
DefaultCNOTUnitObjective(num_qubits, cnots) | CNOT 단위를 기반으로 한 목적 함수의 순진한 구현입니다. |
FastCNOTUnitObjective(num_qubits, cnots) | DefaultCNOTUnitObjective 과 비슷하지만 몇 배 더 빠른 목적 함수 및 기울기 계산기를 구현했습니다. |
수학적 세부 사항
우리는 양자 회로를 컴파일하는 데 관심이 있으며, 이를 몇 가지 추가적인 하드웨어 제약 조건이 있는 대상 단일 행렬( )의 정렬된 게이트 시퀀스 측면에서 최상의 회로 표현을 찾는 것으로 공식화합니다. 특히 하드웨어 연결성 및 게이트 깊이 측면에서 제약이 있을 수 있는 표현을 살펴보고, CNOT 및 회전 게이트 측면에서 게이트 기준을 선택합니다. CNOT와 회전 게이트의 조합은 에서 보편적으로 사용되므로 컴파일을 제한하지 않는다는 점을 기억하세요.
‘최적 회로 표현’이 무엇을 의미하는지 명확히 정의하기 위해, 우리는 이 지표를 컴파일된 회로의 유니터리 행렬 과 목표 유니터리 행렬 사이의 프로베니우스 노름, 즉 으로 정의한다. 이러한 선택은 수학적 프로그래밍적 고려에 근거한 것이며, 문헌에 등장하는 다른 공식화 방식들과도 관련이 있다. 이 문제를 좀 더 자세히 살펴보겠습니다.
을 큐비트 수, 을 큐비트 수라고 합니다. CNOT 구조 와 회전 각도 벡터 가 주어지면 파라메트릭 회로는 행렬 을 형성합니다. 행렬 을 형성하는 목표 회로가 주어지면 다음을 계산하고 싶습니다
여기서 내적 곱은 프로베니우스 내적 곱입니다. 모든 유니타리 및 의 경우 목표 범위는 입니다.
우리의 전략은 다음을 극대화하는 것입니다
그라데이션을 사용합니다. 이제 예시를 통해 구체적인 내용을 살펴보겠습니다.
의 범위는 구조상 의 하위 집합이지만, 대상 회로는 일반적인 단일 행렬을 형성할 수 있습니다. 그러나 ,
따라서 대상 회로를 전역 위상에 따라 정규화한 다음 정규화된 회로를 대략적으로 컴파일해야 합니다. 나중에 글로벌 단계를 다시 추가할 수 있습니다.
알고리즘에서 은 정규화되지 않은 대상 행렬을 나타내고 은 정규화된 대상 행렬을 나타냅니다. 이제 을 얻었으므로, Nesterov의 메서드 최적화 프로그램에 그라데이션 함수를 제공하고 을 계산합니다.
전역 위상을 다시 추가하려면 다음과 같이 제어 회로를 구성할 수 있습니다
논문에서는 Nesterov의 방법을 사용하여 최적화했지만, 이는 수렴을 보장하기 위한 것이지 실제로는 속도를 보장하기 위한 것이 아닙니다. 이 구현에서 기본 옵티마이저로 사용되는 L-BFGS를 사용하는 것이 훨씬 빠릅니다.
AQC 알고리즘의 기본 사용법은 다음 단계로 구성되어야 합니다:
# Define a target circuit as a unitary matrix
unitary = ...
# Define a number of qubits for the algorithm, at least 3 qubits
num_qubits = round(math.log2(unitary.shape[0]))
# Choose a layout of the CNOT structure for the approximate circuit, e.g. ``spin`` for
# a linear layout.
layout = options.get("layout") or "spin"
# Choose a connectivity type, e.g. ``full`` for full connectivity between qubits.
connectivity = options.get("connectivity") or "full"
# Define a targeted depth of the approximate circuit in the number of CNOT units.
depth = int(options.get("depth") or 0)
# Generate a network made of CNOT units
cnots = make_cnot_network(
num_qubits=num_qubits,
network_layout=layout,
connectivity_type=connectivity,
depth=depth
)
# Create an optimizer to be used by AQC
optimizer = partial(scipy.optimize.minimize, method="L-BFGS-B")
# Create an instance
aqc = AQC(optimizer)
# Create a template circuit that will approximate our target circuit
approximate_circuit = CNOTUnitCircuit(num_qubits=num_qubits, cnots=cnots)
# Create an objective that defines our optimization problem
approximating_objective = DefaultCNOTUnitObjective(num_qubits=num_qubits, cnots=cnots)
# Run optimization process to compile the unitary
aqc.compile_unitary(
target_matrix=unitary,
approximate_circuit=approximate_circuit,
approximating_objective=approximating_objective
)이제 approximate_circuit 은 목표 행렬을 어느 정도 근사화하여 원래 행렬 대신 사용할 수 있는 회로입니다.
이것은 도우미 함수를 사용합니다, make_cnot_network.
make_cnot_network
qiskit.synthesis.unitary.aqc.make_cnot_network(num_qubits, network_layout='spin', connectivity_type='full', depth=0)
각각 CNOT 게이트와 일부 단일 큐비트 게이트를 포함하는 빌딩 블록으로 구성된 네트워크를 생성합니다. 이 네트워크는 해당 양자 연산자를 모델링합니다. 각 빌딩 블록에는 한 쌍의 큐비트에 해당하는 2개의 입력과 출력이 있다는 점에 유의하세요. 여기서 실제로 반환되는 것은 모든 빌딩 블록이 연속적으로 공유하는 큐비트 쌍의 인덱스 체인입니다.
매개변수
- num_qubits (int) – 큐비트 수입니다.
- network_layout (str) – 네트워크 지오메트리 유형,
{"sequ", "spin", "cart", "cyclic_spin", "cyclic_line"}. - connectivity_type (str) – 쿼트 간 연결 유형,
{"full", "line", "star"}. - depth (int) – cNOT 네트워크의 깊이, 즉 각 레이어가 단일 CNOT 블록으로 구성된 레이어 수입니다(기본값은
L <= 0입니다).
리턴
Cnot-network의 레이어를 정의하는 크기 (2, N) 행렬로, 여기서 N
는 L 와 같거나 네트워크의 구체적인 유형에 따라 정의됩니다.
레이즈
ValueError - 지원되지 않는 유형의 CNOT 네트워크 레이아웃 또는 큐비트 수 또는 매개변수 조합이 전달된 경우.
리턴 유형
가속화된 버전의 목적 함수를 활용할 수 있습니다. 기본 알고리즘( DefaultCNOTUnitObjective )과 동일한 수학적 알고리즘을 구현하지만 몇 배 더 빠르게 실행됩니다. 가속화된 목적 함수 클래스의 인스턴스화는 기본 사례와 유사합니다:
# 최적화 문제 근사값을 정의하는 목표 생성_objective = FastCNOTUnitObjective(num_qubits=num_qubits, cnots=cnots)
위 예제의 나머지 코드는 변경되지 않습니다.
참조
[1] : 리암 매든, 안드레아 시모네토, 가장 근사한 양자 컴파일 문제.