UNPKG

@uor-foundation/geometry

Version:

Layer 5: Geometric manifolds - the shape of mathematical space

274 lines 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResonanceSurfaceAnalyzer = void 0; class ResonanceSurfaceAnalyzer { constructor(resonance, topology) { this.resonance = resonance; this.topology = topology; } computeResonanceSurface(center, radius) { const values = new Map(); for (let offset = -radius; offset <= radius; offset++) { const position = center + offset; if (position >= 0n) { const resonanceValue = this.resonance.calculateResonance(position); values.set(position, resonanceValue); } } const criticalPoints = this.findCriticalPoints(values); return { center, radius, values, criticalPoints, }; } findCriticalPoints(surface) { const points = []; const positions = Array.from(surface.keys()).sort((a, b) => Number(a - b)); for (let i = 1; i < positions.length - 1; i++) { const prev = positions[i - 1]; const curr = positions[i]; const next = positions[i + 1]; const valuePrev = surface.get(prev); const valueCurr = surface.get(curr); const valueNext = surface.get(next); if (valuePrev === undefined || valueCurr === undefined || valueNext === undefined) { continue; } const firstDerivative = (valueNext - valuePrev) / 2; const secondDerivative = valueNext - 2 * valueCurr + valuePrev; if (Math.abs(firstDerivative) < 1e-6) { let type; if (secondDerivative > 0) { type = 'minimum'; } else if (secondDerivative < 0) { type = 'maximum'; } else { type = 'saddle'; } points.push({ position: curr, value: valueCurr, type, hessian: secondDerivative, }); } } return points; } computeEnergyLandscape(min, max, resolution = 1n) { const potential = new Map(); const gradientField = new Map(); for (let n = min; n <= max; n += resolution) { const resonanceValue = this.resonance.calculateResonance(n); potential.set(n, resonanceValue); if (n > min && n < max) { const prev = this.resonance.calculateResonance(n - resolution); const next = this.resonance.calculateResonance(n + resolution); const gradient = (next - prev) / (2 * Number(resolution)); gradientField.set(n, gradient); } } const flowLines = this.computeFlowLines(potential, gradientField, min, max, resolution); return { bounds: { min, max }, resolution, potential, gradientField, flowLines, }; } computeFlowLines(potential, gradientField, min, max, resolution) { const flowLines = []; const visited = new Set(); for (let start = min; start <= max; start += resolution * 10n) { if (visited.has(start.toString())) continue; const flowLine = this.followGradientFlow(start, gradientField, min, max, resolution); flowLines.push(flowLine); for (const point of flowLine.path) { visited.add(point.toString()); } } return flowLines; } followGradientFlow(start, gradientField, min, max, resolution) { const path = [start]; let current = start; const maxSteps = 1000; let steps = 0; while (steps < maxSteps) { const gradient = gradientField.get(current) ?? 0; if (Math.abs(gradient) < 1e-6) { return { start, path, endpoint: current, endpointType: 'minimum', }; } const stepSize = BigInt(Math.sign(-gradient)) * resolution; const next = current + stepSize; if (next < min || next > max) { return { start, path, endpoint: current, endpointType: 'boundary', }; } if (path.includes(next)) { return { start, path, endpoint: current, endpointType: 'minimum', }; } current = next; path.push(current); steps++; } return { start, path, endpoint: current, endpointType: 'boundary', }; } findBasinsOfAttraction(landscape) { const basins = new Map(); const minima = landscape.flowLines .filter((line) => line.endpointType === 'minimum') .map((line) => line.endpoint); for (const minimum of minima) { if (!basins.has(minimum)) { basins.set(minimum, []); } } for (const flowLine of landscape.flowLines) { if (flowLine.endpointType === 'minimum') { const basin = basins.get(flowLine.endpoint); if (basin) { basin.push(...flowLine.path); } } } for (const [minimum, points] of basins) { basins.set(minimum, [...new Set(points)].sort((a, b) => Number(a - b))); } return basins; } computePotentialBarrier(from, to) { const path = this.findOptimalPath(from, to); let maxPotential = -Infinity; for (const point of path) { const potential = this.resonance.calculateResonance(point); maxPotential = Math.max(maxPotential, potential); } const fromPotential = this.resonance.calculateResonance(from); const toPotential = this.resonance.calculateResonance(to); return maxPotential - Math.max(fromPotential, toPotential); } findOptimalPath(from, to) { const path = []; const step = from < to ? 1n : -1n; let current = from; while (current !== to) { path.push(current); current += step; } path.push(to); return path; } visualizeSlice(surface) { const positions = Array.from(surface.values.keys()).sort((a, b) => Number(a - b)); if (positions.length === 0) return ''; const minValue = Math.min(...Array.from(surface.values.values())); const maxValue = Math.max(...Array.from(surface.values.values())); const range = maxValue - minValue; const height = 20; const lines = []; for (let h = height; h >= 0; h--) { let line = ''; const threshold = minValue + (h / height) * range; for (const pos of positions) { const value = surface.values.get(pos) ?? 0; if (value >= threshold) { line += '█'; } else { line += ' '; } } lines.push(line); } return lines.join('\n'); } computeMorseComplex(landscape) { const criticalPoints = []; for (const [position] of landscape.potential) { const gradient = landscape.gradientField.get(position) ?? 0; if (Math.abs(gradient) < 1e-6) { const prev = landscape.potential.get(position - landscape.resolution); const curr = landscape.potential.get(position); if (curr === undefined) continue; const next = landscape.potential.get(position + landscape.resolution); if (prev !== undefined && next !== undefined) { const secondDerivative = next - 2 * curr + prev; let type; if (secondDerivative > 0) { type = 'minimum'; } else if (secondDerivative < 0) { type = 'maximum'; } else { type = 'saddle'; } criticalPoints.push({ position, value: curr, type, hessian: secondDerivative, }); } } } const connections = this.findMorseConnections(criticalPoints, landscape); return { criticalPoints, connections, dimension: 1, }; } findMorseConnections(criticalPoints, _landscape) { const connections = []; const saddles = criticalPoints.filter((p) => p.type === 'saddle'); const minima = criticalPoints.filter((p) => p.type === 'minimum'); for (const saddle of saddles) { let closestMinimum = null; let minDistance = Infinity; for (const minimum of minima) { if (minimum.position < saddle.position) { const distance = Number(saddle.position - minimum.position); if (distance < minDistance) { minDistance = distance; closestMinimum = minimum.position; } } } if (closestMinimum !== null) { connections.push([saddle.position, closestMinimum]); } } return connections; } } exports.ResonanceSurfaceAnalyzer = ResonanceSurfaceAnalyzer; //# sourceMappingURL=resonance-surface.js.map