@sschepis/resolang
Version:
ResoLang - Core quantum resonance computation library for browser and Node.js
329 lines (273 loc) • 8.87 kB
text/typescript
/**
* Embedding Pipeline
*
* Pipeline for vector embeddings with prime structure.
* Uses Quaternion, Hilbert space, and Resonance modules.
*/
import { Quaternion } from '../quaternion';
import { PrimeHilbertState, EntropyDrivenEvolution } from '../hilbert';
import { generatePrimes } from '../core/math';
import { BasePipeline, IEmbeddingCapable } from './base';
import { PipelineConfig, PipelineEventType, EmbeddingResult } from './types';
import { JSONBuilder } from '../core/serialization';
import { PI } from '../core/math';
const TWO_PI: f64 = 2.0 * PI;
/**
* EmbeddingPipeline - For vector embeddings with prime structure
*
* Components:
* - Quaternion algebra for rotations
* - Prime Hilbert space for state vectors
* - Resonance encoding for stable representations
*/
export class EmbeddingPipeline extends BasePipeline implements IEmbeddingCapable {
private hilbert!: PrimeHilbertState;
private evolution: EntropyDrivenEvolution | null = null;
private primes: Array<u32> = new Array<u32>();
private embeddingDim: i32 = 16;
private referenceState!: PrimeHilbertState;
constructor(config: PipelineConfig | null = null) {
super(config);
// Initialize with actual config values after super()
this.embeddingDim = this.config.numPrimes;
this.primes = generatePrimes(this.embeddingDim);
this.hilbert = new PrimeHilbertState(this.primes);
this.referenceState = PrimeHilbertState.uniform(this.primes);
}
getName(): string {
return "EmbeddingPipeline";
}
protected onInitialize(): void {
this.primes = generatePrimes(this.embeddingDim);
this.hilbert = new PrimeHilbertState(this.primes);
this.referenceState = PrimeHilbertState.uniform(this.primes);
this.evolution = new EntropyDrivenEvolution(this.hilbert, this.config.resonanceStrength, this.config.coherenceThreshold, this.config.defaultDt);
}
protected onStart(): void {
// Nothing special needed
}
protected onStop(): void {
// Nothing special needed
}
protected onTick(dt: f64, timestamp: i64): void {
// Step the evolution if available
if (this.evolution !== null) {
this.evolution.step();
this.hilbert = this.evolution.state;
}
// Check for resonance
const entropy = this.hilbert.entropy();
const coherence = this.hilbert.coherence(this.referenceState);
if (entropy < 0.5) {
this.emitResonance(`{"entropy":${entropy},"coherence":${coherence}}`);
}
}
protected onReset(): void {
this.onInitialize();
}
protected collectState(): void {
this.state.entropy = this.hilbert.entropy();
this.state.coherence = this.hilbert.coherence(this.referenceState);
}
// IEmbeddingCapable implementation
/**
* Embed text into vector space
*/
embed(input: string): Float64Array {
const result = new Float64Array(this.embeddingDim);
const textLen = input.length;
if (textLen == 0) return result;
// Character-based encoding into prime phases
for (let i = 0; i < textLen; i++) {
const charCode = input.charCodeAt(i);
const primeIdx = charCode % this.embeddingDim;
// Phase from position, amplitude from frequency
const phase = TWO_PI * f64(i) / f64(textLen);
const amplitude = 1.0 / f64(textLen);
// Add to embedding vector
result[primeIdx] += Math.cos(phase) * amplitude;
}
// Normalize
let norm: f64 = 0.0;
for (let i = 0; i < this.embeddingDim; i++) {
norm += result[i] * result[i];
}
norm = Math.sqrt(norm);
if (norm > 1e-10) {
for (let i = 0; i < this.embeddingDim; i++) {
result[i] /= norm;
}
}
return result;
}
/**
* Embed values into vector space
*/
embedValues(values: Float64Array): Float64Array {
const result = new Float64Array(this.embeddingDim);
const valLen = values.length;
// Project input values onto prime basis
for (let i = 0; i < valLen; i++) {
const primeIdx = i % this.embeddingDim;
result[primeIdx] += values[i];
}
// Apply quaternion rotation for mixing
const q = new Quaternion(
result[0] / 2,
result[1 % this.embeddingDim] / 2,
result[2 % this.embeddingDim] / 2,
result[3 % this.embeddingDim] / 2
).normalize();
// Rotate the embedding
for (let i = 0; i < this.embeddingDim; i++) {
const angle = q.w * f64(this.primes[i]);
result[i] = result[i] * Math.cos(angle) + (q.x + q.y + q.z) * Math.sin(angle) / 3.0;
}
// Normalize
let norm: f64 = 0.0;
for (let i = 0; i < this.embeddingDim; i++) {
norm += result[i] * result[i];
}
norm = Math.sqrt(norm);
if (norm > 1e-10) {
for (let i = 0; i < this.embeddingDim; i++) {
result[i] /= norm;
}
}
return result;
}
/**
* Calculate similarity between two embeddings
*/
similarity(a: Float64Array, b: Float64Array): f64 {
const n = Math.min(a.length, b.length) as i32;
let dot: f64 = 0.0;
let normA: f64 = 0.0;
let normB: f64 = 0.0;
for (let i = 0; i < n; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
const norms = Math.sqrt(normA * normB);
if (norms < 1e-10) return 0.0;
return dot / norms;
}
// Additional embedding methods
/**
* Get embedding dimension
*/
getDimension(): i32 {
return this.embeddingDim;
}
/**
* Get primes used for encoding
*/
getPrimes(): Array<u32> {
return this.primes;
}
/**
* Get Hilbert space entropy
*/
getHilbertEntropy(): f64 {
return this.hilbert.entropy();
}
/**
* Get Hilbert space coherence
*/
getHilbertCoherence(): f64 {
return this.hilbert.coherence(this.referenceState);
}
/**
* Get prime signature (dominant primes)
*/
getPrimeSignature(embedding: Float64Array, topN: i32 = 5): Array<u32> {
// Get indices sorted by absolute value
const indexed = new Array<i32>(embedding.length);
for (let i = 0; i < embedding.length; i++) {
indexed[i] = i;
}
// Sort by absolute value descending
indexed.sort((a: i32, b: i32): i32 => {
const valA = Math.abs(embedding[a]);
const valB = Math.abs(embedding[b]);
if (valB > valA) return 1;
if (valB < valA) return -1;
return 0;
});
// Return top N prime indices
const result = new Array<u32>();
const n = Math.min(topN, indexed.length) as i32;
for (let i = 0; i < n; i++) {
result.push(this.primes[indexed[i]]);
}
return result;
}
/**
* Get embedding result with all metrics
*/
getEmbeddingResult(input: string): EmbeddingResult {
const vector = this.embed(input);
const result = new EmbeddingResult(this.embeddingDim);
// Copy vector
for (let i = 0; i < this.embeddingDim; i++) {
result.vector[i] = vector[i];
}
// Get prime signature
const sig = this.getPrimeSignature(vector, 5);
for (let i = 0; i < sig.length; i++) {
result.primeSignature.push(sig[i] as i32);
}
// Get quaternion components from first 4 values
const q = new Quaternion(
vector[0],
vector[1 % this.embeddingDim],
vector[2 % this.embeddingDim],
vector[3 % this.embeddingDim]
).normalize();
result.quaternionComponents[0] = q.w;
result.quaternionComponents[1] = q.x;
result.quaternionComponents[2] = q.y;
result.quaternionComponents[3] = q.z;
return result;
}
/**
* Project to lower dimension using quaternion
*/
projectTo4D(embedding: Float64Array): Float64Array {
const result = new Float64Array(4);
// Sum into quaternion components
for (let i = 0; i < embedding.length; i++) {
result[i % 4] += embedding[i];
}
// Normalize
let norm: f64 = 0.0;
for (let i = 0; i < 4; i++) {
norm += result[i] * result[i];
}
norm = Math.sqrt(norm);
if (norm > 1e-10) {
for (let i = 0; i < 4; i++) {
result[i] /= norm;
}
}
return result;
}
toJSON(): string {
const builder = new JSONBuilder();
builder.startObject()
.addStringField("name", this.getName())
.addBooleanField("running", this.running)
.addNumberField("dimension", f64(this.embeddingDim))
.addNumberField("hilbertEntropy", this.getHilbertEntropy())
.addNumberField("hilbertCoherence", this.getHilbertCoherence())
.endObject();
return builder.build();
}
}
// Factory function
export function createEmbeddingPipeline(config: PipelineConfig | null = null): EmbeddingPipeline {
const pipeline = new EmbeddingPipeline(config);
pipeline.initialize();
return pipeline;
}