janus.simulator.result 源代码
"""
Janus 模拟器结果类
封装模拟结果,包括测量计数、状态向量、概率分布等
"""
from typing import Dict, List, Optional, Union
import numpy as np
from collections import Counter
[文档]
class Counts(Counter):
"""
测量计数类
继承自 Counter,提供额外的量子计算相关方法
Example:
counts = Counts({'00': 512, '11': 488})
print(counts.most_frequent()) # '00'
print(counts.int_outcomes()) # {0: 512, 3: 488}
"""
[文档]
def __init__(self, data: Optional[Dict[str, int]] = None):
super().__init__(data or {})
[文档]
def most_frequent(self) -> str:
"""返回出现次数最多的测量结果"""
if not self:
return ""
return self.most_common(1)[0][0]
[文档]
def int_outcomes(self) -> Dict[int, int]:
"""将二进制字符串结果转换为整数"""
return {int(k, 2): v for k, v in self.items()}
[文档]
def hex_outcomes(self) -> Dict[str, int]:
"""将二进制字符串结果转换为十六进制"""
return {hex(int(k, 2)): v for k, v in self.items()}
[文档]
def total_shots(self) -> int:
"""返回总测量次数"""
return sum(self.values())
[文档]
def probabilities(self) -> Dict[str, float]:
"""返回概率分布"""
total = self.total_shots()
if total == 0:
return {}
return {k: v / total for k, v in self.items()}
[文档]
def marginal(self, indices: List[int]) -> 'Counts':
"""
边缘化到指定的比特位置
Args:
indices: 要保留的比特索引列表(从右到左,0 是最低位)
Returns:
Counts: 边缘化后的计数
"""
new_counts = Counter()
for bitstring, count in self.items():
# 提取指定位置的比特
new_bits = ''.join(bitstring[-(i+1)] for i in sorted(indices, reverse=True))
new_counts[new_bits] += count
return Counts(dict(new_counts))
[文档]
class SimulatorResult:
"""
模拟器结果类
封装单次模拟运行的所有结果
Attributes:
counts: 测量计数
statevector: 最终状态向量(可选)
probabilities: 概率分布
shots: 测量次数
metadata: 额外元数据
"""
[文档]
def __init__(
self,
counts: Optional[Dict[str, int]] = None,
statevector: Optional[np.ndarray] = None,
shots: int = 0,
metadata: Optional[Dict] = None
):
self._counts = Counts(counts) if counts else Counts()
self._statevector = statevector
self._shots = shots
self._metadata = metadata or {}
self._probabilities: Optional[np.ndarray] = None
@property
def counts(self) -> Counts:
"""获取测量计数"""
return self._counts
@property
def statevector(self) -> Optional[np.ndarray]:
"""获取最终状态向量"""
return self._statevector
@property
def shots(self) -> int:
"""获取测量次数"""
return self._shots
@property
def metadata(self) -> Dict:
"""获取元数据"""
return self._metadata
@property
def probabilities(self) -> np.ndarray:
"""获取概率分布"""
if self._probabilities is None and self._statevector is not None:
self._probabilities = np.abs(self._statevector) ** 2
return self._probabilities
[文档]
def get_counts(self, threshold: float = 0.0) -> Counts:
"""
获取测量计数,可选过滤低于阈值的结果
Args:
threshold: 概率阈值,低于此值的结果将被过滤
"""
if threshold <= 0:
return self._counts
total = self._counts.total_shots()
if total == 0:
return self._counts
filtered = {k: v for k, v in self._counts.items()
if v / total >= threshold}
return Counts(filtered)
[文档]
def get_statevector(self) -> Optional[np.ndarray]:
"""获取状态向量的副本"""
if self._statevector is None:
return None
return self._statevector.copy()
[文档]
def get_probabilities(self, decimals: Optional[int] = None) -> Dict[str, float]:
"""
获取概率分布字典
Args:
decimals: 小数位数,None 表示不舍入
"""
if self._statevector is None:
return self._counts.probabilities()
probs = np.abs(self._statevector) ** 2
n_qubits = int(np.log2(len(probs)))
result = {}
for i, p in enumerate(probs):
if p > 1e-15: # 过滤极小值
bitstring = format(i, f'0{n_qubits}b')
if decimals is not None:
p = round(p, decimals)
result[bitstring] = p
return result
[文档]
def expectation_value(self, observable: np.ndarray) -> complex:
"""
计算可观测量的期望值
Args:
observable: 可观测量矩阵(厄米矩阵)
Returns:
期望值 <ψ|O|ψ>
"""
if self._statevector is None:
raise ValueError("No statevector available for expectation value calculation")
return np.vdot(self._statevector, observable @ self._statevector)
def __repr__(self) -> str:
return f"SimulatorResult(shots={self._shots}, counts={dict(self._counts)})"