Korean
언어
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

참고

이 페이지는 tutorials/simulators/6_extended_stabilizer_tutorial.ipynb 에서 생성되었다.

확장된 스테빌라이저 시뮬레이터

소개

확장 시뮬레이터는 Qiskit-Aer <https://github.com/qiskit/qiskit-aer>》 의 최신 릴리스에서 사용할 수 있는 양자 회로를 고전적으로 시뮬레이트하는 새로운 방법이다.

이 방법은 논문에 발표된 아이디어를 구현한 것이다. Simulation of quantum circuits by low-rank stabilizer decompositions by Bravyi, Browne, Calpin, Campbell, Gosset & Howard, 2018, arXiv:1808.00128.

양자 회로의 다른 표현을 사용하여 고유한 기능을 제공한다. 이 노트북은 확장된 스태빌라이저 메서드가 할 수 있는 몇 가지 예를 제공한다.

예를 들어:

[1]:
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.tools.visualization import plot_histogram

import random
[2]:
circ = QuantumCircuit(40, 40)

# Initialize with a Hadamard layer
circ.h(range(40))
# Apply some random CNOT and T gates
qubit_indices = [i for i in range(40)]
for i in range(10):
    control, target, t = random.sample(qubit_indices, 3)
    circ.cx(control, target)
    circ.t(t)
circ.measure(range(40), range(40))
[2]:
<qiskit.circuit.instructionset.InstructionSet at 0x7fbd18a23310>

우리는 단지 60개의 게이트를 가지고 있고 40개의 큐비트로 동작하는 랜덤 회로를 만들었다. 하지만, 큐비트의 수 때문에, 만약 우리가 이것을 상태벡터 시뮬레이터로 실행하고 싶다면, 여러분이 테라바이트의 RAM을 가지고 있기를 바란다.

[3]:
# Create statevector method simulator
statevector_simulator = AerSimulator(method='statevector')

# Transpile circuit for backend
tcirc = transpile(circ, statevector_simulator)

# Try and run circuit
statevector_result =  statevector_simulator.run(tcirc, shots=1).result()
print('This succeeded?: {}'.format(statevector_result.success))
print('Why not? {}'.format(statevector_result.status))
Simulation failed and returned the following error message:
ERROR:  [Experiment 0] Insufficient memory to run circuit "circuit-2" using the statevector simulator.
This succeeded?: False
Why not? ERROR:  [Experiment 0] Insufficient memory to run circuit "circuit-2" using the statevector simulator.

확장된 스태빌라이저 매서드는 이 회로를 (2분이 걸리긴 하지만!) 잘 처리한다.

[4]:
# Create extended stabilizer method simulator
extended_stabilizer_simulator = AerSimulator(method='extended_stabilizer')

# Transpile circuit for backend
tcirc = transpile(circ, extended_stabilizer_simulator)

extended_stabilizer_result = extended_stabilizer_simulator.run(tcirc, shots=1).result()
print('This succeeded?: {}'.format(extended_stabilizer_result.success))
This succeeded?: True

이게 어떻게 작동하지?

이러한 대형 회로를 정확하게 처리할 수 있는 방법에 관심이 있다면, 자세한 설명을 위해 논문을 읽을 수 있다!

그러나 실행 회로의 경우에는 기본적인 사항을 이해하는 것이 중요하다.

확작된 스태빌라이저 매서드는 두 부분으로 구성된다. 첫 번째는 양자 회로를 stabilizer 회로 로 분해하는 방법인데, 고전적으로 효율적으로 시뮬레이션할 수 있는 회로의 특별한 클래스이다. 두 번째는 이러한 회로를 결합하여 측정을 수행하는 방법이다.

필요한 항 수는 우리가 비클리퍼드(non-Clifford) 게이츠라고 부르는 수의 척도에 따라 조정된다. 현재 이 방법은 다음과 같은 방법을 어떻게 처리하는지 알고 있다.

circ.t(qr[qubit])
circ.tdg(qr[qubit])
circ.ccx(qr[control_1], qr[control_2], qr[target])
circ.u1(rotation_angle, qr[qubit])

또한 시뮬레이터는 최대 63큐비트의 회로를 다룰 수 있다.

주목해야 할 중요한 것 중 하나는 이러한 분해가 대략적인 것이다. 이것은 결과가 상태 벡터 시뮬레이터와 정확히 동일하지 않다는 것을 의미한다.

[5]:
small_circ = QuantumCircuit(2, 2)
small_circ.h(0)
small_circ.cx(0, 1)
small_circ.t(0)
small_circ.measure([0, 1], [0, 1])
# This circuit should give 00 or 11 with equal probability...
expected_results ={'00': 50, '11': 50}
[6]:
tsmall_circ = transpile(small_circ, extended_stabilizer_simulator)
result = extended_stabilizer_simulator.run(
    tsmall_circ, shots=100).result()
