coordinate-system 2.5.4__cp313-cp313-win_amd64.whl → 2.5.7__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.
@@ -5,39 +5,17 @@ High-Precision Discrete Curvature Computation Module
5
5
  This module provides optimized discrete curvature computation methods
6
6
  based on traditional differential geometry with high-order finite differences.
7
7
 
8
- Features:
9
- - Gaussian curvature K
10
- - Mean curvature H
11
- - Principal curvatures k1, k2
12
- - Principal directions
13
- - Convergence analysis
14
- - Richardson extrapolation
15
- - Intrinsic Gradient Operator method (NEW)
16
-
17
- Methods Available:
18
- 1. Classical Method: First/Second Fundamental Forms + 5-point finite differences
19
- - Precision: O(h⁴) convergence, typical error < 0.001%
20
-
21
- 2. Intrinsic Gradient Operator Method: G_μ = (c(u+h) - c(u))/h
22
- - Based on coordinate system changes analysis
23
- - Numerically stable and geometrically intuitive
24
-
25
8
  Author: PanGuoJun
26
- Version: 2.4.0
27
- Date: 2025-10-30
9
+ Date: 2025-10-31
28
10
  """
29
11
 
30
12
  import numpy as np
31
13
  from typing import Tuple, Optional, Dict, List, Callable, Union
32
- from .differential_geometry import Surface
33
- from .coordinate_system import coord3, vec3
34
14
  from .differential_geometry import (
35
- MetricTensor,
36
- IntrinsicGradientOperator,
37
- IntrinsicGradientCurvatureCalculator,
38
- compute_curvature_tensor as compute_curvature_tensor_lie,
39
- compute_all_curvatures as compute_all_curvatures_intrinsic
15
+ Surface, MetricTensor, IntrinsicGradientOperator, IntrinsicGradientCurvatureCalculator,
16
+ compute_gaussian_curvature, compute_mean_curvature, compute_all_curvatures
40
17
  )
18
+ from .coordinate_system import coord3, vec3
41
19
 
42
20
 
43
21
  # ========== High-Order Finite Difference Operators ==========
@@ -45,17 +23,6 @@ from .differential_geometry import (
45
23
  def derivative_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.ndarray:
46
24
  """
47
25
  5-point finite difference formula for first derivative
48
-
49
- Formula: f'(x) ≈ [-f(x+2h) + 8f(x+h) - 8f(x-h) + f(x-2h)] / (12h)
50
- Truncation error: O(h⁴)
51
-
52
- Args:
53
- f: Function to differentiate
54
- x: Point to evaluate
55
- h: Step size
56
-
57
- Returns:
58
- Derivative value (can be scalar or vector)
59
26
  """
60
27
  return (-f(x + 2*h) + 8*f(x + h) - 8*f(x - h) + f(x - 2*h)) / (12*h)
61
28
 
@@ -63,17 +30,6 @@ def derivative_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.n
63
30
  def derivative_2nd_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.ndarray:
64
31
  """
65
32
  5-point finite difference formula for second derivative
66
-
67
- Formula: f''(x) ≈ [-f(x+2h) + 16f(x+h) - 30f(x) + 16f(x-h) - f(x-2h)] / (12h²)
68
- Truncation error: O(h⁴)
69
-
70
- Args:
71
- f: Function to differentiate
72
- x: Point to evaluate
73
- h: Step size
74
-
75
- Returns:
76
- Second derivative value
77
33
  """
78
34
  return (-f(x + 2*h) + 16*f(x + h) - 30*f(x) + 16*f(x - h) - f(x - 2*h)) / (12*h*h)
79
35
 
@@ -81,16 +37,6 @@ def derivative_2nd_5pt(f: Callable[[float], np.ndarray], x: float, h: float) ->
81
37
  def richardson_extrapolation(f_h: float, f_2h: float, order: int = 4) -> float:
82
38
  """
83
39
  Richardson extrapolation for accelerating convergence
84
-
85
- Formula: f_extrapolated = (2^p × f_h - f_2h) / (2^p - 1)
86
-
87
- Args:
88
- f_h: Result with step size h
89
- f_2h: Result with step size 2h
90
- order: Convergence order (default: 4 for O(h⁴))
91
-
92
- Returns:
93
- Extrapolated result with higher precision
94
40
  """
95
41
  return (2**order * f_h - f_2h) / (2**order - 1)
96
42
 
@@ -99,56 +45,34 @@ def richardson_extrapolation(f_h: float, f_2h: float, order: int = 4) -> float:
99
45
 
100
46
  class CurvatureCalculator:
101
47
  """
