scalar-autograd 0.1.7 → 0.1.9

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.
Files changed (86) hide show
  1. package/README.md +127 -2
  2. package/dist/CompiledFunctions.d.ts +111 -0
  3. package/dist/CompiledFunctions.js +268 -0
  4. package/dist/CompiledResiduals.d.ts +74 -0
  5. package/dist/CompiledResiduals.js +94 -0
  6. package/dist/EigenvalueHelpers.d.ts +14 -0
  7. package/dist/EigenvalueHelpers.js +93 -0
  8. package/dist/Geometry.d.ts +131 -0
  9. package/dist/Geometry.js +213 -0
  10. package/dist/GraphBuilder.d.ts +64 -0
  11. package/dist/GraphBuilder.js +237 -0
  12. package/dist/GraphCanonicalizerNoSort.d.ts +20 -0
  13. package/dist/GraphCanonicalizerNoSort.js +190 -0
  14. package/dist/GraphHashCanonicalizer.d.ts +46 -0
  15. package/dist/GraphHashCanonicalizer.js +220 -0
  16. package/dist/GraphSignature.d.ts +7 -0
  17. package/dist/GraphSignature.js +7 -0
  18. package/dist/KernelPool.d.ts +55 -0
  19. package/dist/KernelPool.js +124 -0
  20. package/dist/LBFGS.d.ts +84 -0
  21. package/dist/LBFGS.js +313 -0
  22. package/dist/LinearSolver.d.ts +69 -0
  23. package/dist/LinearSolver.js +213 -0
  24. package/dist/Losses.d.ts +9 -0
  25. package/dist/Losses.js +42 -37
  26. package/dist/Matrix3x3.d.ts +50 -0
  27. package/dist/Matrix3x3.js +146 -0
  28. package/dist/NonlinearLeastSquares.d.ts +33 -0
  29. package/dist/NonlinearLeastSquares.js +252 -0
  30. package/dist/Optimizers.d.ts +70 -14
  31. package/dist/Optimizers.js +42 -19
  32. package/dist/V.d.ts +0 -0
  33. package/dist/V.js +0 -0
  34. package/dist/Value.d.ts +84 -2
  35. package/dist/Value.js +296 -58
  36. package/dist/ValueActivation.js +10 -14
  37. package/dist/ValueArithmetic.d.ts +1 -0
  38. package/dist/ValueArithmetic.js +58 -50
  39. package/dist/ValueComparison.js +9 -13
  40. package/dist/ValueRegistry.d.ts +38 -0
  41. package/dist/ValueRegistry.js +88 -0
  42. package/dist/ValueTrig.js +14 -18
  43. package/dist/Vec2.d.ts +45 -0
  44. package/dist/Vec2.js +93 -0
  45. package/dist/Vec3.d.ts +78 -0
  46. package/dist/Vec3.js +169 -0
  47. package/dist/Vec4.d.ts +45 -0
  48. package/dist/Vec4.js +126 -0
  49. package/dist/__tests__/duplicate-inputs.test.js +33 -0
  50. package/dist/cli/gradient-gen.d.ts +19 -0
  51. package/dist/cli/gradient-gen.js +264 -0
  52. package/dist/compileIndirectKernel.d.ts +24 -0
  53. package/dist/compileIndirectKernel.js +148 -0
  54. package/dist/index.d.ts +20 -0
  55. package/dist/index.js +20 -0
  56. package/dist/scalar-autograd.d.ts +1157 -0
  57. package/dist/symbolic/AST.d.ts +113 -0
  58. package/dist/symbolic/AST.js +128 -0
  59. package/dist/symbolic/CodeGen.d.ts +35 -0
  60. package/dist/symbolic/CodeGen.js +280 -0
  61. package/dist/symbolic/Parser.d.ts +64 -0
  62. package/dist/symbolic/Parser.js +329 -0
  63. package/dist/symbolic/Simplify.d.ts +10 -0
  64. package/dist/symbolic/Simplify.js +244 -0
  65. package/dist/symbolic/SymbolicDiff.d.ts +35 -0
  66. package/dist/symbolic/SymbolicDiff.js +339 -0
  67. package/dist/tsdoc-metadata.json +11 -0
  68. package/package.json +29 -5
  69. package/dist/Losses.spec.js +0 -54
  70. package/dist/Optimizers.edge-cases.spec.d.ts +0 -1
  71. package/dist/Optimizers.edge-cases.spec.js +0 -29
  72. package/dist/Optimizers.spec.d.ts +0 -1
  73. package/dist/Optimizers.spec.js +0 -56
  74. package/dist/Value.edge-cases.spec.d.ts +0 -1
  75. package/dist/Value.edge-cases.spec.js +0 -54
  76. package/dist/Value.grad-flow.spec.d.ts +0 -1
  77. package/dist/Value.grad-flow.spec.js +0 -24
  78. package/dist/Value.losses-edge-cases.spec.d.ts +0 -1
  79. package/dist/Value.losses-edge-cases.spec.js +0 -30
  80. package/dist/Value.memory.spec.d.ts +0 -1
  81. package/dist/Value.memory.spec.js +0 -23
  82. package/dist/Value.nn.spec.d.ts +0 -1
  83. package/dist/Value.nn.spec.js +0 -111
  84. package/dist/Value.spec.d.ts +0 -1
  85. package/dist/Value.spec.js +0 -245
  86. /package/dist/{Losses.spec.d.ts → __tests__/duplicate-inputs.test.d.ts} +0 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * External helper functions for eigenvalue computation in compiled code.
