coordinate-system 2.5.0__cp313-cp313-win_amd64.whl → 2.5.3__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.
@@ -4,26 +4,21 @@ from .coordinate_system import vec3, vec2
4
4
  from .coordinate_system import quat
5
5
  from .coordinate_system import coord3
6
6
 
7
- # Differential geometry module (v2.2.0+)
7
+ # Differential geometry module (v3.0.0+)
8
8
  from .differential_geometry import (
9
9
  # Classes
10
10
  Surface,
11
11
  Sphere,
12
12
  Torus,
13
13
  MetricTensor,
14
- ConnectionOperator,
14
+ IntrinsicGradientOperator,
15
+ IntrinsicGradientCurvatureCalculator,
15
16
 
16
17
  # Main functions
17
- compute_metric,
18
- compute_connection,
19
- compute_curvature_tensor,
20
- compute_gaussian_curvature,
21
-
22
- # Aliases
23
- compute_frame_derivative,
24
18
  compute_intrinsic_gradient,
25
- compute_geometric_gradient,
26
- compute_metric_tensor,
19
+ compute_gaussian_curvature,
20
+ compute_curvature_tensor,
21
+ compute_all_curvatures,
27
22
  )
28
23
 
29
24
  # High-precision curvature computation module (v2.3.0+)
@@ -47,9 +42,8 @@ from .curvature import (
47
42
  )
48
43
 
49
44
  # Intrinsic Gradient Operator method (v2.4.0+)