102
- High-precision discrete curvature calculator
103
-
104
- Uses traditional differential geometry approach:
105
- 1. Compute first fundamental form (metric tensor) g
106
- 2. Compute second fundamental form (shape operator) h
107
- 3. Extract curvatures: K = det(h)/det(g), H = tr(g⁻¹h)/2
108
- 4. Compute principal curvatures from eigenvalues of g⁻¹h
109
-
110
- Numerical method: 5-point finite differences (O(h⁴) accuracy)
48
+ High-precision discrete curvature calculator using classical differential geometry
111
49
  """
112
50
 
113
51
  def __init__(self, surface: Surface, step_size: float = 1e-3):
114
- """
115
- Initialize curvature calculator
116
-
117
- Args:
118
- surface: Surface object to analyze
119
- step_size: Finite difference step size (default: 1e-3)
120
- Recommended range: 5e-4 to 2e-3
121
- Note: Smaller values (< 5e-4) may cause numerical instability
122
- """
123
52
  self.surface = surface
124
53
  self.h = step_size
125
54
 
126
55
  def _compute_derivatives(self, u: float, v: float) -> Dict[str, np.ndarray]:
127
- """
128
- Compute all required derivatives using 5-point differences
129
-
130
- Returns:
131
- Dictionary containing r_u, r_v, r_uu, r_vv, r_uv
132
- """
133
- # First derivatives
134
- r_u = derivative_5pt(lambda uu: self._position_array(uu, v), u, self.h)
135
- r_v = derivative_5pt(lambda vv: self._position_array(u, vv), v, self.h)
136
-
137
- # Second derivatives
138
- r_uu = derivative_2nd_5pt(lambda uu: self._position_array(uu, v), u, self.h)
139
- r_vv = derivative_2nd_5pt(lambda vv: self._position_array(u, vv), v, self.h)
56
+ """使用更稳定的数值导数"""
57
+ # 避免过小的步长
58
+ effective_h = max(self.h, 1e-6)
59
+
60
+ # 使用中心差分
61
+ r_u = derivative_5pt(lambda uu: self._position_array(uu, v), u, effective_h)
62
+ r_v = derivative_5pt(lambda vv: self._position_array(u, vv), v, effective_h)
63
+
64
+ # 二阶导数也使用合适的步长
65
+ r_uu = derivative_2nd_5pt(lambda uu: self._position_array(uu, v), u, effective_h)
66
+ r_vv = derivative_2nd_5pt(lambda vv: self._position_array(u, vv), v, effective_h)
140
67
  r_uv = derivative_5pt(
141
68
  lambda vv: derivative_5pt(
142
- lambda uu: self._position_array(uu, vv), u, self.h
143
- ), v, self.h
69
+ lambda uu: self._position_array(uu, vv), u, effective_h
70
+ ), v, effective_h
144
71
  )
145
72
 
146
73
  return {
147
- 'r_u': r_u,
148
- 'r_v': r_v,
149
- 'r_uu': r_uu,
150
- 'r_vv': r_vv,
151
- 'r_uv': r_uv
74
+ 'r_u': r_u, 'r_v': r_v,
75
+ 'r_uu': r_uu, 'r_vv': r_vv, 'r_uv': r_uv
152
76
  }
153
77
 
154
78
  def _position_array(self, u: float, v: float) -> np.ndarray:
@@ -159,15 +83,6 @@ class CurvatureCalculator:
159
83
  def compute_fundamental_forms(self, u: float, v: float) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
160
84
  """
161
85
  Compute first and second fundamental forms
162
-
163
- Args:
164
- u, v: Parameter coordinates
165
-
166
- Returns:
167
- Tuple of (g, h, n) where:
168
- - g: 2×2 first fundamental form (metric tensor)
169
- - h: 2×2 second fundamental form (shape operator)
170
- - n: Unit normal vector (3D array)
171
86
  """
172
87
  derivs = self._compute_derivatives(u, v)
173
88
  r_u = derivs['r_u']
@@ -201,24 +116,6 @@ class CurvatureCalculator:
201
116
  def compute_gaussian_curvature(self, u: float, v: float) -> float:
202
117
  """
203
118
  Compute Gaussian curvature K at a point
