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.
@@ -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()