@@ -2385,5 +2385,157 @@ def test_2q_swap_partially_connected_prepost_spectators(self):
23852385 self .assertEqual (dag , expected )
23862386
23872387
2388+ class TestDagCausalCone (QiskitTestCase ):
2389+ """Test `get_causal_node` function"""
2390+
2391+ def test_causal_cone_regular_circuit (self ):
2392+ """Test causal cone with a regular circuit"""
2393+
2394+ # q_0: ───────■─────────────
2395+ # │
2396+ # q_1: ──■────┼───■─────────
2397+ # ┌─┴─┐ │ │
2398+ # q_2: ┤ X ├──┼───┼──■──────
2399+ # └───┘┌─┴─┐ │ │
2400+ # q_3: ─────┤ X ├─┼──┼───■──
2401+ # └───┘ │ │ ┌─┴─┐
2402+ # q_4: ───────────■──■─┤ X ├
2403+ # └───┘
2404+ # c: 5/═════════════════════
2405+
2406+ dag = DAGCircuit ()
2407+ qreg = QuantumRegister (5 )
2408+ creg = ClassicalRegister (5 )
2409+ dag .add_qreg (qreg )
2410+ dag .add_creg (creg )
2411+ dag .apply_operation_back (CXGate (), qreg [[1 , 2 ]], [])
2412+ dag .apply_operation_back (CXGate (), qreg [[0 , 3 ]], [])
2413+ dag .apply_operation_back (CZGate (), qreg [[1 , 4 ]], [])
2414+ dag .apply_operation_back (CZGate (), qreg [[2 , 4 ]], [])
2415+ dag .apply_operation_back (CXGate (), qreg [[3 , 4 ]], [])
2416+
2417+ # Get causal cone of qubit at index 0
2418+ result = dag .quantum_causal_cone (qreg [0 ])
2419+
2420+ # Expected result
2421+ expected = set (qreg [[0 , 3 ]])
2422+ self .assertEqual (result , expected )
2423+
2424+ def test_causal_cone_invalid_qubit (self ):
2425+ """Test causal cone with invalid qubit"""
2426+
2427+ # q_0: ───────■─────────────
2428+ # │
2429+ # q_1: ──■────┼───■─────────
2430+ # ┌─┴─┐ │ │
2431+ # q_2: ┤ X ├──┼───┼──■──────
2432+ # └───┘┌─┴─┐ │ │
2433+ # q_3: ─────┤ X ├─┼──┼───■──
2434+ # └───┘ │ │ ┌─┴─┐
2435+ # q_4: ───────────■──■─┤ X ├
2436+ # └───┘
2437+ # c: 5/═════════════════════
2438+
2439+ dag = DAGCircuit ()
2440+ qreg = QuantumRegister (5 )
2441+ creg = ClassicalRegister (5 )
2442+ dag .add_qreg (qreg )
2443+ dag .add_creg (creg )
2444+ dag .apply_operation_back (CXGate (), qreg [[1 , 2 ]], [])
2445+ dag .apply_operation_back (CXGate (), qreg [[0 , 3 ]], [])
2446+ dag .apply_operation_back (CZGate (), qreg [[1 , 4 ]], [])
2447+ dag .apply_operation_back (CZGate (), qreg [[2 , 4 ]], [])
2448+ dag .apply_operation_back (CXGate (), qreg [[3 , 4 ]], [])
2449+
2450+ # Raise error due to invalid index
2451+ self .assertRaises (DAGCircuitError , dag .quantum_causal_cone , Qubit ())
2452+
2453+ def test_causal_cone_no_neighbor (self ):
2454+ """Test causal cone with no neighbor"""
2455+
2456+ # q_0: ───────────
2457+
2458+ # q_1: ──■───■────
2459+ # ┌─┴─┐ │
2460+ # q_2: ┤ X ├─┼──■─
2461+ # ├───┤ │ │
2462+ # q_3: ┤ X ├─┼──┼─
2463+ # └───┘ │ │
2464+ # q_4: ──────■──■─
2465+
2466+ # c: 5/═══════════
2467+
2468+ dag = DAGCircuit ()
2469+ qreg = QuantumRegister (5 )
2470+ creg = ClassicalRegister (5 )
2471+ dag .add_qreg (qreg )
2472+ dag .add_creg (creg )
2473+ dag .apply_operation_back (CXGate (), qreg [[1 , 2 ]], [])
2474+ dag .apply_operation_back (CZGate (), qreg [[1 , 4 ]], [])
2475+ dag .apply_operation_back (CZGate (), qreg [[2 , 4 ]], [])
2476+ dag .apply_operation_back (XGate (), qreg [[3 ]], [])
2477+
2478+ # Get causal cone of Qubit at index 3.
2479+ result = dag .quantum_causal_cone (qreg [3 ])
2480+ # Expect only a set with Qubit at index 3
2481+ expected = set (qreg [[3 ]])
2482+ self .assertEqual (result , expected )
2483+
2484+ def test_causal_cone_empty_circuit (self ):
2485+ """Test causal cone for circuit with no operations"""
2486+ dag = DAGCircuit ()
2487+ qreg = QuantumRegister (5 )
2488+ creg = ClassicalRegister (5 )
2489+ dag .add_qreg (qreg )
2490+ dag .add_creg (creg )
2491+
2492+ # Get causal cone of qubit at index 4
2493+ result = dag .quantum_causal_cone (qreg [4 ])
2494+ # Expect only a set with Qubit at index 4
2495+ expected = set (qreg [[4 ]])
2496+
2497+ self .assertEqual (result , expected )
2498+
2499+ def test_causal_cone_barriers (self ):
2500+ """Test causal cone for circuit with barriers"""
2501+
2502+ # ┌───┐ ░ ░
2503+ # q1_0: ┤ X ├──■───░───────────────░───────────
2504+ # └───┘┌─┴─┐ ░ ░
2505+ # q1_1: ─────┤ X ├─░───────■───■───░───────────
2506+ # └───┘ ░ ┌───┐ │ │ ░ ┌───┐
2507+ # q1_2: ───────────░─┤ H ├─■───┼───░─┤ Y ├─────
2508+ # ░ └───┘ ┌─┴─┐ ░ └─┬─┘┌───┐
2509+ # q1_3: ───────────░─────────┤ Y ├─░───■──┤ X ├
2510+ # ░ └───┘ ░ └─┬─┘
2511+ # q1_4: ───────────░───────────────░────────■──
2512+ # ░ ░
2513+
2514+ # Build the circuit:
2515+ qreg = QuantumRegister (5 )
2516+ qc = QuantumCircuit (qreg )
2517+ qc .x (0 )
2518+ qc .cx (0 , 1 )
2519+ qc .barrier ()
2520+
2521+ qc .h (2 )
2522+ qc .cz (2 , 1 )
2523+ qc .cy (1 , 3 )
2524+ qc .barrier ()
2525+
2526+ qc .cy (3 , 2 )
2527+ qc .cx (4 , 3 )
2528+
2529+ # Transform into a dag:
2530+ dag = circuit_to_dag (qc )
2531+
2532+ # Compute result:
2533+ result = dag .quantum_causal_cone (qreg [1 ])
2534+ # Expected:
2535+ expected = {qreg [0 ], qreg [1 ], qreg [2 ], qreg [3 ]}
2536+
2537+ self .assertEqual (result , expected )
2538+
2539+
23882540if __name__ == "__main__" :
23892541 unittest .main ()
0 commit comments