@uor-foundation/geometry
Version:
Layer 5: Geometric manifolds - the shape of mathematical space
214 lines • 7.39 kB
JavaScript
;
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