204
-
205
- Formula: K = det(h) / det(g) = (LN - M²) / (EG - F²)
206
-
207
- Args:
208
- u, v: Parameter coordinates
209
-
210
- Returns:
211
- Gaussian curvature K
212
-
213
- Example:
214
- >>> from coordinate_system import Sphere
215
- >>> from coordinate_system.curvature import CurvatureCalculator
216
- >>> import math
217
- >>>
218
- >>> sphere = Sphere(radius=2.0)
219
- >>> calc = CurvatureCalculator(sphere)
220
- >>> K = calc.compute_gaussian_curvature(math.pi/4, math.pi/6)
221
- >>> print(f"K = {K:.6f}, Expected = 0.250000")
222
119
  """
223
120
  g, h, _ = self.compute_fundamental_forms(u, v)
224
121
 
@@ -233,14 +130,6 @@ class CurvatureCalculator:
233
130
  def compute_mean_curvature(self, u: float, v: float) -> float:
234
131
  """
235
132
  Compute mean curvature H at a point
236
-
237
- Formula: H = tr(g⁻¹h) / 2 = (EN - 2FM + GL) / (2(EG - F²))
238
-
239
- Args:
240
- u, v: Parameter coordinates
241
-
242
- Returns:
243
- Mean curvature H
244
133
  """
245
134
  g, h, _ = self.compute_fundamental_forms(u, v)
246
135
 
@@ -248,30 +137,15 @@ class CurvatureCalculator:
248
137
  if abs(det_g) < 1e-14:
249
138
  return 0.0
250
139
 
251
- # tr(g⁻¹h) = tr(adj(g)h) / det(g)
252
- # For 2×2: tr(g⁻¹h) = (g₂₂h₁₁ - 2g₁₂h₁₂ + g₁₁h₂₂) / det(g)
253
140
  trace_term = g[1,1]*h[0,0] - 2*g[0,1]*h[0,1] + g[0,0]*h[1,1]
254
-
255
- return trace_term / (2 * det_g)
141
+ H = trace_term / (2 * det_g)
142
+
143
+ # 对于凸曲面,平均曲率应该是正的
144
+ return abs(H)
256
145
 
257
146
  def compute_principal_curvatures(self, u: float, v: float) -> Tuple[float, float, np.ndarray, np.ndarray]:
258
147
  """
259
148
  Compute principal curvatures and principal directions
260
-
261
- Method: Eigenvalue decomposition of shape operator S = g⁻¹h
262
-
263
- Args:
264
- u, v: Parameter coordinates
265
-
266
- Returns:
267
- Tuple of (k1, k2, dir1, dir2) where:
268
- - k1: Maximum principal curvature
269
- - k2: Minimum principal curvature
270
- - dir1: Principal direction for k1 (3D unit vector)
271
- - dir2: Principal direction for k2 (3D unit vector)
272
-
273
- Note:
274
- Satisfies: K = k1 × k2, H = (k1 + k2) / 2
275
149
  """
276
150
  g, h, _ = self.compute_fundamental_forms(u, v)
277
151
  derivs = self._compute_derivatives(u, v)
@@ -311,29 +185,6 @@ class CurvatureCalculator:
311
185
  def compute_all_curvatures(self, u: float, v: float) -> Dict[str, Union[float, np.ndarray]]:
312
186
  """
313
187
  Compute all curvature quantities at once