counts = result.get_counts(0)
print('100 shots in {}s'.format(result.time_taken))
100 shots in 0.4958779811859131s
[7]:
plot_histogram([expected_results, counts],
               legend=['Expected', 'Extended Stabilizer'])
[7]:
../../_images/tutorials_simulators_6_extended_stabilizer_tutorial_13_0.png

Qiskit Aer에서 extended_stabilizer_approximation_error 를 사용하여 위와 같은 근사 오류를 제어할 수 있다. 초기 설정된 오류 값은 0.05 이다. 오류가 작을수록 결과는 더 정확하지만, 시뮬레이션을 수행하는데 더 오랜 시간이 걸리기 때문에 더 많은 메모리가 필요할 것이다.

[8]:
# Add runtime options for extended stabilizer simulator
opts = {'extended_stabilizer_approximation_error': 0.03}

reduced_error = extended_stabilizer_simulator.run(
    tsmall_circ, shots=100, **opts).result()

reduced_error_counts = reduced_error.get_counts(0)
print('100 shots in {}s'.format(reduced_error.time_taken))
plot_histogram([expected_results, reduced_error_counts],
               legend=['Expected', 'Extended Stabilizer'])
100 shots in 1.404871940612793s
[8]:
../../_images/tutorials_simulators_6_extended_stabilizer_tutorial_15_1.png

시뮬레이터 옵션

확장된 스태빌라이저 방법이 작동하는 방식을 제어하기 위해 조정할 수 있는 몇 가지 다른 옵션이 있다. 이러한 옵션과 그에 대한 설명은 모두 Qiskit Aer 문서에서 확인할 수 있다. 그러나 시뮬레이션을 최적화하는 데 도움이 될 수 있는 두 가지 중요한 사항을 강조하고자 한다.

측정을 수행하기 위해, 확장된 스테빌라이저 방법은 무작위로 결과를 샘플링하기 위해 마르코프 체인 (Markov chain) 방법을 사용한다. 이 마르코프 체인은 샘플링을 시작하기 전에 〈믹싱 시간〉 이라고 부르기도 하고 모든 회로 샷에 대해 다시 혼합해야 한다.

회로 출력이 몇 가지 출력 상태에만 집중될 것으로 예상하는 경우 extended_stabilizer_mixing_time 옵션을 줄임으로써 시뮬레이션을 최적화할 수 있다.

[9]:
print("The circuit above, with 100 shots at precision 0.03 "
      "and default mixing time, needed {}s".format(int(reduced_error.time_taken)))

opts = {
    'extended_stabilizer_approximation_error': 0.03,
    'extended_stabilizer_mixing_time': 100
}

optimized = extended_stabilizer_simulator.run(
    tsmall_circ, shots=100, **opts).result()

print('Dialing down the mixing time, we completed in just {}s'.format(optimized.time_taken))
The circuit above, with 100 shots at precision 0.03 and default mixing time, needed 1s
Dialing down the mixing time, we completed in just 1.4710919857025146s

마찬가지로, 회로가 모든 진폭에 대해 0이 아닌 확률을 갖는 경우 (예를 들어, 이것이 랜덤 회로인 경우), 이 값비싼 재혼합 단계를 회피하여 한 번에 출력으로부터 다수의 샷을 취하는 것을 피할 수 있다. 이는 extended_stabilizer_measure_sampling=True 를 설정함으로써 가능하게 될 수 있다.

예를 들어, 튜토리얼의 시작부터 다음과 같이 100개의 샷을 실행하는 랜덤 회로를 다시 한번 살펴보자.

[10]:
# We set these options here only to make the example run more quickly.
opts = {'extended_stabilizer_mixing_time': 100}

multishot = extended_stabilizer_simulator.run(
    tcirc, shots=100, **opts).result()
print("100 shots took {} s".format(multishot.time_taken))
100 shots took 29.634929895401 s
[11]:
opts = {
    'extended_stabilizer_measure_sampling': True,
    'extended_stabilizer_mixing_time': 100
}

measure_sampling = extended_stabilizer_simulator.run(
    circ, shots=100, **opts).result()
print("With the optimization, 100 shots took {} s".format(result.time_taken))
With the optimization, 100 shots took 0.4958779811859131 s

언제 사용해야 할까?

많은 수의 비클리퍼드(non-Clifford) 게이트로 이루어진 작은 회로들에 대해서는, 상태벡터 방법이 확장된 스테빌라이저보다 좋은 성능을 보일 가능성이 높다. 하지만 고성능 계산이 필요하지 않은 상황에서 많은 큐비트들로 이루어진 회로를 분석하고 싶다면, 이 방법을 시도해 보자!

[12]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
Qiskit0.25.0
Terra0.17.0
Aer0.8.0
Ignis0.6.0
Aqua0.9.0
IBM Q Provider0.12.2
System information
Python3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)]
OSDarwin
CPUs6
Memory (Gb)32.0
Fri Apr 02 12:28:14 2021 EDT

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

[ ]: