coordinate-system 5.2.2__cp313-cp313-win_amd64.whl → 6.0.1__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coordinate_system/__init__.py +120 -145
- coordinate_system/differential_geometry.py +618 -298
- coordinate_system/fourier_spectral.py +115 -729
- coordinate_system/frames.py +1571 -0
- coordinate_system/qframes.py +747 -630
- coordinate_system/visualization.py +695 -292
- coordinate_system-6.0.1.dist-info/METADATA +721 -0
- coordinate_system-6.0.1.dist-info/RECORD +15 -0
- coordinate_system-5.2.2.dist-info/METADATA +0 -807
- coordinate_system-5.2.2.dist-info/RECORD +0 -14
- {coordinate_system-5.2.2.dist-info → coordinate_system-6.0.1.dist-info}/LICENSE +0 -0
- {coordinate_system-5.2.2.dist-info → coordinate_system-6.0.1.dist-info}/WHEEL +0 -0
- {coordinate_system-5.2.2.dist-info → coordinate_system-6.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1571 @@
|
|
|
1
|
+
"""
|
|
2
|
+
复标架场与量子谱几何 (Complex Frame Field & Quantum Spectral Geometry)
|
|
3
|
+
================================================================================
|
|
4
|
+
|
|
5
|
+
统一几何、拓扑与量子物理的标架代数框架。
|
|
6
|
+
|
|
7
|
+
核心思想:
|
|
8
|
+
- 复标架变换 = ComplexFrame * Ω (Ω ∈ ℂ×)
|
|
9
|
+
- 傅里叶变换 = ComplexFrame * e^{iθ} (相位旋转)
|
|
10
|
+
- 共形变换 = ComplexFrame * λ (λ ∈ ℝ⁺, 缩放)
|
|
11
|
+
- 内禀梯度算子 G_μ = d/dx^μ log ComplexFrame(x)
|
|
12
|
+
- 曲率 R_{μν} = [G_μ, G_ν]
|
|
13
|
+
- Berry相位 γ = ∮ G_μ dx^μ
|
|
14
|
+
- 陈数 c₁ = (1/2π) ∬ R_{μν} dS
|
|
15
|
+
|
|
16
|
+
数学框架:
|
|
17
|
+
- 纤维丛理论:ComplexFrame 作为标架丛的局部截面
|
|
18
|
+
- 李群李代数:内禀梯度算子构成李代数
|
|
19
|
+
- 谱几何:曲率算子的谱分解与热核展开
|
|
20
|
+
- 路径积分:标架测度 Det[ComplexFrame] 与作用量
|
|
21
|
+
|
|
22
|
+
Author: Quantum Frame Theory
|
|
23
|
+
Date: 2025-12-04
|
|
24
|
+
Version: 6.0.1
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
__version__ = '6.0.1'
|
|
28
|
+
|
|
29
|
+
import numpy as np
|
|
30
|
+
from typing import List, Tuple, Dict, Optional, Union, Any, Callable
|
|
31
|
+
from dataclasses import dataclass
|
|
32
|
+
import warnings
|
|
33
|
+
|
|
34
|
+
# 导入坐标系统
|
|
35
|
+
try:
|
|
36
|
+
from .coordinate_system import coord3, vec3, quat
|
|
37
|
+
except ImportError:
|
|
38
|
+
try:
|
|
39
|
+
from coordinate_system import coord3, vec3, quat
|
|
40
|
+
except ImportError:
|
|
41
|
+
# 延迟导入,允许独立使用
|
|
42
|
+
coord3 = None
|
|
43
|
+
vec3 = None
|
|
44
|
+
quat = None
|
|
45
|
+
|
|
46
|
+
# 物理常数
|
|
47
|
+
HBAR = 1.0 # 约化普朗克常数(自然单位)
|
|
48
|
+
|
|
49
|
+
# GPU 可用性检查
|
|
50
|
+
try:
|
|
51
|
+
import cupy as cp
|
|
52
|
+
import cupyx.scipy.fft as cufft
|
|
53
|
+
GPU_AVAILABLE = True
|
|
54
|
+
except ImportError:
|
|
55
|
+
GPU_AVAILABLE = False
|
|
56
|
+
cp = None
|
|
57
|
+
cufft = None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# ============================================================
|
|
61
|
+
# 复标架代数 (Complex Frame Algebra)
|
|
62
|
+
# ============================================================
|
|
63
|
+
|
|
64
|
+
class ComplexFrame:
|
|
65
|
+
"""
|
|
66
|
+
复标架 - 统一几何、拓扑与量子物理的核心对象
|
|
67
|
+
|
|
68
|
+
复标架是经典坐标系对象的复数化扩展:
|
|
69
|
+
ComplexFrame = coord3 ⊗ ℂ
|
|
70
|
+
|
|
71
|
+
核心属性:
|
|
72
|
+
- base_coord: 基础坐标系 (coord3 对象)
|
|
73
|
+
- Q: 复标度因子 Q ∈ ℂ,编码相位与缩放
|
|
74
|
+
|
|
75
|
+
关键变换:
|
|
76
|
+
- ComplexFrame * e^{iθ} = 傅里叶变换 (θ=π/2 为标准变换)
|
|
77
|
+
- ComplexFrame * λ = 共形变换 (λ∈ℝ⁺)
|
|
78
|
+
- ComplexFrame * ComplexFrame = 标架复合 (路径积分中的复合)
|
|
79
|
+
|
|
80
|
+
几何意义:
|
|
81
|
+
- 作为标架丛 F(M) 的局部截面
|
|
82
|
+
- 内禀梯度算子 G_μ 描述局部旋转
|
|
83
|
+
- 曲率 R_{μν} = [G_μ, G_ν] 描述非交换性
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(self, base_coord=None, q_factor=1.0+0j):
|
|
87
|
+
"""
|
|
88
|
+
初始化复标架
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
base_coord: 基础坐标系 (coord3 对象),None 时使用单位标架
|
|
92
|
+
q_factor: 复标度因子 Q ∈ ℂ
|
|
93
|
+
"""
|
|
94
|
+
if base_coord is None:
|
|
95
|
+
if coord3 is not None:
|
|
96
|
+
self.base = coord3.identity()
|
|
97
|
+
else:
|
|
98
|
+
self.base = None
|
|
99
|
+
else:
|
|
100
|
+
self.base = base_coord
|
|
101
|
+
|
|
102
|
+
self.Q = complex(q_factor) # 确保是复数
|
|
103
|
+
self.dim = 3
|
|
104
|
+
|
|
105
|
+
# -------------------- 复标架属性 --------------------
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def o(self):
|
|
109
|
+
"""复位置向量"""
|
|
110
|
+
if self.base is None:
|
|
111
|
+
return None
|
|
112
|
+
o_base = self.base.o
|
|
113
|
+
# 复扩展:实部为原位置,虚部编码相位信息
|
|
114
|
+
return vec3(
|
|
115
|
+
o_base.x * self.Q.real + 1j * o_base.x * self.Q.imag,
|
|
116
|
+
o_base.y * self.Q.real + 1j * o_base.y * self.Q.imag,
|
|
117
|
+
o_base.z * self.Q.real + 1j * o_base.z * self.Q.imag
|
|
118
|
+
) if vec3 else None
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def s(self):
|
|
122
|
+
"""复缩放向量: s_Q = s_base · Q"""
|
|
123
|
+
if self.base is None:
|
|
124
|
+
return None
|
|
125
|
+
s_base = self.base.s
|
|
126
|
+
return vec3(
|
|
127
|
+
s_base.x * self.Q.real + 1j * s_base.x * self.Q.imag,
|
|
128
|
+
s_base.y * self.Q.real + 1j * s_base.y * self.Q.imag,
|
|
129
|
+
s_base.z * self.Q.real + 1j * s_base.z * self.Q.imag
|
|
130
|
+
) if vec3 else None
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def phase(self):
|
|
134
|
+
"""相位 arg(Q)"""
|
|
135
|
+
return np.angle(self.Q)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def magnitude(self):
|
|
139
|
+
"""模 |Q|"""
|
|
140
|
+
return np.abs(self.Q)
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def det(self):
|
|
144
|
+
"""
|
|
145
|
+
行列式: Det(Frame)
|
|
146
|
+
|
|
147
|
+
用于路径积分测度 ∫ Dφ · Det[Frame] · exp(iS/ħ)
|
|
148
|
+
"""
|
|
149
|
+
if self.base is None:
|
|
150
|
+
return self.Q ** 3 # 3维标架
|
|
151
|
+
s = self.base.s
|
|
152
|
+
det_s = s.x * s.y * s.z
|
|
153
|
+
return det_s * (self.Q ** 3)
|
|
154
|
+
|
|
155
|
+
# -------------------- 标架运算 --------------------
|
|
156
|
+
|
|
157
|
+
def __mul__(self, other):
|
|
158
|
+
"""
|
|
159
|
+
标架乘法 - 核心变换操作
|
|
160
|
+
|
|
161
|
+
支持:
|
|
162
|
+
- Frame * complex: 相位旋转/缩放 (傅里叶/共形变换)
|
|
163
|
+
- Frame * Frame: 标架复合 (路径积分复合)
|
|
164
|
+
- Frame * vec3: 向量变换
|
|
165
|
+
"""
|
|
166
|
+
if isinstance(other, (int, float, complex)):
|
|
167
|
+
# 标量乘法实现傅里叶/共形变换
|
|
168
|
+
new_Q = self.Q * other
|
|
169
|
+
return ComplexFrame(self.base, new_Q)
|
|
170
|
+
|
|
171
|
+
elif isinstance(other, ComplexFrame):
|
|
172
|
+
# 标架复合
|
|
173
|
+
if self.base is not None and other.base is not None:
|
|
174
|
+
new_base = self.base * other.base
|
|
175
|
+
else:
|
|
176
|
+
new_base = self.base or other.base
|
|
177
|
+
new_Q = self.Q * other.Q
|
|
178
|
+
return ComplexFrame(new_base, new_Q)
|
|
179
|
+
|
|
180
|
+
elif vec3 is not None and isinstance(other, vec3):
|
|
181
|
+
# 向量变换
|
|
182
|
+
return vec3(
|
|
183
|
+
other.x * self.Q.real,
|
|
184
|
+
other.y * self.Q.real,
|
|
185
|
+
other.z * self.Q.real
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
return NotImplemented
|
|
189
|
+
|
|
190
|
+
def __rmul__(self, other):
|
|
191
|
+
"""右乘法"""
|
|
192
|
+
return self.__mul__(other)
|
|
193
|
+
|
|
194
|
+
def __truediv__(self, other):
|
|
195
|
+
"""标架除法 - 逆变换"""
|
|
196
|
+
if isinstance(other, (int, float, complex)):
|
|
197
|
+
return ComplexFrame(self.base, self.Q / other)
|
|
198
|
+
elif isinstance(other, ComplexFrame):
|
|
199
|
+
if self.base is not None and other.base is not None:
|
|
200
|
+
new_base = self.base / other.base
|
|
201
|
+
else:
|
|
202
|
+
new_base = self.base
|
|
203
|
+
return ComplexFrame(new_base, self.Q / other.Q)
|
|
204
|
+
return NotImplemented
|
|
205
|
+
|
|
206
|
+
def __pow__(self, n):
|
|
207
|
+
"""幂运算: 对应多次变换"""
|
|
208
|
+
if isinstance(n, (int, float, complex)):
|
|
209
|
+
return ComplexFrame(self.base, self.Q ** n)
|
|
210
|
+
return NotImplemented
|
|
211
|
+
|
|
212
|
+
def __eq__(self, other):
|
|
213
|
+
"""相等比较"""
|
|
214
|
+
if not isinstance(other, ComplexFrame):
|
|
215
|
+
return False
|
|
216
|
+
return np.isclose(self.Q, other.Q)
|
|
217
|
+
|
|
218
|
+
def __repr__(self):
|
|
219
|
+
if self.base is not None:
|
|
220
|
+
return f"ComplexFrame(Q={self.Q:.4f}, o={self.base.o})"
|
|
221
|
+
return f"ComplexFrame(Q={self.Q:.4f})"
|
|
222
|
+
|
|
223
|
+
# -------------------- 傅里叶变换 --------------------
|
|
224
|
+
|
|
225
|
+
def fourier_transform(self, theta: float = np.pi/2) -> 'ComplexFrame':
|
|
226
|
+
"""
|
|
227
|
+
傅里叶变换: F_θ[ComplexFrame] = ComplexFrame · e^{iθ}
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
theta: 旋转角度,π/2 为标准傅里叶变换
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
变换后的 ComplexFrame
|
|
234
|
+
|
|
235
|
+
性质:
|
|
236
|
+
- F^4 = I (四次变换回到自身)
|
|
237
|
+
- F^2 = P (宇称变换)
|
|
238
|
+
"""
|
|
239
|
+
ft_factor = np.exp(1j * theta)
|
|
240
|
+
return self * ft_factor
|
|
241
|
+
|
|
242
|
+
def inverse_fourier_transform(self, theta: float = np.pi/2) -> 'ComplexFrame':
|
|
243
|
+
"""逆傅里叶变换: F^{-1} = F_{-θ}"""
|
|
244
|
+
return self.fourier_transform(-theta)
|
|
245
|
+
|
|
246
|
+
def conformal_transform(self, lambda_factor: float) -> 'ComplexFrame':
|
|
247
|
+
"""
|
|
248
|
+
共形变换: ComplexFrame → ComplexFrame · λ, λ ∈ ℝ⁺
|
|
249
|
+
|
|
250
|
+
实现缩放变换,保持角度不变
|
|
251
|
+
"""
|
|
252
|
+
return self * lambda_factor
|
|
253
|
+
|
|
254
|
+
# -------------------- 经典几何演化 --------------------
|
|
255
|
+
|
|
256
|
+
def diffusion_evolution(self, t: float, kappa: float = 1.0) -> 'ComplexFrame':
|
|
257
|
+
"""
|
|
258
|
+
扩散演化算子: e^{tΔ} ComplexFrame
|
|
259
|
+
|
|
260
|
+
这是经典热方程 ∂u/∂t = κΔu 的解算子,其中:
|
|
261
|
+
- Δ 是拉普拉斯算子(几何扩散算子)
|
|
262
|
+
- t 是时间参数(实时间,非虚时间)
|
|
263
|
+
- κ 是扩散系数
|
|
264
|
+
|
|
265
|
+
数学形式:
|
|
266
|
+
ComplexFrame(x, t) = e^{tκΔ} ComplexFrame(x, 0)
|
|
267
|
+
= ComplexFrame₀ · e^{-tκ|k|²} (动量空间)
|
|
268
|
+
|
|
269
|
+
物理意义:
|
|
270
|
+
- 描述几何信息在流形上的扩散过程
|
|
271
|
+
- 热核作为基本解:K(x,y,t) = (4πκt)^{-d/2} e^{-|x-y|²/(4κt)}
|
|
272
|
+
- 谱几何中的核心工具,用于提取流形的几何不变量
|
|
273
|
+
|
|
274
|
+
注意:这是**经典几何**的扩散过程,与量子力学的虚时间演化
|
|
275
|
+
在形式上类似,但物理意义完全不同。
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
t: 扩散时间(必须 > 0)
|
|
279
|
+
kappa: 扩散系数(默认1.0)
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
扩散演化后的ComplexFrame
|
|
283
|
+
|
|
284
|
+
局限性:
|
|
285
|
+
- 简化实现:仅对标度因子Q进行扩散
|
|
286
|
+
- 完整实现需要在标架场上定义拉普拉斯算子
|
|
287
|
+
- 数值实现受网格分辨率限制
|
|
288
|
+
"""
|
|
289
|
+
if t < 0:
|
|
290
|
+
raise ValueError("扩散时间t必须非负")
|
|
291
|
+
|
|
292
|
+
# 简化模型:对Q因子进行衰减(高频抑制)
|
|
293
|
+
# 完整实现需要在标架场的频谱表示中进行
|
|
294
|
+
decay_factor = np.exp(-kappa * t * np.abs(self.Q)**2)
|
|
295
|
+
evolved_Q = self.Q * decay_factor
|
|
296
|
+
|
|
297
|
+
return ComplexFrame(self.base, evolved_Q)
|
|
298
|
+
|
|
299
|
+
@staticmethod
|
|
300
|
+
def laplacian_from_field(frame_field: List[List['ComplexFrame']],
|
|
301
|
+
i: int, j: int) -> complex:
|
|
302
|
+
"""
|
|
303
|
+
从离散标架场计算拉普拉斯算子
|
|
304
|
+
|
|
305
|
+
Δ log ComplexFrame ≈ (∇² log ComplexFrame)
|
|
306
|
+
= ∂²/∂x² log Q + ∂²/∂y² log Q
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
frame_field: 离散标架场
|
|
310
|
+
i, j: 网格位置
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
拉普拉斯算子作用结果(复数)
|
|
314
|
+
|
|
315
|
+
数学细节:
|
|
316
|
+
使用五点差分模板计算二阶导数:
|
|
317
|
+
Δf ≈ [f(i+1,j) + f(i-1,j) + f(i,j+1) + f(i,j-1) - 4f(i,j)] / h²
|
|
318
|
+
"""
|
|
319
|
+
ny, nx = len(frame_field), len(frame_field[0])
|
|
320
|
+
|
|
321
|
+
if i <= 0 or i >= ny - 1 or j <= 0 or j >= nx - 1:
|
|
322
|
+
return 0.0 + 0j
|
|
323
|
+
|
|
324
|
+
# 中心点
|
|
325
|
+
log_Q_center = np.log(frame_field[i][j].Q)
|
|
326
|
+
|
|
327
|
+
# 四个邻居
|
|
328
|
+
log_Q_xp = np.log(frame_field[i][j+1].Q)
|
|
329
|
+
log_Q_xm = np.log(frame_field[i][j-1].Q)
|
|
330
|
+
log_Q_yp = np.log(frame_field[i+1][j].Q)
|
|
331
|
+
log_Q_ym = np.log(frame_field[i-1][j].Q)
|
|
332
|
+
|
|
333
|
+
# 五点拉普拉斯模板(假设网格间距h=1)
|
|
334
|
+
laplacian = (log_Q_xp + log_Q_xm + log_Q_yp + log_Q_ym - 4*log_Q_center)
|
|
335
|
+
|
|
336
|
+
return laplacian
|
|
337
|
+
|
|
338
|
+
# -------------------- 谱变换 --------------------
|
|
339
|
+
|
|
340
|
+
@staticmethod
|
|
341
|
+
def spectral_transform_2d(field: np.ndarray, hbar: float = HBAR) -> np.ndarray:
|
|
342
|
+
"""
|
|
343
|
+
二维谱变换:位置空间 → 动量空间
|
|
344
|
+
|
|
345
|
+
数学形式:
|
|
346
|
+
ψ̃(k) = ∫ e^{ikx/ħ} ψ(x) dx / √(2πħ)
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
field: 输入场,形状 [ny, nx, ...] 或 [ny, nx]
|
|
350
|
+
hbar: 约化普朗克常数
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
动量空间谱
|
|
354
|
+
"""
|
|
355
|
+
# 确定 FFT 的轴
|
|
356
|
+
if field.ndim >= 2:
|
|
357
|
+
axes = (0, 1)
|
|
358
|
+
else:
|
|
359
|
+
axes = None
|
|
360
|
+
|
|
361
|
+
spectrum = np.fft.fft2(field, axes=axes)
|
|
362
|
+
|
|
363
|
+
# 量子力学归一化
|
|
364
|
+
normalization = 1.0 / np.sqrt(2 * np.pi * hbar)
|
|
365
|
+
return spectrum * normalization
|
|
366
|
+
|
|
367
|
+
@staticmethod
|
|
368
|
+
def inverse_spectral_transform_2d(spectrum: np.ndarray, hbar: float = HBAR) -> np.ndarray:
|
|
369
|
+
"""
|
|
370
|
+
二维逆谱变换:动量空间 → 位置空间
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
spectrum: 动量空间谱
|
|
374
|
+
hbar: 约化普朗克常数
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
位置空间场
|
|
378
|
+
"""
|
|
379
|
+
if spectrum.ndim >= 2:
|
|
380
|
+
axes = (0, 1)
|
|
381
|
+
else:
|
|
382
|
+
axes = None
|
|
383
|
+
|
|
384
|
+
denormalization = np.sqrt(2 * np.pi * hbar)
|
|
385
|
+
return np.fft.ifft2(spectrum * denormalization, axes=axes).real
|
|
386
|
+
|
|
387
|
+
@staticmethod
|
|
388
|
+
def spectral_transform_2d_gpu(field: np.ndarray, hbar: float = HBAR) -> np.ndarray:
|
|
389
|
+
"""GPU 加速的二维谱变换"""
|
|
390
|
+
if not GPU_AVAILABLE:
|
|
391
|
+
raise RuntimeError("CuPy 不可用,无法使用 GPU 加速")
|
|
392
|
+
|
|
393
|
+
field_gpu = cp.asarray(field)
|
|
394
|
+
spectrum_gpu = cufft.fft2(field_gpu, axes=(0, 1))
|
|
395
|
+
normalization = 1.0 / np.sqrt(2 * np.pi * hbar)
|
|
396
|
+
spectrum_gpu *= normalization
|
|
397
|
+
return cp.asnumpy(spectrum_gpu)
|
|
398
|
+
|
|
399
|
+
@classmethod
|
|
400
|
+
def from_coord_field(cls, coord_field: List[List], hbar: float = HBAR) -> 'ComplexFrameSpectrum':
|
|
401
|
+
"""
|
|
402
|
+
从坐标场创建谱表示
|
|
403
|
+
|
|
404
|
+
将坐标场的各分量进行谱变换
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
coord_field: 二维坐标场列表 [[coord3, ...], ...]
|
|
408
|
+
hbar: 约化普朗克常数
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
ComplexFrameSpectrum 对象
|
|
412
|
+
"""
|
|
413
|
+
ny = len(coord_field)
|
|
414
|
+
nx = len(coord_field[0]) if ny > 0 else 0
|
|
415
|
+
|
|
416
|
+
# 提取场分量
|
|
417
|
+
tensor_field = np.zeros((ny, nx, 12), dtype=np.float64)
|
|
418
|
+
for i in range(ny):
|
|
419
|
+
for j in range(nx):
|
|
420
|
+
coord = coord_field[i][j]
|
|
421
|
+
tensor_field[i, j, 0:3] = [coord.o.x, coord.o.y, coord.o.z]
|
|
422
|
+
tensor_field[i, j, 3:6] = [coord.ux.x, coord.ux.y, coord.ux.z]
|
|
423
|
+
tensor_field[i, j, 6:9] = [coord.uy.x, coord.uy.y, coord.uy.z]
|
|
424
|
+
tensor_field[i, j, 9:12] = [coord.uz.x, coord.uz.y, coord.uz.z]
|
|
425
|
+
|
|
426
|
+
# 谱变换各分量
|
|
427
|
+
origin_spectrum = cls.spectral_transform_2d(tensor_field[..., 0:3], hbar)
|
|
428
|
+
ux_spectrum = cls.spectral_transform_2d(tensor_field[..., 3:6], hbar)
|
|
429
|
+
uy_spectrum = cls.spectral_transform_2d(tensor_field[..., 6:9], hbar)
|
|
430
|
+
uz_spectrum = cls.spectral_transform_2d(tensor_field[..., 9:12], hbar)
|
|
431
|
+
|
|
432
|
+
# 动量网格
|
|
433
|
+
kx = 2 * np.pi * np.fft.fftfreq(nx) / hbar
|
|
434
|
+
ky = 2 * np.pi * np.fft.fftfreq(ny) / hbar
|
|
435
|
+
|
|
436
|
+
return ComplexFrameSpectrum(
|
|
437
|
+
ux_spectrum=ux_spectrum,
|
|
438
|
+
uy_spectrum=uy_spectrum,
|
|
439
|
+
uz_spectrum=uz_spectrum,
|
|
440
|
+
origin_spectrum=origin_spectrum,
|
|
441
|
+
momentum_grid=(kx, ky),
|
|
442
|
+
hbar=hbar
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
# ============================================================
|
|
447
|
+
# 内禀梯度算子 (Intrinsic Gradient Operator)
|
|
448
|
+
# ============================================================
|
|
449
|
+
|
|
450
|
+
class IntrinsicGradient:
|
|
451
|
+
"""
|
|
452
|
+
内禀梯度算子 G_μ = d/dx^μ log ComplexFrame(x)
|
|
453
|
+
|
|
454
|
+
几何意义(经典谱几何视角):
|
|
455
|
+
- 描述标架的局部旋转速率(协变导数的对数形式)
|
|
456
|
+
- 对应黎曼几何中的联络1-形式
|
|
457
|
+
- 非交换性 [G_μ, G_ν] 直接给出曲率张量
|
|
458
|
+
|
|
459
|
+
数学性质:
|
|
460
|
+
- δComplexFrame = G_μ ComplexFrame δx^μ (无穷小变换)
|
|
461
|
+
- [G_μ, G_ν] = R_{μν} (曲率2-形式)
|
|
462
|
+
- γ = ∮ G_μ dx^μ (几何相位 - parallel transport)
|
|
463
|
+
- Δ = ∇² = ∂_μ ∂^μ (拉普拉斯算子)
|
|
464
|
+
|
|
465
|
+
与量子理论的关系:
|
|
466
|
+
- 形式上类似规范场论中的联络,但这里是**纯几何对象**
|
|
467
|
+
- Berry相位在这里是经典几何相位(平行输运),非量子效应
|
|
468
|
+
- 该理论完全在经典微分几何框架内
|
|
469
|
+
"""
|
|
470
|
+
|
|
471
|
+
def __init__(self, frame_field: Union[Callable, List[List['ComplexFrame']]]):
|
|
472
|
+
"""
|
|
473
|
+
初始化内禀梯度算子
|
|
474
|
+
|
|
475
|
+
Args:
|
|
476
|
+
frame_field: 标架场,可以是函数或离散场
|
|
477
|
+
"""
|
|
478
|
+
self.frame_field = frame_field
|
|
479
|
+
self.is_discrete = isinstance(frame_field, list)
|
|
480
|
+
|
|
481
|
+
def compute_at(self, position: Union[Tuple, int],
|
|
482
|
+
direction: int, delta: float = 1e-5) -> complex:
|
|
483
|
+
"""
|
|
484
|
+
计算指定位置和方向的内禀梯度
|
|
485
|
+
|
|
486
|
+
Args:
|
|
487
|
+
position: 位置坐标 (连续) 或索引 (离散)
|
|
488
|
+
direction: 方向索引 (0=x, 1=y, 2=z)
|
|
489
|
+
delta: 有限差分步长
|
|
490
|
+
|
|
491
|
+
Returns:
|
|
492
|
+
G_μ 的复数值
|
|
493
|
+
"""
|
|
494
|
+
if self.is_discrete:
|
|
495
|
+
return self._compute_discrete(position, direction)
|
|
496
|
+
else:
|
|
497
|
+
return self._compute_continuous(position, direction, delta)
|
|
498
|
+
|
|
499
|
+
def _compute_discrete(self, idx: Tuple[int, int], direction: int) -> complex:
|
|
500
|
+
"""离散场的内禀梯度"""
|
|
501
|
+
i, j = idx
|
|
502
|
+
ny, nx = len(self.frame_field), len(self.frame_field[0])
|
|
503
|
+
|
|
504
|
+
# 中心差分
|
|
505
|
+
if direction == 0: # x方向
|
|
506
|
+
if j + 1 < nx and j - 1 >= 0:
|
|
507
|
+
frame_forward = self.frame_field[i][j + 1]
|
|
508
|
+
frame_backward = self.frame_field[i][j - 1]
|
|
509
|
+
frame_center = self.frame_field[i][j]
|
|
510
|
+
|
|
511
|
+
# G_x ≈ (log Q_{j+1} - log Q_{j-1}) / 2
|
|
512
|
+
return (np.log(frame_forward.Q) - np.log(frame_backward.Q)) / 2.0
|
|
513
|
+
|
|
514
|
+
elif direction == 1: # y方向
|
|
515
|
+
if i + 1 < ny and i - 1 >= 0:
|
|
516
|
+
frame_forward = self.frame_field[i + 1][j]
|
|
517
|
+
frame_backward = self.frame_field[i - 1][j]
|
|
518
|
+
|
|
519
|
+
return (np.log(frame_forward.Q) - np.log(frame_backward.Q)) / 2.0
|
|
520
|
+
|
|
521
|
+
return 0.0 + 0j
|
|
522
|
+
|
|
523
|
+
def _compute_continuous(self, pos: Tuple, direction: int, delta: float) -> complex:
|
|
524
|
+
"""连续场的内禀梯度"""
|
|
525
|
+
pos_list = list(pos)
|
|
526
|
+
|
|
527
|
+
# 前向和后向位置
|
|
528
|
+
pos_forward = pos_list.copy()
|
|
529
|
+
pos_backward = pos_list.copy()
|
|
530
|
+
pos_forward[direction] += delta
|
|
531
|
+
pos_backward[direction] -= delta
|
|
532
|
+
|
|
533
|
+
frame_forward = self.frame_field(tuple(pos_forward))
|
|
534
|
+
frame_backward = self.frame_field(tuple(pos_backward))
|
|
535
|
+
|
|
536
|
+
# G_μ = d/dx^μ log Frame
|
|
537
|
+
return (np.log(frame_forward.Q) - np.log(frame_backward.Q)) / (2 * delta)
|
|
538
|
+
|
|
539
|
+
def commutator(self, pos: Union[Tuple, int],
|
|
540
|
+
dir1: int, dir2: int, delta: float = 1e-5) -> complex:
|
|
541
|
+
"""
|
|
542
|
+
计算李括号 [G_μ, G_ν] = 曲率 R_{μν}
|
|
543
|
+
|
|
544
|
+
Args:
|
|
545
|
+
pos: 位置
|
|
546
|
+
dir1, dir2: 两个方向索引
|
|
547
|
+
delta: 有限差分步长
|
|
548
|
+
|
|
549
|
+
Returns:
|
|
550
|
+
曲率分量 R_{μν}
|
|
551
|
+
"""
|
|
552
|
+
G_mu = self.compute_at(pos, dir1, delta)
|
|
553
|
+
G_nu = self.compute_at(pos, dir2, delta)
|
|
554
|
+
|
|
555
|
+
# 简化版本:[G_μ, G_ν] ≈ G_μ G_ν - G_ν G_μ
|
|
556
|
+
# 对于阿贝尔情况(标量Q),交换子为0
|
|
557
|
+
# 完整实现需要考虑标架场的非阿贝尔结构
|
|
558
|
+
return G_mu * G_nu - G_nu * G_mu
|
|
559
|
+
|
|
560
|
+
def laplacian(self, position: Union[Tuple[int, int], int]) -> complex:
|
|
561
|
+
"""
|
|
562
|
+
拉普拉斯算子 Δ = ∇² = ∂²/∂x² + ∂²/∂y²
|
|
563
|
+
|
|
564
|
+
作用于 log ComplexFrame:
|
|
565
|
+
Δ log ComplexFrame = ∂²/∂x² log Q + ∂²/∂y² log Q
|
|
566
|
+
|
|
567
|
+
这是谱几何的核心算子,其本征值问题:
|
|
568
|
+
Δφ_n = -λ_n φ_n
|
|
569
|
+
|
|
570
|
+
定义了流形的谱(spectrum),从而编码几何信息。
|
|
571
|
+
|
|
572
|
+
Args:
|
|
573
|
+
position: 网格位置 (i, j) 或索引
|
|
574
|
+
|
|
575
|
+
Returns:
|
|
576
|
+
拉普拉斯算子作用结果
|
|
577
|
+
|
|
578
|
+
数学背景:
|
|
579
|
+
- 拉普拉斯算子是黎曼流形上的自然微分算子
|
|
580
|
+
- 其谱{λ_n}包含流形的几何不变量(Weyl律、热核展开)
|
|
581
|
+
- "Can one hear the shape of a drum?" - Kac's问题
|
|
582
|
+
"""
|
|
583
|
+
if not self.is_discrete:
|
|
584
|
+
raise NotImplementedError("连续场的拉普拉斯算子需要额外实现")
|
|
585
|
+
|
|
586
|
+
if isinstance(position, int):
|
|
587
|
+
# 1D情况(简化)
|
|
588
|
+
return 0.0 + 0j
|
|
589
|
+
|
|
590
|
+
# 使用ComplexFrame的静态方法
|
|
591
|
+
return ComplexFrame.laplacian_from_field(self.frame_field, position[0], position[1])
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
# ============================================================
|
|
595
|
+
# 曲率计算 (Curvature from Frames)
|
|
596
|
+
# ============================================================
|
|
597
|
+
|
|
598
|
+
class CurvatureFromFrame:
|
|
599
|
+
"""
|
|
600
|
+
从标架场计算曲率
|
|
601
|
+
|
|
602
|
+
核心公式:
|
|
603
|
+
- R_{μν} = [G_μ, G_ν] = ∂_μ G_ν - ∂_ν G_μ - [G_μ, G_ν]
|
|
604
|
+
- 高斯曲率 K = -⟨[G_u, G_v] e_v, e_u⟩ / √det(g)
|
|
605
|
+
- 平均曲率 H = (1/2) Tr(R)
|
|
606
|
+
"""
|
|
607
|
+
|
|
608
|
+
def __init__(self, frame_field: List[List['ComplexFrame']]):
|
|
609
|
+
"""
|
|
610
|
+
初始化曲率计算器
|
|
611
|
+
|
|
612
|
+
Args:
|
|
613
|
+
frame_field: 离散标架场
|
|
614
|
+
"""
|
|
615
|
+
self.frame_field = frame_field
|
|
616
|
+
self.gradient_op = IntrinsicGradient(frame_field)
|
|
617
|
+
self.ny = len(frame_field)
|
|
618
|
+
self.nx = len(frame_field[0]) if self.ny > 0 else 0
|
|
619
|
+
|
|
620
|
+
def gaussian_curvature(self, i: int, j: int) -> float:
|
|
621
|
+
"""
|
|
622
|
+
计算高斯曲率
|
|
623
|
+
|
|
624
|
+
K = -⟨[G_u, G_v] e_v, e_u⟩ / √det(g)
|
|
625
|
+
|
|
626
|
+
Args:
|
|
627
|
+
i, j: 网格索引
|
|
628
|
+
|
|
629
|
+
Returns:
|
|
630
|
+
高斯曲率值
|
|
631
|
+
"""
|
|
632
|
+
# 计算李括号 [G_x, G_y]
|
|
633
|
+
R_xy = self.gradient_op.commutator((i, j), 0, 1)
|
|
634
|
+
|
|
635
|
+
# 简化版本:K ≈ -Im(R_xy) (对于复标架)
|
|
636
|
+
# 完整实现需要计算度量张量
|
|
637
|
+
return -R_xy.imag
|
|
638
|
+
|
|
639
|
+
def mean_curvature(self, i: int, j: int) -> float:
|
|
640
|
+
"""
|
|
641
|
+
计算平均曲率
|
|
642
|
+
|
|
643
|
+
H = (1/2) Tr(R)
|
|
644
|
+
|
|
645
|
+
Args:
|
|
646
|
+
i, j: 网格索引
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
平均曲率值
|
|
650
|
+
"""
|
|
651
|
+
# 简化实现
|
|
652
|
+
R_xx = self.gradient_op.commutator((i, j), 0, 0)
|
|
653
|
+
R_yy = self.gradient_op.commutator((i, j), 1, 1)
|
|
654
|
+
|
|
655
|
+
return 0.5 * (R_xx.real + R_yy.real)
|
|
656
|
+
|
|
657
|
+
def riemann_curvature_tensor(self, i: int, j: int) -> np.ndarray:
|
|
658
|
+
"""
|
|
659
|
+
计算黎曼曲率张量
|
|
660
|
+
|
|
661
|
+
R_{ijkl} = -√det(g) ⟨[G_i, G_j] e_l, e_k⟩
|
|
662
|
+
|
|
663
|
+
Args:
|
|
664
|
+
i, j: 网格索引
|
|
665
|
+
|
|
666
|
+
Returns:
|
|
667
|
+
曲率张量 (2x2 矩阵,简化2D情况)
|
|
668
|
+
"""
|
|
669
|
+
R = np.zeros((2, 2), dtype=complex)
|
|
670
|
+
|
|
671
|
+
R[0, 0] = self.gradient_op.commutator((i, j), 0, 0)
|
|
672
|
+
R[0, 1] = self.gradient_op.commutator((i, j), 0, 1)
|
|
673
|
+
R[1, 0] = self.gradient_op.commutator((i, j), 1, 0)
|
|
674
|
+
R[1, 1] = self.gradient_op.commutator((i, j), 1, 1)
|
|
675
|
+
|
|
676
|
+
return R
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
# ============================================================
|
|
680
|
+
# 几何相位 (Geometric Phase)
|
|
681
|
+
# ============================================================
|
|
682
|
+
|
|
683
|
+
class BerryPhase:
|
|
684
|
+
"""
|
|
685
|
+
Berry相位计算
|
|
686
|
+
|
|
687
|
+
几何相位公式:
|
|
688
|
+
γ = ∮_C G_μ dx^μ = ∮_C (∂_μ Frame · Frame^{-1}) dx^μ
|
|
689
|
+
|
|
690
|
+
性质:
|
|
691
|
+
- 与路径参数化无关
|
|
692
|
+
- 仅依赖于路径的几何形状
|
|
693
|
+
- 对应曲率的面积分(Stokes定理)
|
|
694
|
+
"""
|
|
695
|
+
|
|
696
|
+
def __init__(self, gradient_operator: IntrinsicGradient):
|
|
697
|
+
"""
|
|
698
|
+
初始化Berry相位计算器
|
|
699
|
+
|
|
700
|
+
Args:
|
|
701
|
+
gradient_operator: 内禀梯度算子
|
|
702
|
+
"""
|
|
703
|
+
self.gradient_op = gradient_operator
|
|
704
|
+
|
|
705
|
+
def compute_along_path(self, path: List[Tuple], closed: bool = True) -> complex:
|
|
706
|
+
"""
|
|
707
|
+
沿路径计算Berry相位
|
|
708
|
+
|
|
709
|
+
γ = ∮_C G_μ dx^μ
|
|
710
|
+
|
|
711
|
+
Args:
|
|
712
|
+
path: 路径点列表 [(i1, j1), (i2, j2), ...]
|
|
713
|
+
closed: 是否闭合路径
|
|
714
|
+
|
|
715
|
+
Returns:
|
|
716
|
+
几何相位(复数)
|
|
717
|
+
"""
|
|
718
|
+
if len(path) < 2:
|
|
719
|
+
return 0.0 + 0j
|
|
720
|
+
|
|
721
|
+
phase = 0.0 + 0j
|
|
722
|
+
|
|
723
|
+
for k in range(len(path) - 1):
|
|
724
|
+
pos_current = path[k]
|
|
725
|
+
pos_next = path[k + 1]
|
|
726
|
+
|
|
727
|
+
# 确定方向
|
|
728
|
+
dx = pos_next[0] - pos_current[0]
|
|
729
|
+
dy = pos_next[1] - pos_current[1]
|
|
730
|
+
|
|
731
|
+
# 计算梯度分量
|
|
732
|
+
if abs(dx) > abs(dy):
|
|
733
|
+
direction = 0 # x方向
|
|
734
|
+
step = dx
|
|
735
|
+
else:
|
|
736
|
+
direction = 1 # y方向
|
|
737
|
+
step = dy
|
|
738
|
+
|
|
739
|
+
# G_μ dx^μ
|
|
740
|
+
G_mu = self.gradient_op.compute_at(pos_current, direction)
|
|
741
|
+
phase += G_mu * step
|
|
742
|
+
|
|
743
|
+
# 闭合路径
|
|
744
|
+
if closed and len(path) > 2:
|
|
745
|
+
pos_last = path[-1]
|
|
746
|
+
pos_first = path[0]
|
|
747
|
+
|
|
748
|
+
dx = pos_first[0] - pos_last[0]
|
|
749
|
+
dy = pos_first[1] - pos_last[1]
|
|
750
|
+
|
|
751
|
+
if abs(dx) > abs(dy):
|
|
752
|
+
direction = 0
|
|
753
|
+
step = dx
|
|
754
|
+
else:
|
|
755
|
+
direction = 1
|
|
756
|
+
step = dy
|
|
757
|
+
|
|
758
|
+
G_mu = self.gradient_op.compute_at(pos_last, direction)
|
|
759
|
+
phase += G_mu * step
|
|
760
|
+
|
|
761
|
+
return phase
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
# ============================================================
|
|
765
|
+
# 陈数 (Chern Number)
|
|
766
|
+
# ============================================================
|
|
767
|
+
|
|
768
|
+
class ChernNumber:
|
|
769
|
+
"""
|
|
770
|
+
第一陈数计算
|
|
771
|
+
|
|
772
|
+
拓扑不变量:
|
|
773
|
+
c₁ = (1/2π) ∬_M R_{μν} dS^{μν}
|
|
774
|
+
= (1/2π) ∬_M Tr([G_μ, G_ν]) dS^{μν}
|
|
775
|
+
|
|
776
|
+
物理意义:
|
|
777
|
+
- 刻画纤维丛的拓扑性质
|
|
778
|
+
- 量子霍尔效应中的拓扑不变量
|
|
779
|
+
- 与Berry相位的关联(Stokes定理)
|
|
780
|
+
"""
|
|
781
|
+
|
|
782
|
+
def __init__(self, curvature_calculator: CurvatureFromFrame):
|
|
783
|
+
"""
|
|
784
|
+
初始化陈数计算器
|
|
785
|
+
|
|
786
|
+
Args:
|
|
787
|
+
curvature_calculator: 曲率计算器
|
|
788
|
+
"""
|
|
789
|
+
self.curvature = curvature_calculator
|
|
790
|
+
|
|
791
|
+
def compute(self) -> float:
|
|
792
|
+
"""
|
|
793
|
+
计算第一陈数
|
|
794
|
+
|
|
795
|
+
c₁ = (1/2π) Σ_{ij} R_{xy}(i,j) ΔS
|
|
796
|
+
|
|
797
|
+
Returns:
|
|
798
|
+
陈数(实数)
|
|
799
|
+
"""
|
|
800
|
+
total = 0.0 + 0j
|
|
801
|
+
|
|
802
|
+
ny, nx = self.curvature.ny, self.curvature.nx
|
|
803
|
+
|
|
804
|
+
for i in range(1, ny - 1):
|
|
805
|
+
for j in range(1, nx - 1):
|
|
806
|
+
# 曲率 R_{xy}
|
|
807
|
+
R_xy = self.curvature.gradient_op.commutator((i, j), 0, 1)
|
|
808
|
+
total += R_xy
|
|
809
|
+
|
|
810
|
+
# 归一化
|
|
811
|
+
c1 = total / (2 * np.pi)
|
|
812
|
+
|
|
813
|
+
# 陈数应为整数(拓扑不变量)
|
|
814
|
+
return round(c1.real)
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
# ============================================================
|
|
818
|
+
# 谱分解 (Spectral Decomposition)
|
|
819
|
+
# ============================================================
|
|
820
|
+
|
|
821
|
+
class SpectralDecomposition:
|
|
822
|
+
"""
|
|
823
|
+
拉普拉斯算子的谱分解(经典几何谱理论)
|
|
824
|
+
|
|
825
|
+
数学框架:
|
|
826
|
+
拉普拉斯本征值问题:
|
|
827
|
+
Δφ_n = -λ_n φ_n
|
|
828
|
+
∫ φ_m φ_n dV = δ_{mn}
|
|
829
|
+
|
|
830
|
+
谱分解定理:
|
|
831
|
+
Δ = -Σ_n λ_n |φ_n⟩⟨φ_n|
|
|
832
|
+
|
|
833
|
+
**ComplexFrame作为本征态基础**:
|
|
834
|
+
在我们的框架中,ComplexFrame场可展开为本征态的叠加:
|
|
835
|
+
|
|
836
|
+
ComplexFrame(x) = Σ_n c_n φ_n(x) ComplexFrame_n
|
|
837
|
+
|
|
838
|
+
其中:
|
|
839
|
+
- φ_n(x) 是拉普拉斯算子的标量本征函数
|
|
840
|
+
- ComplexFrame_n 是对应的标架本征态
|
|
841
|
+
- c_n = ⟨φ_n | ComplexFrame⟩ 是展开系数
|
|
842
|
+
|
|
843
|
+
谱的几何意义:
|
|
844
|
+
- {λ_n} 编码流形的几何信息(形状DNA)
|
|
845
|
+
- 低频模式(小λ)对应大尺度几何特征
|
|
846
|
+
- 高频模式(大λ)对应局部细节
|
|
847
|
+
|
|
848
|
+
Weyl渐近律:
|
|
849
|
+
N(λ) ~ (ω_d / (2π)^d) Vol(M) λ^{d/2}
|
|
850
|
+
|
|
851
|
+
其中 N(λ) 是小于λ的本征值个数。
|
|
852
|
+
|
|
853
|
+
应用:
|
|
854
|
+
- ShapeDNA:谱签名用于形状识别
|
|
855
|
+
- 谱距离:流形间的几何距离度量
|
|
856
|
+
- 多尺度分析:不同频段的几何特征
|
|
857
|
+
- 热核展开:Tr(e^{tΔ}) = Σ_n e^{-tλ_n}
|
|
858
|
+
"""
|
|
859
|
+
|
|
860
|
+
def __init__(self, frame_field: Union[List[List['ComplexFrame']], 'ComplexFrameSpectrum']):
|
|
861
|
+
"""
|
|
862
|
+
初始化谱分解
|
|
863
|
+
|
|
864
|
+
Args:
|
|
865
|
+
frame_field: ComplexFrame场或其频谱表示
|
|
866
|
+
"""
|
|
867
|
+
if isinstance(frame_field, list):
|
|
868
|
+
# 离散标架场
|
|
869
|
+
self.frame_field = frame_field
|
|
870
|
+
self.gradient_op = IntrinsicGradient(frame_field)
|
|
871
|
+
self.ny = len(frame_field)
|
|
872
|
+
self.nx = len(frame_field[0]) if self.ny > 0 else 0
|
|
873
|
+
self.spectrum = None
|
|
874
|
+
else:
|
|
875
|
+
# 频谱表示
|
|
876
|
+
self.spectrum = frame_field
|
|
877
|
+
self.frame_field = None
|
|
878
|
+
self.gradient_op = None
|
|
879
|
+
self.ny, self.nx = frame_field.shape
|
|
880
|
+
|
|
881
|
+
self._eigenvalues = None
|
|
882
|
+
self._eigenvectors = None
|
|
883
|
+
|
|
884
|
+
def compute_eigenspectrum(self) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
885
|
+
"""
|
|
886
|
+
计算拉普拉斯算子的本征谱
|
|
887
|
+
|
|
888
|
+
Returns:
|
|
889
|
+
(eigenvalues, eigenvectors)
|
|
890
|
+
- eigenvalues: λ_n 数组(降序排列)
|
|
891
|
+
- eigenvectors: 本征函数φ_n(简化实现可能为None)
|
|
892
|
+
|
|
893
|
+
数值方法:
|
|
894
|
+
对于频谱表示,本征值对应 k² = |k|²
|
|
895
|
+
对于离散场,需要构造拉普拉斯矩阵并求解
|
|
896
|
+
"""
|
|
897
|
+
if self._eigenvalues is not None:
|
|
898
|
+
return self._eigenvalues, self._eigenvectors
|
|
899
|
+
|
|
900
|
+
if self.spectrum is not None:
|
|
901
|
+
# 频谱表示:本征值 = k²
|
|
902
|
+
kx, ky = self.spectrum.momentum_grid
|
|
903
|
+
k2 = kx[:, None]**2 + ky[None, :]**2
|
|
904
|
+
|
|
905
|
+
# 展平并排序(降序)
|
|
906
|
+
eigenvalues = np.sort(k2.flatten())[::-1]
|
|
907
|
+
|
|
908
|
+
self._eigenvalues = eigenvalues
|
|
909
|
+
self._eigenvectors = None
|
|
910
|
+
|
|
911
|
+
elif self.frame_field is not None:
|
|
912
|
+
# 离散场:估算本征值
|
|
913
|
+
# 完整实现需要构造拉普拉斯矩阵并数值求解
|
|
914
|
+
eigenvalues_list = []
|
|
915
|
+
|
|
916
|
+
for i in range(1, self.ny - 1):
|
|
917
|
+
for j in range(1, self.nx - 1):
|
|
918
|
+
lap = self.gradient_op.laplacian((i, j))
|
|
919
|
+
eigenvalues_list.append(abs(lap))
|
|
920
|
+
|
|
921
|
+
eigenvalues = np.sort(np.array(eigenvalues_list))[::-1]
|
|
922
|
+
self._eigenvalues = eigenvalues
|
|
923
|
+
self._eigenvectors = None
|
|
924
|
+
|
|
925
|
+
return self._eigenvalues, self._eigenvectors
|
|
926
|
+
|
|
927
|
+
def expand_frame_in_eigenbasis(self, frame: 'ComplexFrame',
|
|
928
|
+
n_modes: int = 10) -> np.ndarray:
|
|
929
|
+
"""
|
|
930
|
+
将ComplexFrame展开到本征态基底
|
|
931
|
+
|
|
932
|
+
ComplexFrame = Σ_n c_n ComplexFrame_n
|
|
933
|
+
|
|
934
|
+
Args:
|
|
935
|
+
frame: 要展开的ComplexFrame
|
|
936
|
+
n_modes: 使用的模式数量
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
展开系数 c_n
|
|
940
|
+
|
|
941
|
+
数学细节:
|
|
942
|
+
c_n = ∫ φ_n*(x) ComplexFrame(x) dV
|
|
943
|
+
|
|
944
|
+
简化实现:使用傅里叶系数作为近似
|
|
945
|
+
"""
|
|
946
|
+
eigenvalues, _ = self.compute_eigenspectrum()
|
|
947
|
+
|
|
948
|
+
# 简化:使用ComplexFrame的Q因子
|
|
949
|
+
coefficients = np.zeros(n_modes, dtype=complex)
|
|
950
|
+
q_value = frame.Q
|
|
951
|
+
|
|
952
|
+
for n in range(min(n_modes, len(eigenvalues))):
|
|
953
|
+
# 简化投影:c_n ∝ Q / √λ_n
|
|
954
|
+
if eigenvalues[n] > 0:
|
|
955
|
+
coefficients[n] = q_value / np.sqrt(eigenvalues[n])
|
|
956
|
+
|
|
957
|
+
return coefficients
|
|
958
|
+
|
|
959
|
+
def reconstruct_from_modes(self, coefficients: np.ndarray,
|
|
960
|
+
base_frame: 'ComplexFrame') -> 'ComplexFrame':
|
|
961
|
+
"""
|
|
962
|
+
从本征模式重建ComplexFrame
|
|
963
|
+
|
|
964
|
+
ComplexFrame = Σ_n c_n ComplexFrame_n
|
|
965
|
+
|
|
966
|
+
Args:
|
|
967
|
+
coefficients: 展开系数
|
|
968
|
+
base_frame: 基础标架
|
|
969
|
+
|
|
970
|
+
Returns:
|
|
971
|
+
重建的ComplexFrame
|
|
972
|
+
"""
|
|
973
|
+
eigenvalues, _ = self.compute_eigenspectrum()
|
|
974
|
+
|
|
975
|
+
reconstructed_Q = 0.0 + 0j
|
|
976
|
+
for n in range(len(coefficients)):
|
|
977
|
+
if n < len(eigenvalues) and eigenvalues[n] > 0:
|
|
978
|
+
reconstructed_Q += coefficients[n] * np.sqrt(eigenvalues[n])
|
|
979
|
+
|
|
980
|
+
return ComplexFrame(base_frame.base, reconstructed_Q)
|
|
981
|
+
|
|
982
|
+
def weyl_counting(self, lambda_threshold: float) -> int:
|
|
983
|
+
"""
|
|
984
|
+
Weyl渐近计数函数
|
|
985
|
+
|
|
986
|
+
N(λ) = #{n : λ_n < λ} (小于λ的本征值个数)
|
|
987
|
+
|
|
988
|
+
Weyl律:
|
|
989
|
+
N(λ) ~ (ω_d / (2π)^d) Vol(M) λ^{d/2} (λ → ∞)
|
|
990
|
+
|
|
991
|
+
对于2维流形:N(λ) ~ (1/4π) Area(M) λ
|
|
992
|
+
|
|
993
|
+
Args:
|
|
994
|
+
lambda_threshold: 本征值阈值λ
|
|
995
|
+
|
|
996
|
+
Returns:
|
|
997
|
+
N(λ) - 本征值个数
|
|
998
|
+
"""
|
|
999
|
+
eigenvalues, _ = self.compute_eigenspectrum()
|
|
1000
|
+
return int(np.sum(eigenvalues < lambda_threshold))
|
|
1001
|
+
|
|
1002
|
+
def shape_dna(self, n_modes: int = 50) -> np.ndarray:
|
|
1003
|
+
"""
|
|
1004
|
+
形状DNA(ShapeDNA)- 流形的谱签名
|
|
1005
|
+
|
|
1006
|
+
前n个本征值 {λ_1, λ_2, ..., λ_n} 唯一标识流形的几何形状
|
|
1007
|
+
(在同谱异构的情况下)
|
|
1008
|
+
|
|
1009
|
+
这是谱几何中的核心概念:
|
|
1010
|
+
"Can one hear the shape of a drum?" - Mark Kac (1966)
|
|
1011
|
+
|
|
1012
|
+
对于2维流形,谱通常可以听出形状,但存在反例
|
|
1013
|
+
(Gordon-Webb-Wolpert, 1992)
|
|
1014
|
+
|
|
1015
|
+
Args:
|
|
1016
|
+
n_modes: 模式数量(默认50)
|
|
1017
|
+
|
|
1018
|
+
Returns:
|
|
1019
|
+
前n个本征值构成的谱签名
|
|
1020
|
+
|
|
1021
|
+
应用:
|
|
1022
|
+
- 形状识别与检索
|
|
1023
|
+
- 几何相似性度量
|
|
1024
|
+
- 拓扑不变量提取
|
|
1025
|
+
"""
|
|
1026
|
+
eigenvalues, _ = self.compute_eigenspectrum()
|
|
1027
|
+
return eigenvalues[:n_modes]
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
# ============================================================
|
|
1031
|
+
# 热核 (Heat Kernel)
|
|
1032
|
+
# ============================================================
|
|
1033
|
+
|
|
1034
|
+
class HeatKernel:
|
|
1035
|
+
"""
|
|
1036
|
+
热核 - 热方程的基本解(经典几何谱分析)
|
|
1037
|
+
|
|
1038
|
+
数学定义:
|
|
1039
|
+
∂u/∂t = Δu (热方程)
|
|
1040
|
+
K(x, y, t) = 基本解满足: ∂K/∂t = Δ_x K, K(x,y,0) = δ(x-y)
|
|
1041
|
+
|
|
1042
|
+
热核的谱展开:
|
|
1043
|
+
K(x, y, t) = Σ_n e^{-λ_n t} φ_n(x) φ_n(y)
|
|
1044
|
+
|
|
1045
|
+
其中 {λ_n, φ_n} 是拉普拉斯算子 Δφ_n = -λ_n φ_n 的本征系统。
|
|
1046
|
+
|
|
1047
|
+
热核迹的渐近展开(Minakshisundaram-Pleijel):
|
|
1048
|
+
Tr(e^{tΔ}) ~ (4πt)^{-d/2} Σ_k a_k t^k
|
|
1049
|
+
|
|
1050
|
+
热核系数 {a_k} 编码流形的几何不变量:
|
|
1051
|
+
- a₀ = Vol(M) (体积)
|
|
1052
|
+
- a₁ ∝ ∫ R dV (曲率积分)
|
|
1053
|
+
- a₂ ∝ ∫ (R² + 其他曲率不变量) dV
|
|
1054
|
+
|
|
1055
|
+
**ComplexFrame作为数学基础**:
|
|
1056
|
+
在我们的框架中,热核作为ComplexFrame在扩散过程中的演化算子:
|
|
1057
|
+
|
|
1058
|
+
ComplexFrame(x, t) = ∫ K(x, y, t) ComplexFrame(y, 0) dy
|
|
1059
|
+
= e^{tΔ} ComplexFrame(x, 0)
|
|
1060
|
+
|
|
1061
|
+
这将ComplexFrame场视为"温度分布",热核描述其扩散传播。
|
|
1062
|
+
|
|
1063
|
+
**与量子理论的关系及局限性**:
|
|
1064
|
+
- 热核在形式上等价于量子力学的虚时间传播子(Wick旋转)
|
|
1065
|
+
- 但这里是**纯几何**的扩散过程,非量子演化
|
|
1066
|
+
- 不涉及态矢量、算符期望值等量子概念
|
|
1067
|
+
- 适用于经典计算机的数值计算
|
|
1068
|
+
|
|
1069
|
+
应用:
|
|
1070
|
+
- 形状识别(ShapeDNA)
|
|
1071
|
+
- 几何不变量提取
|
|
1072
|
+
- 多尺度几何分析
|
|
1073
|
+
- 流形谱距离
|
|
1074
|
+
"""
|
|
1075
|
+
|
|
1076
|
+
def __init__(self, frame_field: Union[List[List['ComplexFrame']], 'ComplexFrameSpectrum']):
|
|
1077
|
+
"""
|
|
1078
|
+
初始化热核
|
|
1079
|
+
|
|
1080
|
+
Args:
|
|
1081
|
+
frame_field: ComplexFrame场(离散)或其频谱表示
|
|
1082
|
+
"""
|
|
1083
|
+
if isinstance(frame_field, list):
|
|
1084
|
+
# 离散标架场
|
|
1085
|
+
self.frame_field = frame_field
|
|
1086
|
+
self.gradient_op = IntrinsicGradient(frame_field)
|
|
1087
|
+
self.ny = len(frame_field)
|
|
1088
|
+
self.nx = len(frame_field[0]) if self.ny > 0 else 0
|
|
1089
|
+
self.spectrum = None
|
|
1090
|
+
else:
|
|
1091
|
+
# 频谱表示
|
|
1092
|
+
self.spectrum = frame_field
|
|
1093
|
+
self.frame_field = None
|
|
1094
|
+
self.gradient_op = None
|
|
1095
|
+
self.ny, self.nx = frame_field.shape
|
|
1096
|
+
|
|
1097
|
+
def evolution_operator(self, t: float, kappa: float = 1.0) -> Union[np.ndarray, List[List['ComplexFrame']]]:
|
|
1098
|
+
"""
|
|
1099
|
+
热核演化算子: e^{tκΔ} ComplexFrame
|
|
1100
|
+
|
|
1101
|
+
计算标架场在时间t后的扩散状态。
|
|
1102
|
+
|
|
1103
|
+
Args:
|
|
1104
|
+
t: 扩散时间(>0)
|
|
1105
|
+
kappa: 扩散系数(默认1.0)
|
|
1106
|
+
|
|
1107
|
+
Returns:
|
|
1108
|
+
演化后的标架场
|
|
1109
|
+
|
|
1110
|
+
数学细节:
|
|
1111
|
+
在频域中,热核演化简单地是:
|
|
1112
|
+
ComplexFrame(k, t) = e^{-κt|k|²} ComplexFrame(k, 0)
|
|
1113
|
+
|
|
1114
|
+
这是高频抑制(低通滤波),对应空间的平滑化。
|
|
1115
|
+
"""
|
|
1116
|
+
if t < 0:
|
|
1117
|
+
raise ValueError("扩散时间必须非负")
|
|
1118
|
+
|
|
1119
|
+
if self.frame_field is not None:
|
|
1120
|
+
# 离散场:逐点演化
|
|
1121
|
+
evolved_field = []
|
|
1122
|
+
for i in range(self.ny):
|
|
1123
|
+
row = []
|
|
1124
|
+
for j in range(self.nx):
|
|
1125
|
+
evolved_frame = self.frame_field[i][j].diffusion_evolution(t, kappa)
|
|
1126
|
+
row.append(evolved_frame)
|
|
1127
|
+
evolved_field.append(row)
|
|
1128
|
+
return evolved_field
|
|
1129
|
+
|
|
1130
|
+
elif self.spectrum is not None:
|
|
1131
|
+
# 频谱表示:频域衰减
|
|
1132
|
+
kx, ky = self.spectrum.momentum_grid
|
|
1133
|
+
k2 = kx[:, None]**2 + ky[None, :]**2
|
|
1134
|
+
|
|
1135
|
+
# e^{-κt k²} 衰减因子
|
|
1136
|
+
decay = np.exp(-kappa * t * k2)
|
|
1137
|
+
|
|
1138
|
+
# 应用到各分量
|
|
1139
|
+
evolved_spectrum = ComplexFrameSpectrum(
|
|
1140
|
+
ux_spectrum=self.spectrum.ux_spectrum * decay[..., None],
|
|
1141
|
+
uy_spectrum=self.spectrum.uy_spectrum * decay[..., None],
|
|
1142
|
+
uz_spectrum=self.spectrum.uz_spectrum * decay[..., None],
|
|
1143
|
+
origin_spectrum=self.spectrum.origin_spectrum * decay[..., None],
|
|
1144
|
+
momentum_grid=self.spectrum.momentum_grid,
|
|
1145
|
+
hbar=self.spectrum.hbar
|
|
1146
|
+
)
|
|
1147
|
+
return evolved_spectrum
|
|
1148
|
+
|
|
1149
|
+
else:
|
|
1150
|
+
raise ValueError("需要提供标架场或频谱")
|
|
1151
|
+
|
|
1152
|
+
def trace(self, t: float, kappa: float = 1.0) -> float:
|
|
1153
|
+
"""
|
|
1154
|
+
热核迹:Tr(e^{tκΔ}) = Σ_n e^{-κt λ_n}
|
|
1155
|
+
|
|
1156
|
+
这是几何信息的凝聚,包含流形谱的全部信息。
|
|
1157
|
+
|
|
1158
|
+
Args:
|
|
1159
|
+
t: 扩散时间
|
|
1160
|
+
kappa: 扩散系数
|
|
1161
|
+
|
|
1162
|
+
Returns:
|
|
1163
|
+
热核迹值
|
|
1164
|
+
"""
|
|
1165
|
+
if self.spectrum is not None:
|
|
1166
|
+
# 使用频谱表示
|
|
1167
|
+
density = self.spectrum.spectral_density()
|
|
1168
|
+
kx, ky = self.spectrum.momentum_grid
|
|
1169
|
+
k2 = kx[:, None]**2 + ky[None, :]**2
|
|
1170
|
+
|
|
1171
|
+
# Tr(e^{-κt Δ}) = Σ e^{-κt k²}
|
|
1172
|
+
trace_val = np.sum(np.exp(-kappa * t * k2))
|
|
1173
|
+
return float(trace_val)
|
|
1174
|
+
|
|
1175
|
+
elif self.frame_field is not None:
|
|
1176
|
+
# 简化估计:使用标架场的"能量"
|
|
1177
|
+
total = 0.0
|
|
1178
|
+
for i in range(self.ny):
|
|
1179
|
+
for j in range(self.nx):
|
|
1180
|
+
laplacian = self.gradient_op.laplacian((i, j))
|
|
1181
|
+
# e^{-t λ} ≈ 1 - tλ (小t近似)
|
|
1182
|
+
total += np.exp(-kappa * t * abs(laplacian))
|
|
1183
|
+
return total
|
|
1184
|
+
|
|
1185
|
+
return 0.0
|
|
1186
|
+
|
|
1187
|
+
def asymptotic_expansion(self, t: float, kappa: float = 1.0, order: int = 2) -> float:
|
|
1188
|
+
"""
|
|
1189
|
+
热核迹的渐近展开(Minakshisundaram-Pleijel公式)
|
|
1190
|
+
|
|
1191
|
+
Tr(e^{tκΔ}) ~ (4πκt)^{-d/2} [a₀ + a₁(κt) + a₂(κt)² + ...]
|
|
1192
|
+
|
|
1193
|
+
Args:
|
|
1194
|
+
t: 扩散时间(小t渐近)
|
|
1195
|
+
kappa: 扩散系数
|
|
1196
|
+
order: 展开阶数(默认2)
|
|
1197
|
+
|
|
1198
|
+
Returns:
|
|
1199
|
+
渐近估计值
|
|
1200
|
+
|
|
1201
|
+
几何意义:
|
|
1202
|
+
- a₀ = Vol(M) - 流形体积
|
|
1203
|
+
- a₁ ∝ ∫ R dV - 标量曲率积分
|
|
1204
|
+
- a₂ ∝ ∫ (R² - |Ric|² + ...) dV - 更高阶曲率不变量
|
|
1205
|
+
"""
|
|
1206
|
+
d = 2 # 2维流形
|
|
1207
|
+
prefactor = (4 * np.pi * kappa * t) ** (-d / 2)
|
|
1208
|
+
|
|
1209
|
+
# 估算热核系数
|
|
1210
|
+
a0 = float(self.ny * self.nx) # 体积(网格点数)
|
|
1211
|
+
|
|
1212
|
+
# a₁ 需要曲率信息
|
|
1213
|
+
if self.gradient_op is not None:
|
|
1214
|
+
curvature_sum = 0.0
|
|
1215
|
+
for i in range(1, self.ny - 1):
|
|
1216
|
+
for j in range(1, self.nx - 1):
|
|
1217
|
+
R_xy = self.gradient_op.commutator((i, j), 0, 1)
|
|
1218
|
+
curvature_sum += abs(R_xy)
|
|
1219
|
+
a1 = curvature_sum / 6.0
|
|
1220
|
+
else:
|
|
1221
|
+
a1 = 0.0
|
|
1222
|
+
|
|
1223
|
+
a2 = 0.0 # 简化
|
|
1224
|
+
|
|
1225
|
+
# 渐近级数
|
|
1226
|
+
expansion = a0
|
|
1227
|
+
if order >= 1:
|
|
1228
|
+
expansion += a1 * (kappa * t)
|
|
1229
|
+
if order >= 2:
|
|
1230
|
+
expansion += a2 * (kappa * t)**2
|
|
1231
|
+
|
|
1232
|
+
return prefactor * expansion
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
# ============================================================
|
|
1236
|
+
# 频率投影 (Frequency Projection)
|
|
1237
|
+
# ============================================================
|
|
1238
|
+
|
|
1239
|
+
class FrequencyProjection:
|
|
1240
|
+
"""
|
|
1241
|
+
几何频率投影算子
|
|
1242
|
+
|
|
1243
|
+
ω_n = √|κ_n| · sign(κ_n)
|
|
1244
|
+
P_Ω = Σ_{n: ω_n ∈ Ω} |Frame_n⟩⟨Frame_n|
|
|
1245
|
+
|
|
1246
|
+
应用:
|
|
1247
|
+
- 频段滤波
|
|
1248
|
+
- 多尺度分析
|
|
1249
|
+
- 频域波函数
|
|
1250
|
+
"""
|
|
1251
|
+
|
|
1252
|
+
def __init__(self, spectral_decomposition: SpectralDecomposition):
|
|
1253
|
+
"""
|
|
1254
|
+
初始化频率投影
|
|
1255
|
+
|
|
1256
|
+
Args:
|
|
1257
|
+
spectral_decomposition: 谱分解
|
|
1258
|
+
"""
|
|
1259
|
+
self.spectral = spectral_decomposition
|
|
1260
|
+
|
|
1261
|
+
def compute_frequencies(self) -> np.ndarray:
|
|
1262
|
+
"""
|
|
1263
|
+
计算几何频率:ω_n = √|κ_n| · sign(κ_n)
|
|
1264
|
+
|
|
1265
|
+
Returns:
|
|
1266
|
+
频率数组
|
|
1267
|
+
"""
|
|
1268
|
+
eigenvalues, _ = self.spectral.compute_eigenspectrum()
|
|
1269
|
+
frequencies = np.sqrt(np.abs(eigenvalues)) * np.sign(eigenvalues)
|
|
1270
|
+
return frequencies
|
|
1271
|
+
|
|
1272
|
+
def project_to_band(self, omega_min: float, omega_max: float) -> 'FrequencyBandState':
|
|
1273
|
+
"""
|
|
1274
|
+
投影到频段 [ω_min, ω_max]
|
|
1275
|
+
|
|
1276
|
+
Args:
|
|
1277
|
+
omega_min, omega_max: 频段范围
|
|
1278
|
+
|
|
1279
|
+
Returns:
|
|
1280
|
+
频段态
|
|
1281
|
+
"""
|
|
1282
|
+
frequencies = self.compute_frequencies()
|
|
1283
|
+
mask = (frequencies >= omega_min) & (frequencies <= omega_max)
|
|
1284
|
+
|
|
1285
|
+
selected_indices = np.where(mask)[0]
|
|
1286
|
+
|
|
1287
|
+
return FrequencyBandState(
|
|
1288
|
+
frequency_range=(omega_min, omega_max),
|
|
1289
|
+
mode_indices=selected_indices,
|
|
1290
|
+
projection_operator=self
|
|
1291
|
+
)
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
@dataclass
|
|
1295
|
+
class FrequencyBandState:
|
|
1296
|
+
"""频段波函数"""
|
|
1297
|
+
frequency_range: Tuple[float, float]
|
|
1298
|
+
mode_indices: np.ndarray
|
|
1299
|
+
projection_operator: FrequencyProjection
|
|
1300
|
+
|
|
1301
|
+
def wavefunction(self, amplitudes: np.ndarray, phases: np.ndarray) -> complex:
|
|
1302
|
+
"""
|
|
1303
|
+
Ψ_Ω = Σ_{n ∈ Ω} a_n Frame_n e^{iθ_n}
|
|
1304
|
+
|
|
1305
|
+
Args:
|
|
1306
|
+
amplitudes: 振幅数组
|
|
1307
|
+
phases: 相位数组
|
|
1308
|
+
|
|
1309
|
+
Returns:
|
|
1310
|
+
波函数值
|
|
1311
|
+
"""
|
|
1312
|
+
psi = 0.0 + 0j
|
|
1313
|
+
for idx, amp, phase in zip(self.mode_indices, amplitudes, phases):
|
|
1314
|
+
psi += amp * np.exp(1j * phase)
|
|
1315
|
+
return psi
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
# ============================================================
|
|
1319
|
+
# ============================================================
|
|
1320
|
+
# 谱数据结构
|
|
1321
|
+
# ============================================================
|
|
1322
|
+
|
|
1323
|
+
@dataclass
|
|
1324
|
+
class ComplexFrameSpectrum:
|
|
1325
|
+
"""
|
|
1326
|
+
复标架谱表示 - 坐标场在动量空间的表示
|
|
1327
|
+
|
|
1328
|
+
存储坐标场各分量的傅里叶谱
|
|
1329
|
+
"""
|
|
1330
|
+
ux_spectrum: np.ndarray # x轴基矢量谱
|
|
1331
|
+
uy_spectrum: np.ndarray # y轴基矢量谱
|
|
1332
|
+
uz_spectrum: np.ndarray # z轴基矢量谱
|
|
1333
|
+
origin_spectrum: np.ndarray # 原点位置谱
|
|
1334
|
+
momentum_grid: Tuple[np.ndarray, np.ndarray] # (kx, ky)
|
|
1335
|
+
hbar: float = HBAR
|
|
1336
|
+
|
|
1337
|
+
def __post_init__(self):
|
|
1338
|
+
"""验证维度一致性"""
|
|
1339
|
+
shapes = [
|
|
1340
|
+
self.ux_spectrum.shape,
|
|
1341
|
+
self.uy_spectrum.shape,
|
|
1342
|
+
self.uz_spectrum.shape,
|
|
1343
|
+
self.origin_spectrum.shape
|
|
1344
|
+
]
|
|
1345
|
+
if not all(s == shapes[0] for s in shapes):
|
|
1346
|
+
raise ValueError("所有谱分量必须具有相同维度")
|
|
1347
|
+
|
|
1348
|
+
@property
|
|
1349
|
+
def shape(self) -> Tuple[int, int]:
|
|
1350
|
+
"""谱的空间形状"""
|
|
1351
|
+
return self.ux_spectrum.shape[:2]
|
|
1352
|
+
|
|
1353
|
+
def total_energy(self) -> float:
|
|
1354
|
+
"""总能量 E = ∫ |ψ̃(k)|² dk"""
|
|
1355
|
+
return float(
|
|
1356
|
+
np.sum(np.abs(self.ux_spectrum)**2) +
|
|
1357
|
+
np.sum(np.abs(self.uy_spectrum)**2) +
|
|
1358
|
+
np.sum(np.abs(self.uz_spectrum)**2) +
|
|
1359
|
+
np.sum(np.abs(self.origin_spectrum)**2)
|
|
1360
|
+
)
|
|
1361
|
+
|
|
1362
|
+
def spectral_density(self) -> np.ndarray:
|
|
1363
|
+
"""谱密度 ρ(k) = Σ_μ |ψ̃_μ(k)|²"""
|
|
1364
|
+
density = (
|
|
1365
|
+
np.abs(self.ux_spectrum)**2 +
|
|
1366
|
+
np.abs(self.uy_spectrum)**2 +
|
|
1367
|
+
np.abs(self.uz_spectrum)**2 +
|
|
1368
|
+
np.abs(self.origin_spectrum)**2
|
|
1369
|
+
)
|
|
1370
|
+
return np.mean(density, axis=-1) if density.ndim > 2 else density
|
|
1371
|
+
|
|
1372
|
+
def radial_average(self) -> Tuple[np.ndarray, np.ndarray]:
|
|
1373
|
+
"""
|
|
1374
|
+
径向平均谱 (ShapeDNA)
|
|
1375
|
+
|
|
1376
|
+
Returns:
|
|
1377
|
+
(k_bins, radial_spectrum)
|
|
1378
|
+
"""
|
|
1379
|
+
kx, ky = self.momentum_grid
|
|
1380
|
+
k_mag = np.sqrt(kx[:, None]**2 + ky[None, :]**2)
|
|
1381
|
+
|
|
1382
|
+
density = self.spectral_density()
|
|
1383
|
+
|
|
1384
|
+
k_max = np.max(k_mag)
|
|
1385
|
+
k_bins = np.linspace(0, k_max, 50)
|
|
1386
|
+
radial_avg = np.zeros(len(k_bins))
|
|
1387
|
+
|
|
1388
|
+
for i in range(len(k_bins) - 1):
|
|
1389
|
+
mask = (k_mag >= k_bins[i]) & (k_mag < k_bins[i + 1])
|
|
1390
|
+
if np.any(mask):
|
|
1391
|
+
radial_avg[i] = np.mean(density[mask])
|
|
1392
|
+
|
|
1393
|
+
return k_bins, radial_avg
|
|
1394
|
+
|
|
1395
|
+
def to_coord_field(self) -> List[List]:
|
|
1396
|
+
"""
|
|
1397
|
+
逆变换:谱 → 坐标场
|
|
1398
|
+
|
|
1399
|
+
Returns:
|
|
1400
|
+
二维坐标场列表
|
|
1401
|
+
"""
|
|
1402
|
+
ny, nx = self.shape
|
|
1403
|
+
|
|
1404
|
+
origin_field = Frame.inverse_spectral_transform_2d(self.origin_spectrum, self.hbar)
|
|
1405
|
+
ux_field = Frame.inverse_spectral_transform_2d(self.ux_spectrum, self.hbar)
|
|
1406
|
+
uy_field = Frame.inverse_spectral_transform_2d(self.uy_spectrum, self.hbar)
|
|
1407
|
+
uz_field = Frame.inverse_spectral_transform_2d(self.uz_spectrum, self.hbar)
|
|
1408
|
+
|
|
1409
|
+
coord_field = []
|
|
1410
|
+
for i in range(ny):
|
|
1411
|
+
row = []
|
|
1412
|
+
for j in range(nx):
|
|
1413
|
+
o = vec3(origin_field[i, j, 0], origin_field[i, j, 1], origin_field[i, j, 2])
|
|
1414
|
+
ux = vec3(ux_field[i, j, 0], ux_field[i, j, 1], ux_field[i, j, 2])
|
|
1415
|
+
uy = vec3(uy_field[i, j, 0], uy_field[i, j, 1], uy_field[i, j, 2])
|
|
1416
|
+
uz = vec3(uz_field[i, j, 0], uz_field[i, j, 1], uz_field[i, j, 2])
|
|
1417
|
+
|
|
1418
|
+
c = coord3(o, quat(1, 0, 0, 0), vec3(1, 1, 1))
|
|
1419
|
+
c.ux, c.uy, c.uz = ux, uy, uz
|
|
1420
|
+
row.append(c)
|
|
1421
|
+
coord_field.append(row)
|
|
1422
|
+
|
|
1423
|
+
return coord_field
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
# ============================================================
|
|
1427
|
+
# 便利函数
|
|
1428
|
+
# ============================================================
|
|
1429
|
+
|
|
1430
|
+
def spectral_transform(coord_field: List[List],
|
|
1431
|
+
hbar: float = HBAR,
|
|
1432
|
+
use_gpu: bool = False) -> ComplexFrameSpectrum:
|
|
1433
|
+
"""
|
|
1434
|
+
坐标场谱变换
|
|
1435
|
+
|
|
1436
|
+
Args:
|
|
1437
|
+
coord_field: 二维坐标场
|
|
1438
|
+
hbar: 约化普朗克常数
|
|
1439
|
+
use_gpu: 是否使用 GPU 加速
|
|
1440
|
+
|
|
1441
|
+
Returns:
|
|
1442
|
+
ComplexFrameSpectrum 对象
|
|
1443
|
+
"""
|
|
1444
|
+
return ComplexFrame.from_coord_field(coord_field, hbar)
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
def inverse_spectral_transform(spectrum: ComplexFrameSpectrum) -> List[List]:
|
|
1448
|
+
"""
|
|
1449
|
+
逆谱变换
|
|
1450
|
+
|
|
1451
|
+
Args:
|
|
1452
|
+
spectrum: ComplexFrameSpectrum 对象
|
|
1453
|
+
|
|
1454
|
+
Returns:
|
|
1455
|
+
重建的坐标场
|
|
1456
|
+
"""
|
|
1457
|
+
return spectrum.to_coord_field()
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
# ============================================================
|
|
1461
|
+
# 演示
|
|
1462
|
+
# ============================================================
|
|
1463
|
+
|
|
1464
|
+
def demonstrate():
|
|
1465
|
+
"""演示复标架代数与谱几何"""
|
|
1466
|
+
print("=" * 70)
|
|
1467
|
+
print("复标架场与量子谱几何 (ComplexFrame Field & Spectral Geometry)")
|
|
1468
|
+
print("=" * 70)
|
|
1469
|
+
|
|
1470
|
+
# 1. 创建基础 ComplexFrame
|
|
1471
|
+
if coord3 is not None:
|
|
1472
|
+
base_frame = coord3.from_position(vec3(1, 0, 0))
|
|
1473
|
+
frame = ComplexFrame(base_frame, q_factor=1.0+0.5j)
|
|
1474
|
+
else:
|
|
1475
|
+
frame = ComplexFrame(q_factor=1.0+0.5j)
|
|
1476
|
+
|
|
1477
|
+
print(f"\n1. 基础复标架: {frame}")
|
|
1478
|
+
print(f" 相位: {frame.phase:.4f} rad")
|
|
1479
|
+
print(f" 模: {frame.magnitude:.4f}")
|
|
1480
|
+
print(f" 行列式: {frame.det:.4f}")
|
|
1481
|
+
|
|
1482
|
+
# 2. 傅里叶变换
|
|
1483
|
+
print(f"\n2. 傅里叶变换:")
|
|
1484
|
+
ft = frame.fourier_transform()
|
|
1485
|
+
print(f" F[ComplexFrame] = {ft}")
|
|
1486
|
+
print(f" F^4[ComplexFrame] ≈ ComplexFrame: {frame.fourier_transform(2*np.pi)}")
|
|
1487
|
+
|
|
1488
|
+
# 3. 共形变换
|
|
1489
|
+
print(f"\n3. 共形变换:")
|
|
1490
|
+
conf = frame.conformal_transform(2.0)
|
|
1491
|
+
print(f" λ=2: {conf}")
|
|
1492
|
+
|
|
1493
|
+
# 4. 标架复合
|
|
1494
|
+
print(f"\n4. 标架复合:")
|
|
1495
|
+
frame2 = ComplexFrame(q_factor=0.5+0.5j)
|
|
1496
|
+
composed = frame * frame2
|
|
1497
|
+
print(f" ComplexFrame1 * ComplexFrame2 = {composed}")
|
|
1498
|
+
|
|
1499
|
+
# 5. 内禀梯度算子
|
|
1500
|
+
print(f"\n5. 内禀梯度算子:")
|
|
1501
|
+
# 创建简单标架场
|
|
1502
|
+
frame_field = [[ComplexFrame(q_factor=1.0 + 0.1j*(i+j)) for j in range(5)] for i in range(5)]
|
|
1503
|
+
grad_op = IntrinsicGradient(frame_field)
|
|
1504
|
+
G_x = grad_op.compute_at((2, 2), 0)
|
|
1505
|
+
G_y = grad_op.compute_at((2, 2), 1)
|
|
1506
|
+
print(f" G_x(2,2) = {G_x:.4f}")
|
|
1507
|
+
print(f" G_y(2,2) = {G_y:.4f}")
|
|
1508
|
+
|
|
1509
|
+
# 6. 曲率计算
|
|
1510
|
+
print(f"\n6. 曲率计算:")
|
|
1511
|
+
curvature_calc = CurvatureFromFrame(frame_field)
|
|
1512
|
+
K = curvature_calc.gaussian_curvature(2, 2)
|
|
1513
|
+
H = curvature_calc.mean_curvature(2, 2)
|
|
1514
|
+
print(f" 高斯曲率 K = {K:.6f}")
|
|
1515
|
+
print(f" 平均曲率 H = {H:.6f}")
|
|
1516
|
+
|
|
1517
|
+
# 7. Berry相位
|
|
1518
|
+
print(f"\n7. Berry相位:")
|
|
1519
|
+
berry = BerryPhase(grad_op)
|
|
1520
|
+
path = [(1, 1), (1, 3), (3, 3), (3, 1), (1, 1)]
|
|
1521
|
+
gamma = berry.compute_along_path(path, closed=True)
|
|
1522
|
+
print(f" γ = ∮ G_μ dx^μ = {gamma:.4f}")
|
|
1523
|
+
|
|
1524
|
+
# 8. 陈数
|
|
1525
|
+
print(f"\n8. 陈数:")
|
|
1526
|
+
chern = ChernNumber(curvature_calc)
|
|
1527
|
+
c1 = chern.compute()
|
|
1528
|
+
print(f" 第一陈数 c₁ = {c1}")
|
|
1529
|
+
|
|
1530
|
+
print("\n" + "=" * 70)
|
|
1531
|
+
print("核心公式总结:")
|
|
1532
|
+
print(" • G_μ = d/dx^μ log ComplexFrame(x) [内禀梯度]")
|
|
1533
|
+
print(" • R_{μν} = [G_μ, G_ν] [曲率]")
|
|
1534
|
+
print(" • ComplexFrame * e^{iθ} = 傅里叶变换")
|
|
1535
|
+
print(" • ComplexFrame * λ = 共形变换")
|
|
1536
|
+
print(" • γ = ∮ G_μ dx^μ [Berry相位]")
|
|
1537
|
+
print(" • c₁ = (1/2π) ∬ R_{μν} dS [陈数]")
|
|
1538
|
+
print("=" * 70)
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
# ============================================================
|
|
1542
|
+
# 导出
|
|
1543
|
+
# ============================================================
|
|
1544
|
+
|
|
1545
|
+
__all__ = [
|
|
1546
|
+
# 核心类
|
|
1547
|
+
'ComplexFrame',
|
|
1548
|
+
'ComplexFrameSpectrum',
|
|
1549
|
+
|
|
1550
|
+
# 谱几何核心
|
|
1551
|
+
'IntrinsicGradient',
|
|
1552
|
+
'CurvatureFromFrame',
|
|
1553
|
+
'BerryPhase',
|
|
1554
|
+
'ChernNumber',
|
|
1555
|
+
'SpectralDecomposition',
|
|
1556
|
+
'HeatKernel',
|
|
1557
|
+
'FrequencyProjection',
|
|
1558
|
+
'FrequencyBandState',
|
|
1559
|
+
|
|
1560
|
+
# 便利函数
|
|
1561
|
+
'spectral_transform',
|
|
1562
|
+
'inverse_spectral_transform',
|
|
1563
|
+
|
|
1564
|
+
# 常数
|
|
1565
|
+
'HBAR',
|
|
1566
|
+
'GPU_AVAILABLE',
|
|
1567
|
+
]
|
|
1568
|
+
|
|
1569
|
+
|
|
1570
|
+
if __name__ == "__main__":
|
|
1571
|
+
demonstrate()
|