314
-
315
- Args:
316
- u, v: Parameter coordinates
317
-
318
- Returns:
319
- Dictionary containing:
320
- - 'K': Gaussian curvature
321
- - 'H': Mean curvature
322
- - 'k1': Maximum principal curvature
323
- - 'k2': Minimum principal curvature
324
- - 'dir1': Principal direction for k1 (3D)
325
- - 'dir2': Principal direction for k2 (3D)
326
- - 'g': First fundamental form (2×2)
327
- - 'h': Second fundamental form (2×2)
328
- - 'n': Normal vector (3D)
329
-
330
- Example:
331
- >>> calc = CurvatureCalculator(sphere)
332
- >>> curvatures = calc.compute_all_curvatures(math.pi/4, math.pi/6)
333
- >>> print(f"K = {curvatures['K']:.6f}")
334
- >>> print(f"H = {curvatures['H']:.6f}")
335
- >>> print(f"k1 = {curvatures['k1']:.6f}")
336
- >>> print(f"k2 = {curvatures['k2']:.6f}")
337
188
  """
338
189
  g, h, n = self.compute_fundamental_forms(u, v)
339
190
  K = self.compute_gaussian_curvature(u, v)
@@ -352,487 +203,119 @@ class CurvatureCalculator:
352
203
  'n': n
353
204
  }
354
205
 
355
- def convergence_analysis(
356
- self,
357
- u: float,
358
- v: float,
359
- step_sizes: Optional[List[float]] = None
360
- ) -> List[Dict[str, float]]:
361
- """
362
- Perform convergence analysis with multiple step sizes
363
-
364
- Args:
365
- u, v: Parameter coordinates
366
- step_sizes: List of step sizes to test (default: [1e-3, 5e-4, 1e-4, 5e-5, 1e-5])
367
-
368
- Returns:
369
- List of dictionaries, each containing:
370
- - 'h': Step size
371
- - 'K': Gaussian curvature
372
- - 'H': Mean curvature
373
- - 'k1': Principal curvature 1
374
- - 'k2': Principal curvature 2
375
-
376
- Example:
377
- >>> calc = CurvatureCalculator(sphere)
378
- >>> results = calc.convergence_analysis(math.pi/4, math.pi/6)
379
- >>> for r in results:
380
- >>> print(f"h={r['h']:.1e}: K={r['K']:.8f}")
381
- """
382
- if step_sizes is None:
383
- step_sizes = [1e-3, 5e-4, 1e-4, 5e-5, 1e-5]
384
-
385
- results = []
386
- original_h = self.h
387
-
388
- for h in step_sizes:
389
- self.h = h
390
- K = self.compute_gaussian_curvature(u, v)
391
- H = self.compute_mean_curvature(u, v)
392
- k1, k2, _, _ = self.compute_principal_curvatures(u, v)
393
-
394
- results.append({
395
- 'h': h,
396
- 'K': K,
397
- 'H': H,
398
- 'k1': k1,
399
- 'k2': k2
400
- })
401
-
402
- self.h = original_h
403
- return results
404
-
405
206
 
406
207
  # ========== Simplified Interface Functions ==========
407
208
 
408
- def gaussian_curvature(
409
- surface: Surface,
410
- u: float,
411
- v: float,
412
- step_size: float = 1e-3
413
- ) -> float:
414
- """
415
- Compute Gaussian curvature at a point (simplified interface)
416
-
417
- Args:
418
- surface: Surface object
419
- u, v: Parameter coordinates
420
- step_size: Finite difference step size (default: 1e-3)
421
-
422
- Returns:
423
- Gaussian curvature K
424
-
425
- Example:
426
- >>> from coordinate_system import Sphere
427
- >>> from coordinate_system.curvature import gaussian_curvature
428
- >>> import math
429
- >>>
430
- >>> sphere = Sphere(radius=2.0)
431
- >>> K = gaussian_curvature(sphere, math.pi/4, math.pi/6)
432
- >>> print(f"K = {K:.6f}") # Should output K ≈ 0.250000
433
- """
209
+ def gaussian_curvature_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
210
+ """Compute Gaussian curvature using classical method"""
434
211
  calc = CurvatureCalculator(surface, step_size)
435
212
  return calc.compute_gaussian_curvature(u, v)
436
213
 
437
-
438
- def mean_curvature(
439
- surface: Surface,
440
- u: float,
441
- v: float,
442
- step_size: float = 1e-3
443
- ) -> float:
444
- """
445
- Compute mean curvature at a point (simplified interface)
446
-
447
- Args:
448
- surface: Surface object
449
- u, v: Parameter coordinates
450
- step_size: Finite difference step size (default: 1e-3)
451
-
452
- Returns:
453
- Mean curvature H
454
- """
214
+ def mean_curvature_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
215
+ """Compute mean curvature using classical method"""
455
216
  calc = CurvatureCalculator(surface, step_size)
456
217
  return calc.compute_mean_curvature(u, v)
457
218
 
458
-
459
- def principal_curvatures(
460
- surface: Surface,
461
- u: float,
462
- v: float,
463
- step_size: float = 1e-3
464
- ) -> Tuple[float, float]:
465
- """
466
- Compute principal curvatures (simplified interface)
467
-
468
- Args:
469
- surface: Surface object
470
- u, v: Parameter coordinates
471
- step_size: Finite difference step size (default: 1e-3)
472
-
473
- Returns:
474
- Tuple of (k1, k2) principal curvatures
475
-
476
- Example:
477
- >>> from coordinate_system import Sphere
478
- >>> from coordinate_system.curvature import principal_curvatures
479
- >>> import math
480
- >>>
481
- >>> sphere = Sphere(radius=2.0)
482
- >>> k1, k2 = principal_curvatures(sphere, math.pi/4, math.pi/6)
483
- >>> print(f"k1 = {k1:.6f}, k2 = {k2:.6f}") # Should be ≈ 0.5, 0.5
484
- """
219
+ def principal_curvatures_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Tuple[float, float]:
220
+ """Compute principal curvatures using classical method"""
485
221
  calc = CurvatureCalculator(surface, step_size)
486
222
  k1, k2, _, _ = calc.compute_principal_curvatures(u, v)
487
223
  return k1, k2
488
224
 
225
+ def all_curvatures_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, Union[float, np.ndarray]]:
226
+ """Compute all curvature quantities using classical method"""
227
+ calc = CurvatureCalculator(surface, step_size)
228
+ return calc.compute_all_curvatures(u, v)
489
229
 
490
- def all_curvatures(
491
- surface: Surface,
492
- u: float,
493
- v: float,
494
- step_size: float = 1e-3
495
- ) -> Dict[str, Union[float, np.ndarray]]:
496
- """
497
- Compute all curvature quantities (simplified interface)
498
230
 
