Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
phase31_channel_invariants.py
Go to the documentation of this file.
1 """Kraus-bundle invariant metrics for Phase 3.1 strict microcase correctness records."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 import numpy as np
8 
9 from squander.partitioning.noisy_runtime import PHASE31_RUNTIME_PATH_CHANNEL_NATIVE
10 from squander.partitioning.noisy_runtime_channel_native import (
11  _compose_kraus_bundles,
12  _identity_kraus_bundle_for_support_qubit_count,
13  _member_to_kraus_bundle,
14 )
15 from squander.partitioning.noisy_runtime_core import (
16  _build_partition_parameter_vector,
17  _segment_parameter_vector,
18 )
19 from squander.partitioning.noisy_types import NoisyPartitionDescriptorSet
20 
21 _KRAUS_COMPLETENESS_TOL = 1e-10
22 _CHOI_POSITIVITY_FLOOR = -1e-12
23 
24 
25 def _primary_partition(descriptor_set: NoisyPartitionDescriptorSet):
26  for partition in descriptor_set.partitions:
27  if len(partition.local_to_global_qbits) == descriptor_set.qbit_num:
28  return partition
29  return descriptor_set.partitions[0]
30 
31 
33  descriptor_set: NoisyPartitionDescriptorSet,
34  parameters: np.ndarray,
35 ) -> np.ndarray:
36  """Fused channel-native Kraus bundle for the primary partition (matches pytest substrate)."""
37  partition = _primary_partition(descriptor_set)
39  descriptor_set,
40  partition,
41  parameters,
42  runtime_path=PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
43  )
45  descriptor_set,
46  partition.members,
47  local_vec,
48  runtime_path=PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
49  )
50  local_support = tuple(range(len(partition.local_to_global_qbits)))
51  steps = [
53  descriptor_set,
54  m,
55  seg,
56  local_support=local_support,
57  runtime_path=PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
58  )
59  for m in partition.members
60  ]
62  len(local_support),
63  descriptor_set=descriptor_set,
64  runtime_path=PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
65  )
66  for step in steps:
68  acc,
69  step,
70  descriptor_set=descriptor_set,
71  runtime_path=PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
72  )
73  return acc
74 
75 
76 def measure_kraus_bundle_invariants(bundle: np.ndarray) -> dict[str, Any]:
77  """Scalar completeness / Choi checks aligned with ``_check_kraus_bundle_invariants``."""
78  _k, d, _ = bundle.shape
79  acc = np.zeros((d, d), dtype=np.complex128)
80  for idx in range(bundle.shape[0]):
81  kj = bundle[idx]
82  acc += kj.conj().T @ kj
83  completeness_residual = float(
84  np.linalg.norm(acc - np.eye(d, dtype=np.complex128), ord="fro")
85  )
86  choi = np.zeros((d * d, d * d), dtype=np.complex128)
87  for idx in range(bundle.shape[0]):
88  vec = np.reshape(bundle[idx], (d * d,), order="C")
89  choi += np.outer(vec, vec.conj())
90  choi = (choi + choi.conj().T) / 2.0
91  min_eig = float(np.min(np.real(np.linalg.eigvalsh(choi))))
92  return {
93  "kraus_operator_count": int(bundle.shape[0]),
94  "support_dimension": int(d),
95  "completeness_residual_frobenius": completeness_residual,
96  "completeness_tolerance": _KRAUS_COMPLETENESS_TOL,
97  "completeness_pass": completeness_residual <= _KRAUS_COMPLETENESS_TOL,
98  "choi_min_eigenvalue_real": min_eig,
99  "choi_positivity_floor": _CHOI_POSITIVITY_FLOOR,
100  "choi_pass": min_eig >= _CHOI_POSITIVITY_FLOOR,
101  "invariant_slice_pass": (
102  completeness_residual <= _KRAUS_COMPLETENESS_TOL
103  and min_eig >= _CHOI_POSITIVITY_FLOOR
104  ),
105  }
106 
107 
109  descriptor_set: NoisyPartitionDescriptorSet,
110  parameters: np.ndarray,
111 ) -> dict[str, Any]:
112  bundle = build_fused_kraus_bundle_strict_microcase(descriptor_set, parameters)
113  metrics = measure_kraus_bundle_invariants(bundle)
114  return {
115  "runtime_path": PHASE31_RUNTIME_PATH_CHANNEL_NATIVE,
116  "representation_primary": "kraus_bundle",
117  **metrics,
118  }