UNPKG

@uor-foundation/geometry

Version:

Layer 5: Geometric manifolds - the shape of mathematical space

214 lines 7.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ContinuousEmbedding = void 0; class ContinuousEmbedding { constructor(topology) { this.topology = topology; this.LAMBDA = 256; this.FOLIO_SIZE = 65536; this.rotationCache = new Map(); this.precomputeRotations(); } embedFolio(startIndex = 0n) { const curve = []; const segments = []; let currentPos = { x: 0, y: 0 }; let currentAngle = 0; curve.push({ ...currentPos }); for (let i = 0n; i < BigInt(this.FOLIO_SIZE); i++) { const n = startIndex + i; const curvature = this.computeCurvature(n); const segmentStart = { ...currentPos }; const segmentPoints = [segmentStart]; currentAngle += curvature; const rotation = this.getRotation(currentAngle); const dx = rotation.cos; const dy = rotation.sin; currentPos = { x: currentPos.x + dx, y: currentPos.y + dy, }; segmentPoints.push({ ...currentPos }); curve.push({ ...currentPos }); if (i % 48n === 0n) { segments.push({ start: n, end: n + 47n, curvature: curvature, points: segmentPoints, }); } } return { folio: startIndex / BigInt(this.FOLIO_SIZE), curve, segments, totalRotation: currentAngle, }; } computeCurvature(n) { const offset = Number(n % BigInt(this.LAMBDA)); const pagePosition = Number(n % 48n); if (pagePosition === 0 || pagePosition === 1) { return 1.31; } if (pagePosition === 47) { return 1.92; } if (offset === 23) { return -0.42; } if (offset === 107) { return -0.57; } return 0; } getEmbedding(n) { const folioStart = (n / BigInt(this.FOLIO_SIZE)) * BigInt(this.FOLIO_SIZE); const relativeIndex = n - folioStart; const pos = { x: 0, y: 0 }; let angle = 0; for (let i = 0n; i < relativeIndex; i++) { const curvature = this.computeCurvature(folioStart + i); angle += curvature; const rotation = this.getRotation(angle); pos.x += rotation.cos; pos.y += rotation.sin; } return pos; } computeGeodesic(a, b) { if (a === b) return [this.getEmbedding(a)]; const path = []; const step = a < b ? 1n : -1n; for (let n = a; n !== b + step; n += step) { path.push(this.getEmbedding(n)); } return path; } embeddingDistance(a, b) { const pointA = this.getEmbedding(a); const pointB = this.getEmbedding(b); const dx = pointB.x - pointA.x; const dy = pointB.y - pointA.y; return Math.sqrt(dx * dx + dy * dy); } intrinsicDistance(a, b) { return a > b ? a - b : b - a; } biLipschitzBounds(a, b) { const intrinsic = Number(this.intrinsicDistance(a, b)); const kMax = 1.92; return { lower: intrinsic / (1 + kMax), upper: intrinsic, }; } computeArcLength(path) { if (path.length < 2) return 0; let length = 0; for (let i = 0; i < path.length - 1; i++) { const dx = path[i + 1].x - path[i].x; const dy = path[i + 1].y - path[i].y; length += Math.sqrt(dx * dx + dy * dy); } return length; } findCriticalCurvaturePoints(start, end) { const criticalPoints = []; for (let n = start; n <= end; n++) { const curvature = this.computeCurvature(n); const nextCurvature = this.computeCurvature(n + 1n); const prevCurvature = n > 0n ? this.computeCurvature(n - 1n) : curvature; if ((curvature > prevCurvature && curvature > nextCurvature) || (curvature < prevCurvature && curvature < nextCurvature)) { criticalPoints.push(n); } if (prevCurvature * curvature < 0 || curvature * nextCurvature < 0) { criticalPoints.push(n); } } return criticalPoints; } visualizeEmbedding(embedding, width = 80, height = 40) { const grid = Array(height) .fill(null) .map(() => Array(width).fill(' ')); const minX = Math.min(...embedding.curve.map((p) => p.x)); const maxX = Math.max(...embedding.curve.map((p) => p.x)); const minY = Math.min(...embedding.curve.map((p) => p.y)); const maxY = Math.max(...embedding.curve.map((p) => p.y)); const scaleX = (width - 2) / (maxX - minX); const scaleY = (height - 2) / (maxY - minY); const scale = Math.min(scaleX, scaleY); for (const point of embedding.curve) { const x = Math.floor((point.x - minX) * scale + 1); const y = Math.floor((point.y - minY) * scale + 1); if (x >= 0 && x < width && y >= 0 && y < height) { grid[height - 1 - y][x] = '█'; } } return grid.map((row) => row.join('')); } getWindingNumber(embedding) { return Math.round(embedding.totalRotation / (2 * Math.PI)); } interpolateOnCurve(n, t) { const basePoint = this.getEmbedding(n); const nextPoint = this.getEmbedding(n + 1n); return { x: basePoint.x + t * (nextPoint.x - basePoint.x), y: basePoint.y + t * (nextPoint.y - basePoint.y), }; } precomputeRotations() { for (let i = 0; i < this.LAMBDA; i++) { const curvatures = []; for (let j = 0; j <= i; j++) { curvatures.push(this.computeCurvature(BigInt(j))); } const totalAngle = curvatures.reduce((sum, k) => sum + k, 0); this.rotationCache.set(i, { cos: Math.cos(totalAngle), sin: Math.sin(totalAngle), }); } } getRotation(angle) { return { cos: Math.cos(angle), sin: Math.sin(angle), }; } extendToComplexPlane(n) { const point = this.getEmbedding(n); const resonance = Math.sin((Number(n) * Math.PI) / 128); return { real: point.x, imag: point.y * resonance, }; } computeSpectralGap(start, end) { const curvatures = []; for (let n = start; n <= end; n++) { curvatures.push(Math.abs(this.computeCurvature(n))); } curvatures.sort((a, b) => a - b); if (curvatures.length < 2) return 0; return curvatures[1] - curvatures[0]; } detectBottlenecks(embedding) { const bottlenecks = []; for (const segment of embedding.segments) { if (Math.abs(segment.curvature) > 1.5) { bottlenecks.push(segment.start); } } return bottlenecks; } } exports.ContinuousEmbedding = ContinuousEmbedding; //# sourceMappingURL=embedding.js.map