-
Notifications
You must be signed in to change notification settings - Fork 97
Open
Labels
bugSomething isn't workingSomething isn't working
Description
QPanda
基本信息
- QPanda 版本: pyqpanda 3.8.5
- 操作系统:Windows 11
Bug是什么?
使用QPanda产生的QFT和IQFT的矩阵与预期不一致
复现Bug的步骤?
使用如下代码:
"""
使用 PyQPanda 打印 3 量子比特 QFT 和 IQFT 的酉矩阵
本脚本演示如何使用 PyQPanda 库构建量子傅里叶变换(QFT)和
逆量子傅里叶变换(IQFT)电路,并获取对应的酉矩阵。
"""
import numpy as np
import pyqpanda as pq
def print_complex_matrix(mat, epsilon=1e-8, precision=4):
"""
精简打印 NumPy 复数矩阵,忽略实/虚部小于 epsilon 的部分。
同一列元素对齐显示,便于观看方阵结构。
参数:
- mat: NumPy 数组(矩阵)
- epsilon: 阈值,默认为 1e-8
- precision: 格式化精度,默认为 4 位有效数字
"""
def format_complex(val):
"""格式化单个复数,力求精简"""
real = val.real
imag = val.imag
if abs(real) < epsilon and abs(imag) < epsilon:
return '0'
elif abs(real) < epsilon:
return f'{imag:.{precision}g}j'
elif abs(imag) < epsilon:
return f'{real:.{precision}g}'
else:
sign = '+' if imag >= 0 else '-'
return f'{real:.{precision}g}{sign}{abs(imag):.{precision}g}j'
# 先生成所有格式化的字符串
n_rows = len(mat)
n_cols = len(mat[0]) if n_rows > 0 else 0
formatted = [[format_complex(mat[i][j]) for j in range(n_cols)] for i in range(n_rows)]
# 计算每列的最大宽度
col_widths = [max(len(formatted[i][j]) for i in range(n_rows)) for j in range(n_cols)]
# 打印对齐的矩阵
rows = []
for i in range(n_rows):
row_str = [formatted[i][j].rjust(col_widths[j]) for j in range(n_cols)]
rows.append('[' + ' '.join(row_str) + ']')
print('[' + '\n '.join(rows) + ']')
from qututor.qft.utils import (
get_output_filepath,
print_complex_matrix,
tee_output,
verify_qft_iqft,
)
def get_qft_matrix_pyqpanda(num_qubits):
"""
使用 PyQPanda 获取 QFT 的酉矩阵
Args:
num_qubits: 量子比特数量
Returns:
QFT 对应的酉矩阵 (numpy array)
"""
# 初始化量子虚拟机
machine = pq.CPUQVM()
machine.init_qvm()
# 分配量子比特
qvec = machine.qAlloc_many(num_qubits)
# 构建 QFT 量子程序
prog = pq.QProg()
prog << pq.QFT(qvec)
# 获取酉矩阵
matrix = pq.get_matrix(prog)
# 释放资源
machine.finalize()
# 将一维数组重塑为二维矩阵
dim = 2 ** num_qubits
return np.array(matrix).reshape(dim, dim)
def get_iqft_matrix_pyqpanda(num_qubits):
"""
使用 PyQPanda 获取 IQFT 的酉矩阵
Args:
num_qubits: 量子比特数量
Returns:
IQFT 对应的酉矩阵 (numpy array)
"""
# 初始化量子虚拟机
machine = pq.CPUQVM()
machine.init_qvm()
# 分配量子比特
qvec = machine.qAlloc_many(num_qubits)
# 构建 IQFT 量子程序 (QFT 的逆)
prog = pq.QProg()
# QFT 的第二个参数为 True 表示执行逆变换
prog << pq.QFT(qvec).dagger()
# 获取酉矩阵
matrix = pq.get_matrix(prog)
# 释放资源
machine.finalize()
# 将一维数组重塑为二维矩阵
dim = 2 ** num_qubits
return np.array(matrix).reshape(dim, dim)
def main():
num_qubits = 3
# 输出文件路径(与脚本同目录)
output_file = "pyqpanda_qft_matrix_output.txt"
with tee_output(output_file):
print(f"=" * 60)
print(f"PyQPanda: {num_qubits} 量子比特 QFT 和 IQFT 酉矩阵")
print(f"=" * 60)
# 获取 QFT 酉矩阵
print(f"\n{'='*20} QFT 酉矩阵 {'='*20}")
qft_matrix = get_qft_matrix_pyqpanda(num_qubits)
print(f"矩阵维度: {qft_matrix.shape}")
print()
print_complex_matrix(qft_matrix)
# 获取 IQFT 酉矩阵
print(f"\n{'='*20} IQFT 酉矩阵 {'='*20}")
iqft_matrix = get_iqft_matrix_pyqpanda(num_qubits)
print(f"矩阵维度: {iqft_matrix.shape}")
print()
print_complex_matrix(iqft_matrix)
# 验证 QFT * IQFT = I
print(f"\n{'='*20} 验证 {'='*20}")
is_valid = verify_qft_iqft(qft_matrix, iqft_matrix)
print(f"QFT × IQFT = I: {'✓ 通过' if is_valid else '✗ 失败'}")
# 额外:打印 QFT * IQFT 的结果
print(f"\n{'='*20} QFT × IQFT 结果 {'='*20}")
product = np.dot(qft_matrix, iqft_matrix)
print_complex_matrix(product)
print(f"\n结果已保存到: {output_file}")
if __name__ == "__main__":
main()上述代码打印的QFT和IQFT的矩阵分别为:
==================== QFT 酉矩阵 ====================
矩阵维度: (8, 8)
[[0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536]
[0.3536 0.3536 0.3536 0.3536 -0.3536 -0.3536 -0.3536 -0.3536]
[0.3536 0.3536 -0.3536 -0.3536 0.3536j 0.3536j -0.3536j -0.3536j]
[0.3536 0.3536 -0.3536 -0.3536 -0.3536j -0.3536j 0.3536j 0.3536j]
[0.3536 -0.3536 0.3536j -0.3536j 0.25+0.25j -0.25-0.25j -0.25+0.25j 0.25-0.25j]
[0.3536 -0.3536 0.3536j -0.3536j -0.25-0.25j 0.25+0.25j 0.25-0.25j -0.25+0.25j]
[0.3536 -0.3536 -0.3536j 0.3536j -0.25+0.25j 0.25-0.25j 0.25+0.25j -0.25-0.25j]
[0.3536 -0.3536 -0.3536j 0.3536j 0.25-0.25j -0.25+0.25j -0.25-0.25j 0.25+0.25j]]
==================== IQFT 酉矩阵 ====================
矩阵维度: (8, 8)
[[0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536]
[0.3536 0.3536 0.3536 0.3536 -0.3536 -0.3536 -0.3536 -0.3536]
[0.3536 0.3536 -0.3536 -0.3536 -0.3536j -0.3536j 0.3536j 0.3536j]
[0.3536 0.3536 -0.3536 -0.3536 0.3536j 0.3536j -0.3536j -0.3536j]
[0.3536 -0.3536 -0.3536j 0.3536j 0.25-0.25j -0.25+0.25j -0.25-0.25j 0.25+0.25j]
[0.3536 -0.3536 -0.3536j 0.3536j -0.25+0.25j 0.25-0.25j 0.25+0.25j -0.25-0.25j]
[0.3536 -0.3536 0.3536j -0.3536j -0.25-0.25j 0.25+0.25j 0.25-0.25j -0.25+0.25j]
[0.3536 -0.3536 0.3536j -0.3536j 0.25+0.25j -0.25-0.25j -0.25+0.25j 0.25-0.25j]]
但使用dft得到的结果如下:
============================================================
NumPy: 3 量子比特 (8 维) DFT 和 IDFT 矩阵
============================================================
==================== DFT 公式 ====================
F[j,k] = exp(2πi * j * k / N) / sqrt(N)
其中 N = 2^3 = 8, j,k ∈ [0, 7]
==================== DFT 矩阵 ====================
矩阵维度: (8, 8)
[[0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536]
[0.3536 0.25+0.25j 0.3536j -0.25+0.25j -0.3536 -0.25-0.25j -0.3536j 0.25-0.25j]
[0.3536 0.3536j -0.3536 -0.3536j 0.3536 0.3536j -0.3536 -0.3536j]
[0.3536 -0.25+0.25j -0.3536j 0.25+0.25j -0.3536 0.25-0.25j 0.3536j -0.25-0.25j]
[0.3536 -0.3536 0.3536 -0.3536 0.3536 -0.3536 0.3536 -0.3536]
[0.3536 -0.25-0.25j 0.3536j 0.25-0.25j -0.3536 0.25+0.25j -0.3536j -0.25+0.25j]
[0.3536 -0.3536j -0.3536 0.3536j 0.3536 -0.3536j -0.3536 0.3536j]
[0.3536 0.25-0.25j -0.3536j -0.25-0.25j -0.3536 -0.25+0.25j 0.3536j 0.25+0.25j]]
==================== IDFT 公式 ====================
F^(-1)[j,k] = exp(-2πi * j * k / N) / sqrt(N)
对于酉矩阵: IDFT = DFT^H (共轭转置)
==================== IDFT 矩阵 ====================
矩阵维度: (8, 8)
[[0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536]
[0.3536 0.25-0.25j -0.3536j -0.25-0.25j -0.3536 -0.25+0.25j 0.3536j 0.25+0.25j]
[0.3536 -0.3536j -0.3536 0.3536j 0.3536 -0.3536j -0.3536 0.3536j]
[0.3536 -0.25-0.25j 0.3536j 0.25-0.25j -0.3536 0.25+0.25j -0.3536j -0.25+0.25j]
[0.3536 -0.3536 0.3536 -0.3536 0.3536 -0.3536 0.3536 -0.3536]
[0.3536 -0.25+0.25j -0.3536j 0.25+0.25j -0.3536 0.25-0.25j 0.3536j -0.25-0.25j]
[0.3536 0.3536j -0.3536 -0.3536j 0.3536 0.3536j -0.3536 -0.3536j]
[0.3536 0.25+0.25j 0.3536j -0.25+0.25j -0.3536 -0.25-0.25j -0.3536j 0.25-0.25j]]
我做了如下尝试:
- 我无法通过行列变换使得DFT的结果与qpanda的结果一致。
- 我无法利用qpanda来控制是否添加 swap门
- 这个差异并非一个全局相位差(因为两边的矩阵的第一个数是相等的实数)
建议的解决方案
无。
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working