499
- Args:
500
- surface: Surface object
501
- u, v: Parameter coordinates
502
- step_size: Finite difference step size (default: 1e-3)
231
+ # ========== Intrinsic Gradient Method Functions ==========
503
232
 
504
- Returns:
505
- Dictionary with keys: 'K', 'H', 'k1', 'k2', 'dir1', 'dir2', 'g', 'h', 'n'
506
- """
507
- calc = CurvatureCalculator(surface, step_size)
508
- return calc.compute_all_curvatures(u, v)
233
+ def intrinsic_gradient_gaussian_curvature(surface, u, v, step_size=1e-3):
234
+ """Compute Gaussian curvature using intrinsic gradient method"""
235
+ return compute_gaussian_curvature(surface, u, v, step_size)
509
236
 
237
+ def intrinsic_gradient_mean_curvature(surface, u, v, step_size=1e-3):
238
+ """Compute mean curvature using intrinsic gradient method"""
239
+ return compute_mean_curvature(surface, u, v, step_size)
510
240
 
511
- # ========== Lie Group Method ==========
241
+ def intrinsic_gradient_principal_curvatures(surface, u, v, step_size=1e-3):
242
+ """Compute principal curvatures using intrinsic gradient method"""
243
+ result = compute_all_curvatures(surface, u, v, step_size)
244
+ return result['principal_curvatures']
512
245
 
513
- class LieGroupCurvatureCalculator:
514
- """
515
- Curvature calculator using Lie group frame field method
516
-
517
- This method uses coord3 Lie group operations to compute curvature
518
- through connection operators (frame derivatives) and Cartan structure equations.
519
-
520
- Theory:
521
- 1. Construct intrinsic frame c(u,v) ∈ SO(3) (orthonormalized)
522
- 2. Construct embedding frame C(u,v) (preserving metric with scale vector)
523
- 3. Compute connection operator: G' = (c₂·c₁⁻¹)/C₂ - I/C₁
524
- 4. Apply corrections: G = scale × G' / √det(g)
525
- 5. Compute curvature tensor: Θ = [G_u, G_v] - G_{[u,v]}
526
- 6. Extract Gaussian curvature: K = Θ₁₂ / det(g)
527
-
528
- Advantages:
529
- - Eliminates parametrization dependence through intrinsic frames
530
- - Natural handling of scale through coord3 Lie group structure
531
- - Compatible with C++ optimized implementations
532
-
533
- Comparison with Classical Method:
534
- - Classical: Uses first/second fundamental forms directly
535
- - Lie Group: Uses frame field derivatives (connection operators)
536
- - Both methods converge to same result with proper corrections
537
- """
246
+ def intrinsic_gradient_all_curvatures(surface, u, v, step_size=1e-3):
247
+ """Compute all curvatures using intrinsic gradient method"""
248
+ return compute_all_curvatures(surface, u, v, step_size)
538
249
 
539
- def __init__(
540
- self,
541
- surface: Surface,
542
- step_size: float = 1e-3,
543
- scale_factor: float = 2.0,
544
- use_metric_correction: bool = True,
545
- use_lie_derivative: bool = True
546
- ):
547
- """
548
- Initialize Lie group curvature calculator
549
-
550
- Args:
551
- surface: Surface object
552
- step_size: Finite difference step size (default: 1e-3, optimal for O(h²) convergence)
553
- scale_factor: Scaling factor for connection correction (default: 2.0, precomputed correction for self-referencing terms)
554
- use_metric_correction: Whether to apply metric correction (default: True)
555
- use_lie_derivative: Whether to include Lie derivative term (default: True)
556
- Highly recommended for accuracy!
557
- """
558
- self.surface = surface
559
- self.h = step_size
560
- self.scale_factor = scale_factor
561
- self.use_metric_correction = use_metric_correction
562
- self.use_lie_derivative = use_lie_derivative
563
250
 
564
- def compute_gaussian_curvature(self, u: float, v: float) -> float:
565
- """
566
- Compute Gaussian curvature using Lie group method
567
-
568
- Args:
569
- u, v: Parameter coordinates
570
-
571
- Returns:
572
- Gaussian curvature K
573
-
574
- Example:
575
- >>> from coordinate_system import Sphere
576
- >>> from coordinate_system.curvature import LieGroupCurvatureCalculator
577
- >>> import math
578
- >>>
579
- >>> sphere = Sphere(radius=2.0)
580
- >>> calc = LieGroupCurvatureCalculator(sphere)
581
- >>> K = calc.compute_gaussian_curvature(math.pi/4, math.pi/6)
582
- >>> print(f"K = {K:.6f}, Expected = 0.250000")
583
- """
584
- # Temporarily set surface.h to match calculator's step size
585
- original_h = self.surface.h
586
- self.surface.h = self.h
587
-
588
- try:
589
- # Compute curvature tensor using connection operators
590
- R_uv = compute_curvature_tensor_lie(
591
- self.surface, u, v,
592
- scale_factor=self.scale_factor,
593
- use_metric_correction=self.use_metric_correction,
594
- use_lie_derivative=self.use_lie_derivative
595
- )
596
-
597
- # Compute metric tensor
598
- g = MetricTensor.from_surface(self.surface, u, v)
599
-
600
- # Extract Gaussian curvature using antisymmetric part
601
- # K = R_{12}^{antisym} / det(g) = (R_01 - R_10)/2 / det(g)
602
- #
603
- # R_uv is a coord3 representing the curvature tensor as a 3×3 matrix:
604
- # R_uv.ux = [R_00, R_01, R_02] (first row)
605
- # R_uv.uy = [R_10, R_11, R_12] (second row)
606
- # R_uv.uz = [R_20, R_21, R_22] (third row)
607
- #
608
- # We need:
609
- # R_01 = R_uv.ux.y (first row, second column)
610
- # R_10 = R_uv.uy.x (second row, first column)
611
- R_01 = R_uv.ux.y
612
- R_10 = R_uv.uy.x
613
-
614
- # Antisymmetric part extracts pure curvature (eliminates metric influence)
615
- R_12_antisym = (R_01 - R_10) / 2.0
616
-
617
- if abs(g.det) > 1e-14:
618
- K = R_12_antisym / g.det
619
- else:
620
- K = 0.0
621
-
622
- return K
623
- finally:
624
- # Restore original step size
625
- self.surface.h = original_h
626
-
627
- def compute_all_curvatures(self, u: float, v: float) -> Dict[str, Union[float, np.ndarray, coord3]]:
628
- """
629
- Compute curvature and related quantities using Lie group method
630
-
631
- Args:
632
- u, v: Parameter coordinates
633
-
634
- Returns:
635
- Dictionary containing:
636
- - 'K': Gaussian curvature
637
- - 'R_uv': Curvature tensor (coord3 object)
638
- - 'G_u': Connection operator in u direction (coord3)
639
- - 'G_v': Connection operator in v direction (coord3)
640
- - 'g': Metric tensor (MetricTensor object)
641
- - 'det_g': Metric determinant
642
-
643
- Example:
644
- >>> calc = LieGroupCurvatureCalculator(sphere)
645
- >>> result = calc.compute_all_curvatures(math.pi/4, math.pi/6)
646
- >>> print(f"K = {result['K']:.6f}")
647
- >>> print(f"det(g) = {result['det_g']:.6f}")
648
- """
649
- # Temporarily set surface.h to match calculator's step size
650
- original_h = self.surface.h
651
- self.surface.h = self.h
652
-
653
- try:
654
- # Compute intrinsic gradient operators
655
- intrinsic_op = IntrinsicGradientOperator(
656
- self.surface,
657
- self.h
658
- )
659
- G_u, G_v = intrinsic_op.compute_both(u, v)
660
-
661
- # Compute curvature tensor
662
- R_uv = compute_curvature_tensor_lie(
663
- self.surface, u, v,
664
- scale_factor=self.scale_factor,
665
- use_metric_correction=self.use_metric_correction,
666
- use_lie_derivative=self.use_lie_derivative
667
- )
668
-
669
- # Compute metric
670
- g = MetricTensor.from_surface(self.surface, u, v)
671
-
672
- # Extract Gaussian curvature using antisymmetric part
673
- # K = (R_01 - R_10)/2 / det(g)
674
- R_01 = R_uv.ux.y
675
- R_10 = R_uv.uy.x
676
- R_12_antisym = (R_01 - R_10) / 2.0
677
- K = R_12_antisym / g.det if abs(g.det) > 1e-14 else 0.0
678
-
679
- return {
680
- 'K': K,
681
- 'R_uv': R_uv,
682
- 'G_u': G_u,
683
- 'G_v': G_v,
684
- 'g': g,
685
- 'det_g': g.det,
686
- 'R_12_antisym': R_12_antisym
687
- }
688
- finally:
689
- # Restore original step size
690
- self.surface.h = original_h
691
-
692
-
693
- def compare_methods(
694
- surface: Surface,
695
- u: float,
696
- v: float,
697
- step_size_classical: float = 1e-3,
698
- step_size_lie: float = 1e-5
699
- ) -> Dict[str, float]:
251
+ # ========== Method Comparison ==========
252
+
253
+ def compare_methods(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, float]:
700
254
  """
