GroverOperator
class qiskit.circuit.library.GroverOperator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, mcx_mode='noancilla', name='Q')
베이스: QuantumCircuit
Grover 운영자.
그로버의 검색 알고리즘 [1, 2는] 원하는 출력 상태의 진폭을 증폭하는 데 사용되는 소위 그로버 연산자를 반복적으로 적용하는 것으로 구성됩니다. 이 연산자( )는 위상 오라클( ), 제로 위상 편이 또는 제로 반사( ), 입력 상태 준비( )로 구성됩니다:
표준 Grover 검색에는 이 있습니다:
작업은 확산 연산자라고도 합니다. 이 공식에서 Grover의 연산자는 두 단계로 구성되어 있음을 알 수 있습니다. 먼저 위상 오라클이 좋은 상태에 -1 를 곱한 다음( ), 전체 상태를 평균에 반영합니다( ).
이 클래스를 사용하면 양자 진폭 증폭(그로버 알고리즘의 일반화)과 같이 서로 다른 상태 준비 과정을 설정할 수 있습니다. 는 하다마르 게이트의 레이어가 아닐 수도 있습니다. [3].
위상 오라클 의 동작은 다음과 같이 정의됩니다
여기서 상태가 양호하면 , 그렇지 않으면 0입니다. 이 오라클이 좋은 상태의 위상을 뒤집고 결과 큐비트의 상태를 뒤집지 않는다는 사실을 강조하기 위해 을 위상 오라클이라고 부릅니다.
비트플립 오라클에서 위상 오라클을 쉽게 구성하려면 결과 큐비트에 제어된 X 게이트를 X와 H 게이트로 끼워 넣으면 됩니다. 인스턴스
Bitflip oracle Phaseflip oracle
q_0: ──■── q_0: ────────────■────────────
┌─┴─┐ ┌───┐┌───┐┌─┴─┐┌───┐┌───┐
out: ┤ X ├ out: ┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├
└───┘ └───┘└───┘└───┘└───┘└───┘오라클 및 연산자를 정의하는 데 약간의 유연성이 있습니다. 그로버 알고리즘에서 그로버 연산자를 적용하기 전에 먼저 연산자(또는 표준 공식에서는 하다마드 게이트)를 한 번 적용하여 큐비트를 준비합니다. 따라서 항상 형식의 연산이 있습니다. 따라서 비트플립 로직을 으로 옮기고 오라클은 비트플립에 기반한 Z 게이트를 통해 위상 플립만 수행하도록 남겨둘 수 있습니다. 이에 대한 한 가지 가능한 사용 사례는 상태 큐비트의 계산을 해제하지 않는 오라클입니다.
제로 리플렉션 은 일반적으로 다음과 같이 정의됩니다
여기서 은 쿼빗의 ID입니다. 기본적으로 이 클래스는 네거티브 버전 을 구현하는데, 이는 대상 큐비트에 X 게이트로 샌드위치된 다중 제어 Z로 간단히 구현할 수 있고 도입된 글로벌 위상은 Grover의 알고리즘에 중요하지 않기 때문입니다.
예제
>>> from qiskit.circuit import QuantumCircuit
>>> from qiskit.circuit.library import GroverOperator
>>> oracle = QuantumCircuit(2)
>>> oracle.z(0) # good state = first qubit is |1>
>>> grover_op = GroverOperator(oracle, insert_barriers=True)
>>> grover_op.decompose().draw()
┌───┐ ░ ┌───┐ ░ ┌───┐ ┌───┐ ░ ┌───┐
state_0: ┤ Z ├─░─┤ H ├─░─┤ X ├───────■──┤ X ├──────░─┤ H ├
└───┘ ░ ├───┤ ░ ├───┤┌───┐┌─┴─┐├───┤┌───┐ ░ ├───┤
state_1: ──────░─┤ H ├─░─┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├─░─┤ H ├
░ └───┘ ░ └───┘└───┘└───┘└───┘└───┘ ░ └───┘>>> oracle = QuantumCircuit(1)
>>> oracle.z(0) # the qubit state |1> is the good state
>>> state_preparation = QuantumCircuit(1)
>>> state_preparation.ry(0.2, 0) # non-uniform state preparation
>>> grover_op = GroverOperator(oracle, state_preparation)
>>> grover_op.decompose().draw()
┌───┐┌──────────┐┌───┐┌───┐┌───┐┌─────────┐
state_0: ┤ Z ├┤ RY(-0.2) ├┤ X ├┤ Z ├┤ X ├┤ RY(0.2) ├
└───┘└──────────┘└───┘└───┘└───┘└─────────┘>>> oracle = QuantumCircuit(4)
>>> oracle.z(3)
>>> reflection_qubits = [0, 3]
>>> state_preparation = QuantumCircuit(4)
>>> state_preparation.cry(0.1, 0, 3)
>>> state_preparation.ry(0.5, 3)
>>> grover_op = GroverOperator(oracle, state_preparation,
... reflection_qubits=reflection_qubits)
>>> grover_op.decompose().draw()
┌───┐ ┌───┐
state_0: ──────────────────────■──────┤ X ├───────■──┤ X ├──────────■────────────────
│ └───┘ │ └───┘ │
state_1: ──────────────────────┼──────────────────┼─────────────────┼────────────────
│ │ │
state_2: ──────────────────────┼──────────────────┼─────────────────┼────────────────
┌───┐┌──────────┐┌────┴─────┐┌───┐┌───┐┌─┴─┐┌───┐┌───┐┌────┴────┐┌─────────┐
state_3: ┤ Z ├┤ RY(-0.5) ├┤ RY(-0.1) ├┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├┤ RY(0.1) ├┤ RY(0.5) ├
└───┘└──────────┘└──────────┘└───┘└───┘└───┘└───┘└───┘└─────────┘└─────────┘>>> mark_state = Statevector.from_label('011')
>>> diffuse_operator = 2 * DensityMatrix.from_label('000') - Operator.from_label('III')
>>> grover_op = GroverOperator(oracle=mark_state, zero_reflection=diffuse_operator)
>>> grover_op.decompose().draw(fold=70)
┌─────────────────┐ ┌───┐ »
state_0: ┤0 ├──────┤ H ├──────────────────────────»
│ │┌─────┴───┴─────┐ ┌───┐ »
state_1: ┤1 UCRZ(0,pi,0,0) ├┤0 ├─────┤ H ├──────────»
│ ││ UCRZ(pi/2,0) │┌────┴───┴────┐┌───┐»
state_2: ┤2 ├┤1 ├┤ UCRZ(-pi/4) ├┤ H ├»
└─────────────────┘└───────────────┘└─────────────┘└───┘»
« ┌─────────────────┐ ┌───┐
«state_0: ┤0 ├──────┤ H ├─────────────────────────
« │ │┌─────┴───┴─────┐ ┌───┐
«state_1: ┤1 UCRZ(pi,0,0,0) ├┤0 ├────┤ H ├──────────
« │ ││ UCRZ(pi/2,0) │┌───┴───┴────┐┌───┐
«state_2: ┤2 ├┤1 ├┤ UCRZ(pi/4) ├┤ H ├
« └─────────────────┘└───────────────┘└────────────┘└───┘의 grover_operator() 는 동일한 기능을 구현하지만 MCXGate 추상화를 유지하여 컴파일러가 최적의 분해를 선택할 수 있도록 합니다. 성능상의 이유로 grover_operator() 를 사용하는 것이 좋으며, 성능상의 이유로 회로를 불투명 게이트로 감싸지 않습니다.
참조 자료:
[1] L. K. Grover (1996), 데이터베이스 검색을 위한 빠른 양자역학적 알고리즘, arXiv:quant-ph/9605043.
[2] I. Chuang & M. 닐슨, 양자 계산 및 양자 정보, 캠브리지: 캠브리지 대학 출판부, 2000. 장 6.1.2.
[3] 브라사르, G., 호이어, P., 모스카, M., & 태프, A. (2000). 양자 진폭 증폭 및 추정. arXiv:quant-ph/0005055.
qiskit.circuit.library.grover_operator.GroverOperator 클래스는 키스킷 2.1 에서 더 이상 사용되지 않습니다. 키스킷 3.0 에서 제거됩니다. 대신 qiskit.circuit.library.grover_operator 을 사용하세요.
매개변수
- oracle (QuantumCircuit |Statevector) – 불량 상태에 대한 리플렉션을 구현하는 페이즈 오라클. 이 기능은 비트 플립 오라클이 아니라는 점에 유의하십시오. 자세한 내용은 문서 문자열을 참조하십시오.
- state_preparation (QuantumCircuit | None) – 양호 상태와 불량 상태를 준비하는 작업자. 그로버 알고리즘의 경우, 이는 n-큐비트 하다마르 게이트이며, 진폭 증폭 또는 추정 시에는 연산자 가 사용된다.
- zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – 제로 상태에 대한 고찰, .
- reflection_qubits (list[int] | None) – 0 반사 작용이 일어나는 큐비트.
- insert_barriers (bool) – 리플렉션과 A 사이에 장벽을 삽입해야 하는지 여부입니다.
- mcx_mode (str) – 기본 제로 리플렉션을 구축할 때 사용할 모드입니다.
- name (str) – 서킷의 이름입니다.
속성
oracle
나쁜 상태에 대한 리플렉션을 구현하는 오라클입니다.
reflection_qubits
리플렉션 큐비트, S0 이 적용되는 경우( S0 이 사용자가 지정하지 않은 경우).
state_preparation
A 연산자 또는 하다마드를 구현하는 서브회로입니다.
zero_reflection
반사를 약 0으로 구현하는 하위 회로입니다.
name
유형: str
사람이 읽을 수 있는 회로의 이름입니다.
예제
from qiskit import QuantumCircuit
qc = QuantumCircuit(2, 2, name="my_circuit")
print(qc.name)my_circuit