50
- from .intrinsic_gradient_curvature import (
51
- IntrinsicGradientOperator,
52
- IntrinsicGradientCurvatureCalculator,
45
+ # Now imported from curvature module for backward compatibility
46
+ from .curvature import (
53
47
  intrinsic_gradient_gaussian_curvature,
54
48
  intrinsic_gradient_mean_curvature,
55
49
  intrinsic_gradient_principal_curvatures,
@@ -57,20 +51,21 @@ from .intrinsic_gradient_curvature import (
57
51
  )
58
52
 
59
53
  __all__ = [
54
+ # Constants
55
+ 'ZERO3','UNITX','UNITY','UNITZ','ONE3','ONE4','ONEC',
56
+
60
57
  # Core types
61
58
  'vec3', 'vec2', 'quat', 'coord3', 'lerp',
62
59
 
63
- # Differential geometry classes (v2.2.0+)
60
+ # Differential geometry classes (v3.0.0+)
64
61
  'Surface', 'Sphere', 'Torus',
65
- 'MetricTensor', 'ConnectionOperator',
66
-
67
- # Differential geometry functions (v2.2.0+)
68
- 'compute_metric', 'compute_connection',
69
- 'compute_curvature_tensor', 'compute_gaussian_curvature',
62
+ 'MetricTensor', 'IntrinsicGradientOperator', 'IntrinsicGradientCurvatureCalculator',
70
63
 
71
- # Aliases
72
- 'compute_frame_derivative', 'compute_intrinsic_gradient',
73
- 'compute_geometric_gradient', 'compute_metric_tensor',
64
+ # Differential geometry functions (v3.0.0+)
65
+ 'compute_intrinsic_gradient',
66
+ 'compute_gaussian_curvature',
67
+ 'compute_curvature_tensor',
68
+ 'compute_all_curvatures',
74
69
 
75
70
  # High-precision curvature module - Classical method (v2.3.0+)
76
71
  'CurvatureCalculator',
@@ -82,9 +77,7 @@ __all__ = [
82
77
  'gaussian_curvature_lie',
83
78
  'compare_methods',
84
79
 
85
- # Intrinsic Gradient Operator method (v2.4.0+)
86
- 'IntrinsicGradientOperator',
87
- 'IntrinsicGradientCurvatureCalculator',
80
+ # Intrinsic Gradient Operator method (v2.4.0+, merged into other modules)
88
81
  'intrinsic_gradient_gaussian_curvature',
89
82
  'intrinsic_gradient_mean_curvature',
90
83
  'intrinsic_gradient_principal_curvatures',
@@ -0,0 +1,300 @@
1
+ """
2
+ Coord3 Wrapper for Intrinsic Gradient Operator
3
+ ===============================================
4
+
5
+ This module provides a Python wrapper for coord3 that correctly implements
6
+ the mathematical operations needed for the intrinsic gradient operator.
7
+
8
+ Key insight: Use coord3's normalize() to separate rotation and scaling,
9
+ which is a core advantage of our coordinate system design over matrices.
10
+
11
+ Solution: Implement subtraction that properly handles the rotation-scale separation.
12
+ """
13
+
14
+ import numpy as np
15
+ from .coordinate_system import coord3 as _coord3, vec3
16
+ import math
17
+
18
+
19
+ class Coord3Wrapper:
20
+ """
21
+ Wrapper for coord3 that implements correct arithmetic for gradient operators
22
+
23
+ The intrinsic gradient operator requires:
24
+ G_μ = (c(u+h) - c(u)) / h
25
+
26
+ This implementation leverages coord3's ability to separate rotation and scaling.
27
+ """
28
+
29
+ def __init__(self, coord3_obj=None):
30
+ """
31
+ Initialize from a coord3 object or create new
32
+
33
+ Args:
34
+ coord3_obj: Original coord3 object from C++ binding
35
+ """
36
+ if coord3_obj is None:
37
+ self._c3 = _coord3()
38
+ else:
39
+ self._c3 = coord3_obj
40
+ # Ensure normalization to separate rotation and scale
41
+ self.normalize_axes()
42
+
43
+ def normalize_axes(self):
44
+ """
45
+ Normalize axes and extract scale factors
46
+
47
+ This is the key operation that separates rotation from scaling,
48
+ which is the core advantage of coord3 over matrix representations.
49
+ """
50
+ # Extract scale factors from current axes
51
+ sx = math.sqrt(self._c3.ux.dot(self._c3.ux))
52
+ sy = math.sqrt(self._c3.uy.dot(self._c3.uy))
53
+ sz = math.sqrt(self._c3.uz.dot(self._c3.uz))
54
+
55
+ # Normalize axes (pure rotation)
56
+ if sx > 1e-10:
57
+ self._c3.ux = self._c3.ux / sx
58
+ if sy > 1e-10:
59
+ self._c3.uy = self._c3.uy / sy
60
+ if sz > 1e-10:
61
+ self._c3.uz = self._c3.uz / sz
62
+
63
+ # Store scale factors separately
64
+ self._c3.s = vec3(sx, sy, sz)
65
+
66
+ @property
67
+ def o(self):
68
+ """Origin/position"""
69
+ return self._c3.o
70
+
71
+ @property
72
+ def ux(self):
73
+ """X axis direction (unit vector)"""
74
+ return self._c3.ux
75
+
76
+ @property
77
+ def uy(self):
78
+ """Y axis direction (unit vector)"""
79
+ return self._c3.uy
80
+
81
+ @property
82
+ def uz(self):
83
+ """Z axis direction (unit vector)"""
84
+ return self._c3.uz
85
+
86
+ @property
87
+ def s(self):
88
+ """Scale factors"""
89
+ return self._c3.s
90
+
91
+ def VX(self):
92
+ """Scaled X axis = ux * s.x"""
93
+ return vec3(
94
+ self.ux.x * self.s.x,
95
+ self.ux.y * self.s.x,
96
+ self.ux.z * self.s.x
97
+ )
98
+
99
+ def VY(self):
100
+ """Scaled Y axis = uy * s.y"""
101
+ return vec3(
102
+ self.uy.x * self.s.y,
103
+ self.uy.y * self.s.y,
104
+ self.uy.z * self.s.y
105
+ )
106
+
107
+ def VZ(self):
108
+ """Scaled Z axis = uz * s.z"""
109
+ return vec3(
110
+ self.uz.x * self.s.z,
111
+ self.uz.y * self.s.z,
112
+ self.uz.z * self.s.z
113
+ )
114
+
115
+ def __sub__(self, other):
116
+ """
117
+ Subtraction for gradient operator with proper rotation-scale separation
118
+
119
+ This leverages coord3's design advantage:
120
+ 1. Both frames are normalized (rotation and scale separated)
121
+ 2. Compute differences in rotation (unit vectors)
122
+ 3. Compute differences in scale (scale factors)
123
+ 4. Keep them separated for proper gradient computation
124
+ """
125
+ result = Coord3Wrapper()
126
+
127
+ # Ensure both frames are normalized
128
+ self.normalize_axes()
129
+ if isinstance(other, Coord3Wrapper):
130
+ other.normalize_axes()
131
+
132
+ # Origin difference
133
+ result._c3.o = self.o - other.o
134
+
135
+ # Rotation differences (unit vectors)
136
+ result._c3.ux = self.ux - other.ux
137
+ result._c3.uy = self.uy - other.uy
138
+ result._c3.uz = self.uz - other.uz
139
+
140
+ # Scale differences (kept separate)
141
+ result._c3.s = self.s - other.s
142
+
143
+ return result
144
+
145
+ def __truediv__(self, scalar):
146
+ """
147
+ Division by scalar for gradient operator
148
+
149
+ Used in G_μ = (c(u+h) - c(u)) / h
150
+ """
151
+ if isinstance(scalar, (int, float)):
152
+ result = Coord3Wrapper()
153
+
154
+ # Divide all components by scalar
155
+ result._c3.o = self.o / scalar
156
+ result._c3.ux = self.ux / scalar
157
+ result._c3.uy = self.uy / scalar
158
+ result._c3.uz = self.uz / scalar
159
+ result._c3.s = self.s / scalar
160
+
161
+ return result
162
+ else:
163
+ raise TypeError(f"Division only supported by scalar, got {type(scalar)}")
164
+
165
+ def compute_metric_det(self):
166
+ """
167
+ Compute determinant of metric tensor for 2D surface
168
+
169
+ For a surface parametrized by (u,v):
170
+ g = [[E, F], [F, G]]
171
+ where E = |∂r/∂u|², F = ∂r/∂u · ∂r/∂v, G = |∂r/∂v|²
172
+
173
+ Returns:
174
+ det(g) = E*G - F²
175
+ """
176
+ # Get scaled tangent vectors
177
+ vx = self.VX() # ∂r/∂u direction
178
+ vy = self.VY() # ∂r/∂v direction
179
+
180
+ # First fundamental form coefficients
181
+ E = vx.dot(vx) # g_uu
182
+ F = vx.dot(vy) # g_uv
183
+ G = vy.dot(vy) # g_vv
184
+
185
+ # Determinant
186
+ return E * G - F * F
187
+
188
+ def to_coord3(self):
189
+ """Convert back to original coord3"""
190
+ return self._c3
191
+
192
+ @classmethod
193
+ def from_surface_frame(cls, surface, u, v, compute_frame_func):
194
+ """
195
+ Create from surface using frame computation function
196
+
197
+ Args:
198
+ surface: Surface object
199
+ u, v: Parameters
200
+ compute_frame_func: Function to compute embedding frame
201
+
202
+ Returns:
203
+ Coord3Wrapper with proper metric information
204
+ """
205
+ frame = compute_frame_func(surface, u, v)
206
+ return cls(frame)
207
+
208
+
209
+ def create_embedding_frame_with_normalize(surface, u, v):
210
+ """
211
+ Create embedding frame for surface at point (u,v) using coord3's normalize
212
+
213
+ This implementation leverages coord3's design advantage:
214
+ 1. Compute tangent vectors r_u, r_v
215
+ 2. Build initial frame with scaled axes
216
+ 3. Use normalize() to separate rotation and scaling
217
+ 4. Apply Gram-Schmidt in the normalized space
218
+ 5. Preserve metric information in scale factors
219
+
220
+ Returns:
221
+ coord3 with proper embedding frame (rotation and scale separated)
222
+ """
223
+ # Get position
224
+ pos = surface.position(u, v)
225
+
226
+ # Compute tangent vectors using finite differences
227
+ h = 1e-6
228
+ pos_u_plus = surface.position(u + h, v)
229
+ pos_u_minus = surface.position(u - h, v)
230
+ r_u = (pos_u_plus - pos_u_minus) / (2 * h)
231
+
232
+ pos_v_plus = surface.position(u, v + h)
233
+ pos_v_minus = surface.position(u, v - h)
234
+ r_v = (pos_v_plus - pos_v_minus) / (2 * h)
235
+
236
+ # Create initial frame with tangent vectors (not normalized)
237
+ c = _coord3()
238
+ c.o = pos
239
+ c.ux = r_u # Will be normalized later
240
+ c.uy = r_v # Will be normalized later
241
+
242
+ # Compute initial normal (may not be unit)
243
+ n = r_u.cross(r_v)
244
+ c.uz = n
245
+
246
+ # Use coord3's normalize to separate rotation and scale
247
+ # This automatically extracts scale factors and normalizes axes
248
+ c.normalize() # This is the key operation!
249
+
250
+ # Now apply Gram-Schmidt to ensure orthogonality
251
+ # (while preserving the extracted scale factors)
252
+
253
+ # Get current scale factors (preserved from normalize)
254
+ s1 = c.s.x
255
+ s2 = c.s.y
256
+ s3 = c.s.z
257
+
258
+ # Gram-Schmidt on normalized axes
259
+ e1 = c.ux # Already normalized
260
+
261
+ # Orthogonalize e2 against e1
262
+ e2_temp = c.uy - e1 * c.uy.dot(e1)
263
+ e2_len = math.sqrt(e2_temp.dot(e2_temp))
264
+ if e2_len > 1e-10:
265
+ e2 = e2_temp / e2_len
266
+ else:
267
+ # Degenerate case: create orthogonal vector
268
+ if abs(e1.x) < 0.9:
269
+ e2 = vec3(1, 0, 0) - e1 * e1.x
270
+ else:
271
+ e2 = vec3(0, 1, 0) - e1 * e1.y
272
+ e2 = e2.normalized()
273
+
274
+ # Compute orthogonal normal
275
+ e3 = e1.cross(e2)
276
+ e3_len = math.sqrt(e3.dot(e3))
277
+ if e3_len > 1e-10:
278
+ e3 = e3 / e3_len
279
+ else:
280
+ e3 = vec3(0, 0, 1)
281
+
282
+ # Update frame with orthonormal axes
283
+ c.ux = e1
284
+ c.uy = e2
285
+ c.uz = e3
286
+
287
+ # Preserve the original scale factors (metric information)
288
+ # This is crucial for curvature computation
289
+ c.s = vec3(s1, s2, 1.0)
290
+
291
+ return c
292
+
293
+
294
+ def create_embedding_frame(surface, u, v):
295
+ """
296
+ Create embedding frame for surface - backward compatibility wrapper
297
+
298
+ Calls the new implementation that uses normalize().
299
+ """
300
+ return create_embedding_frame_with_normalize(surface, u, v)
@@ -33,9 +33,10 @@ from .differential_geometry import Surface
33
33
  from .coordinate_system import coord3, vec3
34
34
  from .differential_geometry import (
35
35
  MetricTensor,
36
- ConnectionOperator,
36
+ IntrinsicGradientOperator,
37
+ IntrinsicGradientCurvatureCalculator,
37
38
  compute_curvature_tensor as compute_curvature_tensor_lie,
38
- compute_metric
39
+ compute_all_curvatures as compute_all_curvatures_intrinsic
39
40
  )
40
41
 
41
42
 
@@ -594,7 +595,7 @@ class LieGroupCurvatureCalculator:
594
595
  )
595
596
 
596
597
  # Compute metric tensor
597
- g = compute_metric(self.surface, u, v)
598
+ g = MetricTensor.from_surface(self.surface, u, v)
598
599
 
599
600
  # Extract Gaussian curvature using antisymmetric part
600
601
  # K = R_{12}^{antisym} / det(g) = (R_01 - R_10)/2 / det(g)
@@ -650,14 +651,12 @@ class LieGroupCurvatureCalculator:
650
651
  self.surface.h = self.h
651
652
 
652
653
  try:
653
- # Compute connection operators
654
- conn = ConnectionOperator(
654
+ # Compute intrinsic gradient operators
655
+ intrinsic_op = IntrinsicGradientOperator(
655
656
  self.surface,
656
- self.scale_factor,
657
- self.use_metric_correction,
658
657
  self.h
659
658
  )
660
- G_u, G_v = conn.compute_both(u, v)
659
+ G_u, G_v = intrinsic_op.compute_both(u, v)
661
660
 
662
661
  # Compute curvature tensor
663
662
  R_uv = compute_curvature_tensor_lie(
@@ -668,7 +667,7 @@ class LieGroupCurvatureCalculator:
668
667
  )
669
668
 
670
669
  # Compute metric
671
- g = compute_metric(self.surface, u, v)
670
+ g = MetricTensor.from_surface(self.surface, u, v)
672
671
 
673
672
  # Extract Gaussian curvature using antisymmetric part
674
673
  # K = (R_01 - R_10)/2 / det(g)
@@ -785,16 +784,30 @@ def gaussian_curvature_lie(
785
784
 
786
785
 
787
786
  # ========== Intrinsic Gradient Operator Method ==========
788
- # Import from the new module
789
- from .intrinsic_gradient_curvature import (
787
+ # Now imported from differential_geometry module
788
+ from .differential_geometry import (
790
789
  IntrinsicGradientOperator,
791
790
  IntrinsicGradientCurvatureCalculator,
792
- intrinsic_gradient_gaussian_curvature,
793
- intrinsic_gradient_mean_curvature,
794
- intrinsic_gradient_principal_curvatures,
795
- intrinsic_gradient_all_curvatures,
796
791
  )
797
792
 
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)
797
+
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']
806
+
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
+
798
811
  # ========== Export ==========
799
812
 
800
813
  __all__ = [