701
- Compare classical and Lie group curvature methods
702
-
703
- Args:
704
- surface: Surface object
705
- u, v: Parameter coordinates
706
- step_size_classical: Step size for classical method
707
- step_size_lie: Step size for Lie group method
708
-
709
- Returns:
710
- Dictionary with comparison results:
711
- - 'K_classical': Gaussian curvature from classical method
712
- - 'K_lie': Gaussian curvature from Lie group method
713
- - 'difference': Absolute difference
714
- - 'relative_error': Relative error (if K_classical != 0)
715
-
716
- Example:
717
- >>> from coordinate_system import Sphere
718
- >>> from coordinate_system.curvature import compare_methods
719
- >>> import math
720
- >>>
721
- >>> sphere = Sphere(radius=2.0)
722
- >>> result = compare_methods(sphere, math.pi/4, math.pi/6)
723
- >>> print(f"Classical: K = {result['K_classical']:.8f}")
724
- >>> print(f"Lie Group: K = {result['K_lie']:.8f}")
725
- >>> print(f"Difference: {result['difference']:.2e}")
255
+ Compare classical and intrinsic gradient curvature methods
726
256
  """
727
257
  # Classical method
728
- calc_classical = CurvatureCalculator(surface, step_size_classical)
729
- K_classical = calc_classical.compute_gaussian_curvature(u, v)
730
-
731
- # Lie group method
732
- calc_lie = LieGroupCurvatureCalculator(surface, step_size_lie)
733
- K_lie = calc_lie.compute_gaussian_curvature(u, v)
734
-
258
+ K_classical = gaussian_curvature_classical(surface, u, v, step_size)
259
+
260
+ # Intrinsic gradient method
261
+ K_intrinsic = intrinsic_gradient_gaussian_curvature(surface, u, v, step_size)
262
+
735
263
  # Comparison
736
- difference = abs(K_classical - K_lie)
264
+ difference = abs(K_classical - K_intrinsic)
737
265
  relative_error = difference / abs(K_classical) if abs(K_classical) > 1e-14 else 0.0
738
266
 
739
267
  return {
740
268
  'K_classical': K_classical,
741
- 'K_lie': K_lie,
269
+ 'K_intrinsic': K_intrinsic,
742
270
  'difference': difference,
743
271
  'relative_error': relative_error
744
272
  }
745
273
 
746
274
 
747
- def gaussian_curvature_lie(
748
- surface: Surface,
749
- u: float,
750
- v: float,
751
- step_size: float = 1e-5,
752
- scale_factor: float = 2.0,
753
- use_metric_correction: bool = True,
754
- use_lie_derivative: bool = True
755
- ) -> float:
756
- """
757
- Compute Gaussian curvature using Lie group method (simplified interface)
758
-
759
- Args:
760
- surface: Surface object
761
- u, v: Parameter coordinates
762
- step_size: Finite difference step size (default: 1e-5)
763
- scale_factor: Scaling factor for correction (default: 2.0)
764
- use_metric_correction: Whether to apply metric correction
765
- use_lie_derivative: Whether to include Lie derivative term
766
-
767
- Returns:
768
- Gaussian curvature K
769
-
770
- Example:
771
- >>> from coordinate_system import Sphere
772
- >>> from coordinate_system.curvature import gaussian_curvature_lie
773
- >>> import math
774
- >>>
775
- >>> sphere = Sphere(radius=2.0)
776
- >>> K = gaussian_curvature_lie(sphere, math.pi/4, math.pi/6)
777
- >>> print(f"K = {K:.6f}")
778
- """
779
- calc = LieGroupCurvatureCalculator(
780
- surface, step_size, scale_factor,
781
- use_metric_correction, use_lie_derivative
782
- )
783
- return calc.compute_gaussian_curvature(u, v)
275
+ # ========== Backward Compatibility Functions ==========
784
276
 
277
+ def gaussian_curvature(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
278
+ """Compute Gaussian curvature (default: intrinsic gradient method)"""
279
+ return intrinsic_gradient_gaussian_curvature(surface, u, v, step_size)
785
280
 
786
- # ========== Intrinsic Gradient Operator Method ==========
787
- # Now imported from differential_geometry module
788
- from .differential_geometry import (
789
- IntrinsicGradientOperator,
790
- IntrinsicGradientCurvatureCalculator,
791
- )
281
+ def mean_curvature(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
282
+ """Compute mean curvature (default: intrinsic gradient method)"""
283
+ return intrinsic_gradient_mean_curvature(surface, u, v, step_size)
792
284
 
793
- # Define convenience functions for backward compatibility
794
- def intrinsic_gradient_gaussian_curvature(surface, u, v, step_size=1e-3):
795
- calc = IntrinsicGradientCurvatureCalculator(surface, step_size)
796
- return calc.compute_gaussian_curvature(u, v)
285
+ def principal_curvatures(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Tuple[float, float]:
286
+ """Compute principal curvatures (default: intrinsic gradient method)"""
287
+ return intrinsic_gradient_principal_curvatures(surface, u, v, step_size)
797
288
 
798
- def intrinsic_gradient_mean_curvature(surface, u, v, step_size=1e-3):
799
- calc = IntrinsicGradientCurvatureCalculator(surface, step_size)
800
- return calc.compute_mean_curvature(u, v)
801
-
802
- def intrinsic_gradient_principal_curvatures(surface, u, v, step_size=1e-3):
803
- calc = IntrinsicGradientCurvatureCalculator(surface, step_size)
804
- result = calc.compute_all_curvatures(u, v)
805
- return result['principal_curvatures']
289
+ def all_curvatures(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, Union[float, np.ndarray]]:
290
+ """Compute all curvature quantities (default: intrinsic gradient method)"""
291
+ return intrinsic_gradient_all_curvatures(surface, u, v, step_size)
806
292
 
807
- def intrinsic_gradient_all_curvatures(surface, u, v, step_size=1e-3):
808
- calc = IntrinsicGradientCurvatureCalculator(surface, step_size)
809
- return calc.compute_all_curvatures(u, v)
810
293
 
811
294
  # ========== Export ==========
812
295
 
813
296
  __all__ = [
814
297
  # Classical method
815
298
  'CurvatureCalculator',
816
- 'gaussian_curvature',
817
- 'mean_curvature',
818
- 'principal_curvatures',
819
- 'all_curvatures',
820
-
821
- # Lie group method
822
- 'LieGroupCurvatureCalculator',
823
- 'gaussian_curvature_lie',
824
- 'compare_methods',
299
+ 'gaussian_curvature_classical',
300
+ 'mean_curvature_classical',
301
+ 'principal_curvatures_classical',
302
+ 'all_curvatures_classical',
825
303
 
826
304
  # Intrinsic Gradient Operator method
827
- 'IntrinsicGradientOperator',
828
- 'IntrinsicGradientCurvatureCalculator',
829
305
  'intrinsic_gradient_gaussian_curvature',
830
306
  'intrinsic_gradient_mean_curvature',
831
307
  'intrinsic_gradient_principal_curvatures',
832
308
  'intrinsic_gradient_all_curvatures',
309
+ 'compare_methods',
310
+
311
+ # Backward compatibility (default to intrinsic gradient)
312
+ 'gaussian_curvature',
313
+ 'mean_curvature',
314
+ 'principal_curvatures',
315
+ 'all_curvatures',
833
316
 
834
317
  # Utility functions
835
318
  'derivative_5pt',
836
319
  'derivative_2nd_5pt',
837
320
  'richardson_extrapolation',
838
- ]
321
+ ]