3
+ * These are called from generated JavaScript to avoid inlining huge formulas.
4
+ */
5
+ /**
6
+ * Compute smallest eigenvalue of 3x3 symmetric matrix.
7
+ * Uses Cardano's formula for cubic equation.
8
+ */
9
+ export declare function computeSmallestEigenvalue(c00: number, c01: number, c02: number, c11: number, c12: number, c22: number): number;
10
+ /**
11
+ * Apply eigenvalue gradients using analytical formula.
12
+ * Computes eigenvector and updates input gradients with ∂λ/∂C_ij = v_i * v_j
13
+ */
14
+ export declare function applyEigenvalueGradients(outGrad: number, c00: number, c01: number, c02: number, c11: number, c12: number, c22: number, g00: number, g01: number, g02: number, g11: number, g12: number, g22: number): [number, number, number, number, number, number];
@@ -0,0 +1,93 @@
1
+ /**
2
+ * External helper functions for eigenvalue computation in compiled code.
3
+ * These are called from generated JavaScript to avoid inlining huge formulas.
4
+ */
5
+ /**
6
+ * Compute smallest eigenvalue of 3x3 symmetric matrix.
7
+ * Uses Cardano's formula for cubic equation.
8
+ */
9
+ export function computeSmallestEigenvalue(c00, c01, c02, c11, c12, c22) {
10
+ const tr = c00 + c11 + c22;
11
+ const shift = tr / 3;
12
+ const b00 = c00 - shift;
13
+ const b11 = c11 - shift;
14
+ const b22 = c22 - shift;
15
+ const q = 0.5 * (b00 * b00 + b11 * b11 + b22 * b22 + 2 * c01 * c01 + 2 * c02 * c02 + 2 * c12 * c12);
16
+ const p = Math.sqrt((q + 1e-20) / 3);
17
+ const invP = 1 / (p + 1e-12);
18
+ const d00 = b00 * invP;
19
+ const d01 = c01 * invP;
20
+ const d02 = c02 * invP;
21
+ const d11 = b11 * invP;
22
+ const d12 = c12 * invP;
23
+ const d22 = b22 * invP;
24
+ const det = d00 * (d11 * d22 - d12 * d12) + d01 * (d12 * d02 - d01 * d22) + d02 * (d01 * d12 - d11 * d02);
25
+ const r = Math.max(-0.99999, Math.min(det / 2, 0.99999));
26
+ const theta = Math.acos(r);
27
+ const angle2 = theta / 3 + 2 * 2.0943951023931953;
28
+ return shift + 2 * p * Math.cos(angle2);
29
+ }
30
+ /**
31
+ * Apply eigenvalue gradients using analytical formula.
32
+ * Computes eigenvector and updates input gradients with ∂λ/∂C_ij = v_i * v_j
33
+ */
34
+ export function applyEigenvalueGradients(outGrad, c00, c01, c02, c11, c12, c22, g00, g01, g02, g11, g12, g22) {
35
+ const lambda = computeSmallestEigenvalue(c00, c01, c02, c11, c12, c22);
36
+ const a00 = c00 - lambda;
37
+ const a11 = c11 - lambda;
38
+ const a22 = c22 - lambda;
39
+ const row0_x = a00, row0_y = c01, row0_z = c02;
40
+ const row1_x = c01, row1_y = a11, row1_z = c12;
41
+ const row2_x = c02, row2_y = c12, row2_z = a22;
42
+ const cross0_x = row0_y * row1_z - row0_z * row1_y;
43
+ const cross0_y = row0_z * row1_x - row0_x * row1_z;
44
+ const cross0_z = row0_x * row1_y - row0_y * row1_x;
45
+ const cross1_x = row0_y * row2_z - row0_z * row2_y;
46
+ const cross1_y = row0_z * row2_x - row0_x * row2_z;
47
+ const cross1_z = row0_x * row2_y - row0_y * row2_x;
48
+ const cross2_x = row1_y * row2_z - row1_z * row2_y;
49
+ const cross2_y = row1_z * row2_x - row1_x * row2_z;
50
+ const cross2_z = row1_x * row2_y - row1_y * row2_x;
51
+ const mag0 = Math.sqrt(cross0_x * cross0_x + cross0_y * cross0_y + cross0_z * cross0_z);
52
+ const mag1 = Math.sqrt(cross1_x * cross1_x + cross1_y * cross1_y + cross1_z * cross1_z);
53
+ const mag2 = Math.sqrt(cross2_x * cross2_x + cross2_y * cross2_y + cross2_z * cross2_z);
54
+ let bestMag = mag0;
55
+ let vx = cross0_x, vy = cross0_y, vz = cross0_z;
56
+ if (mag1 > bestMag) {
57
+ bestMag = mag1;
58
+ vx = cross1_x;
59
+ vy = cross1_y;
60
+ vz = cross1_z;
61
+ }
62
+ if (mag2 > bestMag) {
63
+ bestMag = mag2;
64
+ vx = cross2_x;
65
+ vy = cross2_y;
66
+ vz = cross2_z;
67
+ }
68
+ if (bestMag < 1e-12) {
69
+ vx = 1;
70
+ vy = 0;
71
+ vz = 0;
72
+ }
73
+ else {
74
+ vx /= bestMag;
75
+ vy /= bestMag;
76
+ vz /= bestMag;
77
+ }
78
+ return [
79
+ g00 + outGrad * vx * vx,
80
+ g01 + outGrad * 2 * vx * vy,
81
+ g02 + outGrad * 2 * vx * vz,
82
+ g11 + outGrad * vy * vy,
83
+ g12 + outGrad * 2 * vy * vz,
84
+ g22 + outGrad * vz * vz
85
+ ];
86
+ }
87
+ // Make available globally for compiled code
88
+ if (typeof window !== 'undefined') {
89
+ window.__eigenHelpers = {
90
+ computeSmallestEigenvalue,
91
+ applyEigenvalueGradients
92
+ };
93
+ }
@@ -0,0 +1,131 @@
1
+ import { Vec3 } from './Vec3';
2
+ import { Value } from './Value';
3
+ /**
4
+ * Geometric utility functions for triangle mesh operations.
5
+ * All methods are differentiable and support automatic gradient computation.
6
+ * @public
7
+ */
8
+ export declare class Geometry {
9
+ /**
10
+ * Compute the normal of a triangle defined by three vertices.
11
+ * Uses right-hand rule: normal points in direction of (b-a) × (c-a).
12
+ * Returns a UNIT normal vector.
13
+ *
14
+ * @param a - First vertex
15
+ * @param b - Second vertex
16
+ * @param c - Third vertex
17
+ * @returns Unit normal vector
18
+ */
19
+ static triangleNormal(a: Vec3, b: Vec3, c: Vec3): Vec3;
20
+ /**
21
+ * Compute the area of a triangle defined by three vertices.
22
+ * Uses the cross product formula: Area = 0.5 * ||(b-a) × (c-a)||
23
+ *
24
+ * @param a - First vertex
25
+ * @param b - Second vertex
26
+ * @param c - Third vertex
27
+ * @returns Triangle area
28
+ */
29
+ static triangleArea(a: Vec3, b: Vec3, c: Vec3): Value;
30
+ /**
31
+ * Compute the interior angle at vertex b in triangle abc.
32
+ * Returns angle in radians, range [0, π].
33
+ *
34
+ * Formula: angle = acos(dot(normalize(a-b), normalize(c-b)))
35
+ *
36
+ * @param a - First neighboring vertex
37
+ * @param b - Vertex where angle is measured
38
+ * @param c - Second neighboring vertex
39
+ * @returns Interior angle in radians
40
+ */
41
+ static interiorAngle(a: Vec3, b: Vec3, c: Vec3): Value;
42
+ /**
43
+ * Compute the angle defect at a vertex.
44
+ * Angle defect = 2π - sum of interior angles around the vertex.
45
+ * For flat regions, angle defect = 0.
46
+ * For positive Gaussian curvature (sphere-like), angle defect > 0.
47
+ * For negative Gaussian curvature (saddle-like), angle defect < 0.
48
+ *
49
+ * @param center - The vertex at which to compute angle defect
50
+ * @param neighbors - Ordered list of neighboring vertices (CCW or CW)
51
+ * @returns Angle defect in radians
52
+ */
53
+ static angleDefect(center: Vec3, neighbors: Vec3[]): Value;
54
+ /**
55
+ * Compute the centroid (center of mass) of a set of points.
56
+ *
57
+ * @param points - Array of points
58
+ * @returns Centroid
59
+ */
60
+ static centroid(points: Vec3[]): Vec3;
61
+ /**
62
+ * Compute area-weighted normal at a vertex.
63
+ * This is the sum of face normals weighted by face areas,
64
+ * then normalized. Provides a smooth approximation of the
65
+ * surface normal at a vertex.
66
+ *
67
+ * @param center - The vertex
68
+ * @param triangles - Array of triangles as [Vec3, Vec3, Vec3] where center is one of the vertices
69
+ * @returns Area-weighted unit normal
70
+ */
71
+ static vertexNormal(center: Vec3, triangles: [Vec3, Vec3, Vec3][]): Vec3;
72
+ /**
73
+ * Project point onto a plane defined by a point and normal.
74
+ *
75
+ * @param point - Point to project
76
+ * @param planePoint - A point on the plane
77
+ * @param planeNormal - Unit normal of the plane
78
+ * @returns Projected point
79
+ */
80
+ static projectToPlane(point: Vec3, planePoint: Vec3, planeNormal: Vec3): Vec3;
81
+ /**
82
+ * Compute signed distance from point to plane.
83
+ * Positive if point is on the side the normal points to.
84
+ *
85
+ * @param point - Point to measure
86
+ * @param planePoint - A point on the plane
87
+ * @param planeNormal - Unit normal of the plane
88
+ * @returns Signed distance
89
+ */
90
+ static distanceToPlane(point: Vec3, planePoint: Vec3, planeNormal: Vec3): Value;
91
+ /**
92
+ * Check if a set of normals are coplanar (lie in a common plane).
93
+ * Returns a measure of non-coplanarity (0 = perfectly coplanar).
94
+ * Uses the smallest eigenvalue of the normal covariance matrix.
95
+ *
96
+ * This is a simplified version - the full implementation would
97
+ * compute eigenvalues. For now, returns sum of cross products.
98
+ *
99
+ * @param normals - Array of unit normal vectors
100
+ * @returns Measure of non-coplanarity (0 = coplanar)
101
+ */
102
+ static normalCoplanarity(normals: Vec3[]): Value;
103
+ /**
104
+ * Compute the dihedral angle between two triangles sharing an edge.
105
+ * Returns angle in radians, range [0, π].
106
+ * Angle = 0 means triangles are coplanar.
107
+ * Angle = π means triangles fold completely back on themselves.
108
+ *
109
+ * @param n1 - Normal of first triangle
110
+ * @param n2 - Normal of second triangle
111
+ * @returns Dihedral angle in radians
112
+ */
113
+ static dihedralAngle(n1: Vec3, n2: Vec3): Value;
114
+ /**
115
+ * Compute the average of multiple vectors.
116
+ *
117
+ * @param vectors - Array of vectors
118
+ * @returns Average vector (not normalized)
119
+ */
120
+ static average(vectors: Vec3[]): Vec3;
121
+ /**
122
+ * Compute bounding box of a set of points.
123
+ *
124
+ * @param points - Array of points
125
+ * @returns Object with min and max corners
126
+ */
127
+ static boundingBox(points: Vec3[]): {
128
+ min: Vec3;
129
+ max: Vec3;
130
+ };
131
+ }
@@ -0,0 +1,213 @@
1
+ import { Vec3 } from './Vec3';
2
+ import { V } from './V';
3
+ /**
4
+ * Geometric utility functions for triangle mesh operations.
5
+ * All methods are differentiable and support automatic gradient computation.
6
+ * @public
7
+ */
8
+ export class Geometry {
9
+ /**
10
+ * Compute the normal of a triangle defined by three vertices.
11
+ * Uses right-hand rule: normal points in direction of (b-a) × (c-a).
12
+ * Returns a UNIT normal vector.
13
+ *
14
+ * @param a - First vertex
15
+ * @param b - Second vertex
16
+ * @param c - Third vertex
17
+ * @returns Unit normal vector
18
+ */
19
+ static triangleNormal(a, b, c) {
20
+ const edge1 = b.sub(a);
21
+ const edge2 = c.sub(a);
22
+ const cross = Vec3.cross(edge1, edge2);
23
+ return cross.normalized;
24
+ }
25
+ /**
26
+ * Compute the area of a triangle defined by three vertices.
27
+ * Uses the cross product formula: Area = 0.5 * ||(b-a) × (c-a)||
28
+ *
29
+ * @param a - First vertex
30
+ * @param b - Second vertex
31
+ * @param c - Third vertex
32
+ * @returns Triangle area
33
+ */
34
+ static triangleArea(a, b, c) {
35
+ const edge1 = b.sub(a);
36
+ const edge2 = c.sub(a);
37
+ const cross = Vec3.cross(edge1, edge2);
38
+ return V.mul(0.5, cross.magnitude);
39
+ }
40
+ /**
41
+ * Compute the interior angle at vertex b in triangle abc.
42
+ * Returns angle in radians, range [0, π].
43
+ *
44
+ * Formula: angle = acos(dot(normalize(a-b), normalize(c-b)))
45
+ *
46
+ * @param a - First neighboring vertex
47
+ * @param b - Vertex where angle is measured
48
+ * @param c - Second neighboring vertex
49
+ * @returns Interior angle in radians
50
+ */
51
+ static interiorAngle(a, b, c) {
52
+ const ba = a.sub(b).normalized;
53
+ const bc = c.sub(b).normalized;
54
+ return Vec3.angleBetween(ba, bc);
55
+ }
56
+ /**
57
+ * Compute the angle defect at a vertex.
58
+ * Angle defect = 2π - sum of interior angles around the vertex.
59
+ * For flat regions, angle defect = 0.
60
+ * For positive Gaussian curvature (sphere-like), angle defect > 0.
61
+ * For negative Gaussian curvature (saddle-like), angle defect < 0.
62
+ *
63
+ * @param center - The vertex at which to compute angle defect
64
+ * @param neighbors - Ordered list of neighboring vertices (CCW or CW)
65
+ * @returns Angle defect in radians
66
+ */
67
+ static angleDefect(center, neighbors) {
68
+ let angleSum = V.C(0);
69
+ const n = neighbors.length;
70
+ for (let i = 0; i < n; i++) {
71
+ const prev = neighbors[i];
72
+ const next = neighbors[(i + 1) % n];
73
+ const angle = Geometry.interiorAngle(prev, center, next);
74
+ angleSum = V.add(angleSum, angle);
75
+ }
76
+ return V.sub(2 * Math.PI, angleSum);
77
+ }
78
+ /**
79
+ * Compute the centroid (center of mass) of a set of points.
80
+ *
81
+ * @param points - Array of points
82
+ * @returns Centroid
83
+ */
84
+ static centroid(points) {
85
+ if (points.length === 0) {
86
+ return Vec3.zero();
87
+ }
88
+ let sum = Vec3.zero();
89
+ for (const p of points) {
90
+ sum = sum.add(p);
91
+ }
92
+ return sum.div(points.length);
93
+ }
94
+ /**
95
+ * Compute area-weighted normal at a vertex.
96
+ * This is the sum of face normals weighted by face areas,
97
+ * then normalized. Provides a smooth approximation of the
98
+ * surface normal at a vertex.
99
+ *
100
+ * @param center - The vertex
101
+ * @param triangles - Array of triangles as [Vec3, Vec3, Vec3] where center is one of the vertices
102
+ * @returns Area-weighted unit normal
103
+ */
104
+ static vertexNormal(center, triangles) {
105
+ let weightedSum = Vec3.zero();
106
+ for (const [a, b, c] of triangles) {
107
+ const normal = Geometry.triangleNormal(a, b, c);
108
+ const area = Geometry.triangleArea(a, b, c);
109
+ weightedSum = weightedSum.add(normal.mul(area));
110
+ }
111
+ return weightedSum.normalized;
112
+ }
113
+ /**
114
+ * Project point onto a plane defined by a point and normal.
115
+ *
116
+ * @param point - Point to project
117
+ * @param planePoint - A point on the plane
118
+ * @param planeNormal - Unit normal of the plane
119
+ * @returns Projected point
120
+ */
121
+ static projectToPlane(point, planePoint, planeNormal) {
122
+ const toPoint = point.sub(planePoint);
123
+ const distance = Vec3.dot(toPoint, planeNormal);
124
+ const offset = planeNormal.mul(distance);
125
+ return point.sub(offset);
126
+ }
127
+ /**
128
+ * Compute signed distance from point to plane.
129
+ * Positive if point is on the side the normal points to.
130
+ *
131
+ * @param point - Point to measure
132
+ * @param planePoint - A point on the plane
133
+ * @param planeNormal - Unit normal of the plane
134
+ * @returns Signed distance
135
+ */
136
+ static distanceToPlane(point, planePoint, planeNormal) {
137
+ const toPoint = point.sub(planePoint);
138
+ return Vec3.dot(toPoint, planeNormal);
139
+ }
140
+ /**
141
+ * Check if a set of normals are coplanar (lie in a common plane).
142
+ * Returns a measure of non-coplanarity (0 = perfectly coplanar).
143
+ * Uses the smallest eigenvalue of the normal covariance matrix.
144
+ *
145
+ * This is a simplified version - the full implementation would
146
+ * compute eigenvalues. For now, returns sum of cross products.
147
+ *
148
+ * @param normals - Array of unit normal vectors
149
+ * @returns Measure of non-coplanarity (0 = coplanar)
150
+ */
151
+ static normalCoplanarity(normals) {
152
+ if (normals.length < 2)
153
+ return V.C(0);
154
+ // Simple measure: sum of squared cross products between all pairs
155
+ // If all normals are coplanar, all cross products lie along the same axis
156
+ let deviation = V.C(0);
157
+ for (let i = 0; i < normals.length; i++) {
158
+ for (let j = i + 1; j < normals.length; j++) {
159
+ const cross = Vec3.cross(normals[i], normals[j]);
160
+ deviation = V.add(deviation, cross.sqrMagnitude);
161
+ }
162
+ }
163
+ return deviation;
164
+ }
165
+ /**
166
+ * Compute the dihedral angle between two triangles sharing an edge.
167
+ * Returns angle in radians, range [0, π].
168
+ * Angle = 0 means triangles are coplanar.
169
+ * Angle = π means triangles fold completely back on themselves.
170
+ *
171
+ * @param n1 - Normal of first triangle
172
+ * @param n2 - Normal of second triangle
173
+ * @returns Dihedral angle in radians
174
+ */
175
+ static dihedralAngle(n1, n2) {
176
+ const dotProd = Vec3.dot(n1, n2);
177
+ const clampedDot = V.clamp(dotProd, -1, 1);
178
+ return V.acos(clampedDot);
179
+ }
180
+ /**
181
+ * Compute the average of multiple vectors.
182
+ *
183
+ * @param vectors - Array of vectors
184
+ * @returns Average vector (not normalized)
185
+ */
186
+ static average(vectors) {
187
+ if (vectors.length === 0)
188
+ return Vec3.zero();
189
+ let sum = Vec3.zero();
190
+ for (const v of vectors) {
191
+ sum = sum.add(v);
192
+ }
193
+ return sum.div(vectors.length);
194
+ }
195
+ /**
196
+ * Compute bounding box of a set of points.
197
+ *
198
+ * @param points - Array of points
199
+ * @returns Object with min and max corners
200
+ */
201
+ static boundingBox(points) {
202
+ if (points.length === 0) {
203
+ return { min: Vec3.zero(), max: Vec3.zero() };
204
+ }
205
+ let min = points[0].clone();
206
+ let max = points[0].clone();
207
+ for (let i = 1; i < points.length; i++) {
208
+ min = Vec3.min(min, points[i]);
209
+ max = Vec3.max(max, points[i]);
210
+ }
211
+ return { min, max };
212
+ }
213
+ }
@@ -0,0 +1,64 @@
1
+ import { Value } from './Value';
2
+ /**
3
+ * Graph signature with hash and input mapping
4
+ */
5
+ export interface GraphSignature {
6
+ /** Hash string for kernel matching */
7
+ hash: string;
8
+ /** Ordered list of leaf Value objects (params first, then constants) */
9
+ leaves: Value[];
10
+ /** Map from Value to index in leaves array */
11
+ leafIndexMap: Map<Value, number>;
12
+ }
13
+ /**
14
+ * Incremental graph builder that tracks structure during construction.
15
+ *
16
+ * Usage:
17
+ * ```typescript
18
+ * const builder = new GraphBuilder(knownParams);
19
+ * const result = builder.build(() => {
20
+ * const a = V.add(params[0], params[1]);
21
+ * const b = V.mul(a, V.C(2));
22
+ * return b;
23
+ * });
24
+ * // result.signature.hash - for kernel lookup
25
+ * // result.signature.leaves - for index mapping at execution time
26
+ * ```
27
+ */
28
+ export declare class GraphBuilder {
29
+ private leaves;
30
+ private leafIndexMap;
31
+ private knownParams;
32
+ private operations;
33
+ /**
34
+ * Create a new graph builder.
35
+ * @param knownParams - Parameters that are known upfront (will be indexed first)
36
+ */
37
+ constructor(knownParams?: Value[]);
38
+ /**
39
+ * Register a leaf Value and return its index.
40
+ * If already registered, returns existing index.
41
+ * New parameters are added dynamically.
42
+ */
43
+ private registerLeaf;
44
+ /**
45
+ * Record an operation during graph building.
46
+ * Called automatically by Value.make() when in tracked context.
47
+ * @internal
48
+ */
49
+ recordOp(value: Value): void;
50
+ /**
51
+ * Build a graph in tracked context and return output + signature.
52
+ *
53
+ * @param fn - Function that builds and returns the output Value
54
+ * @returns Output value and graph signature
55
+ */
56
+ build(fn: () => Value): {
57
+ output: Value;
58
+ signature: GraphSignature;
59
+ };
60
+ /**
61
+ * Get current signature without finalizing (for debugging)
62
+ */
63
+ getCurrentSignature(): Partial<GraphSignature>;
64
+ }