@aleph-ai/tinyaleph 1.2.0 → 1.3.0
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.
- package/README.md +187 -2
- package/backends/bioinformatics/binding.js +503 -0
- package/backends/bioinformatics/dna-computing.js +664 -0
- package/backends/bioinformatics/encoding.js +339 -0
- package/backends/bioinformatics/folding.js +454 -0
- package/backends/bioinformatics/genetic-code.js +269 -0
- package/backends/bioinformatics/index.js +522 -0
- package/backends/bioinformatics/transcription.js +221 -0
- package/backends/bioinformatics/translation.js +264 -0
- package/backends/index.js +25 -1
- package/core/compound.js +532 -0
- package/core/hilbert.js +454 -1
- package/core/index.js +106 -12
- package/core/inference.js +605 -0
- package/core/resonance.js +245 -616
- package/core/symbols/archetypes.js +478 -0
- package/core/symbols/base.js +302 -0
- package/core/symbols/elements.js +487 -0
- package/core/symbols/hieroglyphs.js +303 -0
- package/core/symbols/iching.js +471 -0
- package/core/symbols/index.js +77 -0
- package/core/symbols/tarot.js +211 -0
- package/core/symbols.js +22 -0
- package/docs/design/BIOINFORMATICS_BACKEND_DESIGN.md +493 -0
- package/docs/guide/06-symbolic-ai.md +370 -0
- package/docs/guide/README.md +2 -1
- package/docs/reference/05-symbolic-ai.md +570 -0
- package/docs/reference/06-bioinformatics.md +546 -0
- package/docs/reference/README.md +32 -2
- package/docs/theory/11-prgraph-memory.md +559 -0
- package/docs/theory/12-resonant-attention.md +661 -0
- package/modular.js +33 -1
- package/package.json +1 -1
- package/physics/index.js +16 -0
- package/physics/kuramoto-coupled-ladder.js +603 -0
package/core/resonance.js
CHANGED
|
@@ -1,695 +1,324 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Resonance Calculator
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Entanglement and Coherence
|
|
7
|
-
* - Phase-Locked Prime Rings
|
|
8
|
-
* - Holographic Memory Fields
|
|
4
|
+
* Implements Prime Resonance Theory from symprime:
|
|
5
|
+
* Calculates "resonance" between prime numbers using golden ratio detection.
|
|
9
6
|
*
|
|
10
|
-
*
|
|
7
|
+
* Theory: Primes whose ratio approximates the golden ratio (φ ≈ 1.618)
|
|
8
|
+
* have "natural harmony" - a mathematically grounded measure of affinity.
|
|
9
|
+
*
|
|
10
|
+
* R(p1, p2) = 1/ratio + φ_bonus
|
|
11
|
+
* where φ_bonus = 0.3 if |ratio - φ| < threshold
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const PHI = (1 + Math.sqrt(5)) / 2; // 1.618...
|
|
18
|
-
const PHI_CONJ = (1 - Math.sqrt(5)) / 2; // -0.618...
|
|
19
|
-
const DELTA_S = Math.sqrt(2); // Another irrational for phase locks
|
|
14
|
+
// Golden ratio constant
|
|
15
|
+
const PHI = 1.618033988749895;
|
|
16
|
+
const PHI_THRESHOLD = 0.1; // How close to φ counts as "golden"
|
|
17
|
+
const PHI_BONUS = 0.3; // Bonus for golden ratio relationships
|
|
20
18
|
|
|
21
19
|
/**
|
|
22
|
-
*
|
|
23
|
-
* Using Hamilton quaternions: q = a + bi + cj + dk
|
|
20
|
+
* ResonanceCalculator - Measures harmonic relationships between primes
|
|
24
21
|
*/
|
|
25
|
-
class
|
|
26
|
-
constructor(
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
this.c = c;
|
|
30
|
-
this.d = d;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static fromPrime(p) {
|
|
34
|
-
// Embed a prime in quaternion space using a specific encoding
|
|
35
|
-
// p → (p, 0, 0, 0) for simplicity, or a more interesting embedding
|
|
36
|
-
const sqrt = Math.sqrt(p);
|
|
37
|
-
return new QuaternionPrime(p, 0, 0, 0);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static fromGaussian(g) {
|
|
41
|
-
return new QuaternionPrime(g.real, g.imag, 0, 0);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
norm() {
|
|
45
|
-
return Math.sqrt(this.a*this.a + this.b*this.b + this.c*this.c + this.d*this.d);
|
|
22
|
+
class ResonanceCalculator {
|
|
23
|
+
constructor(cacheSize = 1000) {
|
|
24
|
+
this.cacheSize = cacheSize;
|
|
25
|
+
this.cache = new Map();
|
|
46
26
|
}
|
|
47
|
-
|
|
48
|
-
add(other) {
|
|
49
|
-
return new QuaternionPrime(
|
|
50
|
-
this.a + other.a,
|
|
51
|
-
this.b + other.b,
|
|
52
|
-
this.c + other.c,
|
|
53
|
-
this.d + other.d
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
mul(other) {
|
|
58
|
-
// Hamilton product
|
|
59
|
-
return new QuaternionPrime(
|
|
60
|
-
this.a*other.a - this.b*other.b - this.c*other.c - this.d*other.d,
|
|
61
|
-
this.a*other.b + this.b*other.a + this.c*other.d - this.d*other.c,
|
|
62
|
-
this.a*other.c - this.b*other.d + this.c*other.a + this.d*other.b,
|
|
63
|
-
this.a*other.d + this.b*other.c - this.c*other.b + this.d*other.a
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
conjugate() {
|
|
68
|
-
return new QuaternionPrime(this.a, -this.b, -this.c, -this.d);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
isHurwitzPrime() {
|
|
72
|
-
// A Hurwitz quaternion is prime if its norm is a rational prime
|
|
73
|
-
const n = this.norm();
|
|
74
|
-
return isPrime(Math.round(n * n));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
toArray() {
|
|
78
|
-
return [this.a, this.b, this.c, this.d];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
toString() {
|
|
82
|
-
return `${this.a} + ${this.b}i + ${this.c}j + ${this.d}k`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
27
|
|
|
86
|
-
/**
|
|
87
|
-
* Prime Resonance Identity (PRI)
|
|
88
|
-
* A triadic identity composed of:
|
|
89
|
-
* - P_G: Gaussian prime
|
|
90
|
-
* - P_E: Eisenstein prime
|
|
91
|
-
* - P_Q: Quaternionic prime
|
|
92
|
-
*/
|
|
93
|
-
class PrimeResonanceIdentity {
|
|
94
|
-
constructor(gaussianPrime, eisensteinPrime, quaternionPrime) {
|
|
95
|
-
this.gaussian = gaussianPrime; // GaussianInteger
|
|
96
|
-
this.eisenstein = eisensteinPrime; // EisensteinInteger
|
|
97
|
-
this.quaternion = quaternionPrime; // QuaternionPrime
|
|
98
|
-
|
|
99
|
-
// Compute combined signature
|
|
100
|
-
this._computeSignature();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
_computeSignature() {
|
|
104
|
-
const gNorm = this.gaussian.norm();
|
|
105
|
-
const eNorm = this.eisenstein.norm();
|
|
106
|
-
const qNorm = this.quaternion.norm();
|
|
107
|
-
|
|
108
|
-
// Signature is a triple of norms
|
|
109
|
-
this.signature = [gNorm, eNorm, qNorm];
|
|
110
|
-
|
|
111
|
-
// Hash from signature
|
|
112
|
-
this.hash = (gNorm * 997 + eNorm * 991 + Math.round(qNorm) * 983) % 1000000007;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
28
|
/**
|
|
116
|
-
*
|
|
29
|
+
* Calculate resonance between two primes
|
|
30
|
+
* R(p1, p2) = 1/ratio + φ_bonus
|
|
31
|
+
*
|
|
32
|
+
* @param {number|bigint} p1 - First prime
|
|
33
|
+
* @param {number|bigint} p2 - Second prime
|
|
34
|
+
* @returns {number} Resonance value between 0 and ~1.3
|
|
117
35
|
*/
|
|
118
|
-
|
|
119
|
-
//
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const p3 = firstNPrimes(seed + 20)[seed % 10 + 12];
|
|
123
|
-
|
|
124
|
-
// Create Gaussian prime: find a + bi where a² + b² is prime
|
|
125
|
-
const g = new GaussianInteger(p1 % 100, (seed * 7) % 50);
|
|
126
|
-
|
|
127
|
-
// Create Eisenstein prime: find a + bω where a² - ab + b² ≡ 2 (mod 3)
|
|
128
|
-
const e = new EisensteinInteger(p2 % 100, (seed * 11) % 50);
|
|
129
|
-
|
|
130
|
-
// Create Quaternion prime
|
|
131
|
-
const q = new QuaternionPrime(p3, seed % 10, (seed * 3) % 10, (seed * 7) % 10);
|
|
132
|
-
|
|
133
|
-
return new PrimeResonanceIdentity(g, e, q);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Generate a random PRI
|
|
138
|
-
*/
|
|
139
|
-
static random() {
|
|
140
|
-
const primes = firstNPrimes(50);
|
|
141
|
-
|
|
142
|
-
const idx1 = Math.floor(Math.random() * primes.length);
|
|
143
|
-
const idx2 = Math.floor(Math.random() * primes.length);
|
|
144
|
-
const idx3 = Math.floor(Math.random() * primes.length);
|
|
145
|
-
|
|
146
|
-
const p1 = primes[idx1];
|
|
147
|
-
const p2 = primes[idx2];
|
|
148
|
-
const p3 = primes[idx3];
|
|
149
|
-
|
|
150
|
-
const g = new GaussianInteger(p1, Math.floor(Math.random() * 10));
|
|
151
|
-
const e = new EisensteinInteger(p2, Math.floor(Math.random() * 10));
|
|
152
|
-
const q = new QuaternionPrime(p3,
|
|
153
|
-
Math.floor(Math.random() * 5),
|
|
154
|
-
Math.floor(Math.random() * 5),
|
|
155
|
-
Math.floor(Math.random() * 5)
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
return new PrimeResonanceIdentity(g, e, q);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Compute entanglement strength with another PRI
|
|
163
|
-
*/
|
|
164
|
-
entanglementStrength(other) {
|
|
165
|
-
// Based on phase alignment and norm similarity
|
|
166
|
-
const gPhase = Math.atan2(this.gaussian.imag, this.gaussian.real);
|
|
167
|
-
const gPhaseOther = Math.atan2(other.gaussian.imag, other.gaussian.real);
|
|
168
|
-
|
|
169
|
-
const ePhase = Math.atan2(this.eisenstein.b * Math.sqrt(3)/2,
|
|
170
|
-
this.eisenstein.a - this.eisenstein.b/2);
|
|
171
|
-
const ePhaseOther = Math.atan2(other.eisenstein.b * Math.sqrt(3)/2,
|
|
172
|
-
other.eisenstein.a - other.eisenstein.b/2);
|
|
173
|
-
|
|
174
|
-
const gAlignment = Math.cos(gPhase - gPhaseOther);
|
|
175
|
-
const eAlignment = Math.cos(ePhase - ePhaseOther);
|
|
176
|
-
|
|
177
|
-
// Quaternion alignment via normalized dot product
|
|
178
|
-
const qNorm = this.quaternion.norm() * other.quaternion.norm();
|
|
179
|
-
const qDot = (this.quaternion.a * other.quaternion.a +
|
|
180
|
-
this.quaternion.b * other.quaternion.b +
|
|
181
|
-
this.quaternion.c * other.quaternion.c +
|
|
182
|
-
this.quaternion.d * other.quaternion.d);
|
|
183
|
-
const qAlignment = qNorm > 0 ? qDot / qNorm : 0;
|
|
184
|
-
|
|
185
|
-
// Combined entanglement strength
|
|
186
|
-
return (gAlignment + eAlignment + qAlignment) / 3;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
toJSON() {
|
|
190
|
-
return {
|
|
191
|
-
gaussian: { real: this.gaussian.real, imag: this.gaussian.imag },
|
|
192
|
-
eisenstein: { a: this.eisenstein.a, b: this.eisenstein.b },
|
|
193
|
-
quaternion: this.quaternion.toArray(),
|
|
194
|
-
signature: this.signature,
|
|
195
|
-
hash: this.hash
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Phase-Locked Prime Ring
|
|
202
|
-
* Implements stable communication via irrational phase locks
|
|
203
|
-
*/
|
|
204
|
-
class PhaseLockedRing {
|
|
205
|
-
constructor(primes, phaseType = 'phi') {
|
|
206
|
-
this.primes = primes;
|
|
207
|
-
this.n = primes.length;
|
|
208
|
-
this.phases = new Float64Array(this.n);
|
|
36
|
+
calculateResonance(p1, p2) {
|
|
37
|
+
// Convert to numbers for calculation
|
|
38
|
+
const n1 = Number(p1);
|
|
39
|
+
const n2 = Number(p2);
|
|
209
40
|
|
|
210
|
-
//
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
// Initialize phases using irrational multiples
|
|
216
|
-
for (let i = 0; i < this.n; i++) {
|
|
217
|
-
this.phases[i] = (i * this.phaseMultiplier) % (2 * Math.PI);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Advance all phases by one step
|
|
223
|
-
*/
|
|
224
|
-
tick(dt = 0.01) {
|
|
225
|
-
for (let i = 0; i < this.n; i++) {
|
|
226
|
-
// Each prime oscillates at frequency proportional to log(p)
|
|
227
|
-
const freq = Math.log(this.primes[i]);
|
|
228
|
-
this.phases[i] = (this.phases[i] + freq * dt * this.phaseMultiplier) % (2 * Math.PI);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Compute order parameter (Kuramoto-style)
|
|
234
|
-
* r = |1/N Σ e^(iθ_j)|
|
|
235
|
-
*/
|
|
236
|
-
orderParameter() {
|
|
237
|
-
let sumReal = 0, sumImag = 0;
|
|
238
|
-
for (let i = 0; i < this.n; i++) {
|
|
239
|
-
sumReal += Math.cos(this.phases[i]);
|
|
240
|
-
sumImag += Math.sin(this.phases[i]);
|
|
41
|
+
// Check cache
|
|
42
|
+
const cacheKey = n1 < n2 ? `${n1},${n2}` : `${n2},${n1}`;
|
|
43
|
+
if (this.cache.has(cacheKey)) {
|
|
44
|
+
return this.cache.get(cacheKey);
|
|
241
45
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Synchronization measure
|
|
259
|
-
* How well are phases aligned?
|
|
260
|
-
*/
|
|
261
|
-
synchronization() {
|
|
262
|
-
const order = this.orderParameter();
|
|
263
|
-
return order; // 0 = no sync, 1 = perfect sync
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Apply phase correction toward target
|
|
268
|
-
*/
|
|
269
|
-
correctPhase(targetPhase, strength = 0.1) {
|
|
270
|
-
for (let i = 0; i < this.n; i++) {
|
|
271
|
-
const diff = targetPhase - this.phases[i];
|
|
272
|
-
const correction = Math.sin(diff) * strength;
|
|
273
|
-
this.phases[i] = (this.phases[i] + correction) % (2 * Math.PI);
|
|
46
|
+
|
|
47
|
+
// Handle edge cases
|
|
48
|
+
if (n1 === 0 || n2 === 0) return 0;
|
|
49
|
+
if (n1 === n2) return 1.0; // Self-resonance is perfect
|
|
50
|
+
|
|
51
|
+
// Calculate ratio (larger / smaller)
|
|
52
|
+
const [smaller, larger] = n1 < n2 ? [n1, n2] : [n2, n1];
|
|
53
|
+
const ratio = larger / smaller;
|
|
54
|
+
|
|
55
|
+
// Base resonance: inverse of ratio (closer primes resonate more)
|
|
56
|
+
let resonance = 1.0 / ratio;
|
|
57
|
+
|
|
58
|
+
// Add golden ratio bonus if applicable
|
|
59
|
+
if (this.isGoldenRatio(ratio)) {
|
|
60
|
+
resonance += PHI_BONUS;
|
|
274
61
|
}
|
|
62
|
+
|
|
63
|
+
// Cache result
|
|
64
|
+
this.addToCache(cacheKey, resonance);
|
|
65
|
+
|
|
66
|
+
return resonance;
|
|
275
67
|
}
|
|
276
|
-
|
|
68
|
+
|
|
277
69
|
/**
|
|
278
|
-
*
|
|
70
|
+
* Check if a ratio is close to the golden ratio
|
|
279
71
|
*/
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
for (let i = 0; i < this.n && i < state.primes.length; i++) {
|
|
283
|
-
const p = this.primes[i];
|
|
284
|
-
if (state.amplitudes.has(p)) {
|
|
285
|
-
state.set(p, Complex.fromPolar(1, this.phases[i]));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return state.normalize();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
getPhases() {
|
|
292
|
-
return [...this.phases];
|
|
72
|
+
isGoldenRatio(ratio) {
|
|
73
|
+
return Math.abs(ratio - PHI) < PHI_THRESHOLD;
|
|
293
74
|
}
|
|
294
|
-
}
|
|
295
75
|
|
|
296
|
-
/**
|
|
297
|
-
* Holographic Memory Field
|
|
298
|
-
* 2D spatial representation of prime-encoded information
|
|
299
|
-
* I(x,y) = Σ A_p e^(-S(x,y)) e^(ipθ)
|
|
300
|
-
*/
|
|
301
|
-
class HolographicField {
|
|
302
|
-
constructor(width = 64, height = 64, primes = null) {
|
|
303
|
-
this.width = width;
|
|
304
|
-
this.height = height;
|
|
305
|
-
this.primes = primes || firstNPrimes(25);
|
|
306
|
-
|
|
307
|
-
// Complex amplitude field
|
|
308
|
-
this.field = new Array(height);
|
|
309
|
-
for (let y = 0; y < height; y++) {
|
|
310
|
-
this.field[y] = new Array(width);
|
|
311
|
-
for (let x = 0; x < width; x++) {
|
|
312
|
-
this.field[y][x] = Complex.zero();
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Entropy surface S(x,y)
|
|
317
|
-
this.entropyField = new Array(height);
|
|
318
|
-
for (let y = 0; y < height; y++) {
|
|
319
|
-
this.entropyField[y] = new Float64Array(width);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
76
|
/**
|
|
324
|
-
*
|
|
77
|
+
* Find prime pairs near the golden ratio
|
|
78
|
+
* These are "naturally harmonic" pairs
|
|
79
|
+
*
|
|
80
|
+
* @param {number[]} primes - Array of primes to search
|
|
81
|
+
* @returns {Array<{p1: number, p2: number, ratio: number, resonance: number}>}
|
|
325
82
|
*/
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
centerY = centerY ?? this.height / 2;
|
|
329
|
-
|
|
330
|
-
const sigma = Math.min(this.width, this.height) / 4; // Spread
|
|
83
|
+
findGoldenPairs(primes) {
|
|
84
|
+
const pairs = [];
|
|
331
85
|
|
|
332
|
-
for (let
|
|
333
|
-
for (let
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
const theta = Math.atan2(dy, dx);
|
|
338
|
-
|
|
339
|
-
// Gaussian envelope
|
|
340
|
-
const envelope = Math.exp(-r*r / (2*sigma*sigma));
|
|
341
|
-
|
|
342
|
-
// Sum over primes
|
|
343
|
-
let sum = Complex.zero();
|
|
344
|
-
for (const p of state.primes) {
|
|
345
|
-
const amp = state.get(p);
|
|
346
|
-
const phase = p * theta; // e^(ipθ)
|
|
347
|
-
const contribution = amp.mul(Complex.fromPolar(envelope, phase));
|
|
348
|
-
sum = sum.add(contribution);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
this.field[y][x] = this.field[y][x].add(sum);
|
|
86
|
+
for (let i = 0; i < primes.length; i++) {
|
|
87
|
+
for (let j = i + 1; j < primes.length; j++) {
|
|
88
|
+
const p1 = primes[i];
|
|
89
|
+
const p2 = primes[j];
|
|
90
|
+
const ratio = p2 / p1;
|
|
352
91
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
92
|
+
if (this.isGoldenRatio(ratio)) {
|
|
93
|
+
pairs.push({
|
|
94
|
+
p1,
|
|
95
|
+
p2,
|
|
96
|
+
ratio,
|
|
97
|
+
resonance: this.calculateResonance(p1, p2)
|
|
98
|
+
});
|
|
357
99
|
}
|
|
358
100
|
}
|
|
359
101
|
}
|
|
102
|
+
|
|
103
|
+
return pairs.sort((a, b) =>
|
|
104
|
+
Math.abs(a.ratio - PHI) - Math.abs(b.ratio - PHI)
|
|
105
|
+
);
|
|
360
106
|
}
|
|
361
|
-
|
|
107
|
+
|
|
362
108
|
/**
|
|
363
|
-
*
|
|
109
|
+
* Calculate vectorized resonance matrix for multiple primes
|
|
110
|
+
*
|
|
111
|
+
* @param {number[]} primes - Array of primes
|
|
112
|
+
* @returns {number[][]} NxN matrix of resonance values
|
|
364
113
|
*/
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
for (let
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
if (px >= 0 && px < this.width && py >= 0 && py < this.height) {
|
|
375
|
-
const val = this.field[py][px];
|
|
376
|
-
const theta = Math.atan2(dy, dx);
|
|
377
|
-
|
|
378
|
-
// Recover prime contributions
|
|
379
|
-
for (const p of this.primes) {
|
|
380
|
-
const phase = -p * theta; // Inverse of encoding phase
|
|
381
|
-
const contribution = val.mul(Complex.fromPolar(1, phase));
|
|
382
|
-
state.set(p, state.get(p).add(contribution.scale(1 / (4 * radius * radius))));
|
|
383
|
-
}
|
|
384
|
-
}
|
|
114
|
+
calculateMatrix(primes) {
|
|
115
|
+
const n = primes.length;
|
|
116
|
+
const matrix = [];
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < n; i++) {
|
|
119
|
+
matrix[i] = [];
|
|
120
|
+
for (let j = 0; j < n; j++) {
|
|
121
|
+
matrix[i][j] = this.calculateResonance(primes[i], primes[j]);
|
|
385
122
|
}
|
|
386
123
|
}
|
|
387
|
-
|
|
388
|
-
return
|
|
124
|
+
|
|
125
|
+
return matrix;
|
|
389
126
|
}
|
|
390
|
-
|
|
127
|
+
|
|
391
128
|
/**
|
|
392
|
-
*
|
|
129
|
+
* Calculate average resonance of a prime with a set
|
|
130
|
+
*
|
|
131
|
+
* @param {number} prime - Target prime
|
|
132
|
+
* @param {number[]} primes - Set of primes to compare
|
|
133
|
+
* @returns {number} Average resonance
|
|
393
134
|
*/
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
|
|
135
|
+
calculateAverageResonance(prime, primes) {
|
|
136
|
+
if (primes.length === 0) return 0;
|
|
137
|
+
|
|
138
|
+
let sum = 0;
|
|
139
|
+
for (const p of primes) {
|
|
140
|
+
sum += this.calculateResonance(prime, p);
|
|
397
141
|
}
|
|
398
|
-
|
|
142
|
+
|
|
143
|
+
return sum / primes.length;
|
|
399
144
|
}
|
|
400
|
-
|
|
145
|
+
|
|
401
146
|
/**
|
|
402
|
-
*
|
|
147
|
+
* Find the most resonant prime from a set
|
|
148
|
+
*
|
|
149
|
+
* @param {number} target - Target prime
|
|
150
|
+
* @param {number[]} candidates - Candidate primes
|
|
151
|
+
* @returns {{prime: number, resonance: number}|null}
|
|
403
152
|
*/
|
|
404
|
-
|
|
405
|
-
if (
|
|
406
|
-
|
|
153
|
+
findMostResonant(target, candidates) {
|
|
154
|
+
if (candidates.length === 0) return null;
|
|
155
|
+
|
|
156
|
+
let maxResonance = -1;
|
|
157
|
+
let mostResonant = null;
|
|
158
|
+
|
|
159
|
+
for (const candidate of candidates) {
|
|
160
|
+
const resonance = this.calculateResonance(target, candidate);
|
|
161
|
+
if (resonance > maxResonance) {
|
|
162
|
+
maxResonance = resonance;
|
|
163
|
+
mostResonant = candidate;
|
|
164
|
+
}
|
|
407
165
|
}
|
|
408
|
-
|
|
166
|
+
|
|
167
|
+
return { prime: mostResonant, resonance: maxResonance };
|
|
409
168
|
}
|
|
410
|
-
|
|
169
|
+
|
|
411
170
|
/**
|
|
412
|
-
* Find
|
|
171
|
+
* Find resonance clusters - groups of primes with high mutual resonance
|
|
172
|
+
*
|
|
173
|
+
* @param {number[]} primes - Primes to cluster
|
|
174
|
+
* @param {number} threshold - Minimum resonance for cluster membership
|
|
175
|
+
* @returns {number[][]} Array of clusters
|
|
413
176
|
*/
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
for (
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
isMax = false;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (isMax) {
|
|
436
|
-
peaks.push({ x, y, intensity, phase: this.field[y][x].phase() });
|
|
437
|
-
}
|
|
177
|
+
findClusters(primes, threshold = 0.5) {
|
|
178
|
+
const clusters = [];
|
|
179
|
+
const visited = new Set();
|
|
180
|
+
|
|
181
|
+
for (const p of primes) {
|
|
182
|
+
if (visited.has(p)) continue;
|
|
183
|
+
|
|
184
|
+
const cluster = [p];
|
|
185
|
+
visited.add(p);
|
|
186
|
+
|
|
187
|
+
for (const q of primes) {
|
|
188
|
+
if (visited.has(q)) continue;
|
|
189
|
+
if (this.calculateResonance(p, q) >= threshold) {
|
|
190
|
+
cluster.push(q);
|
|
191
|
+
visited.add(q);
|
|
438
192
|
}
|
|
439
193
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
maxIntensity() {
|
|
446
|
-
let max = 0;
|
|
447
|
-
for (let y = 0; y < this.height; y++) {
|
|
448
|
-
for (let x = 0; x < this.width; x++) {
|
|
449
|
-
const i = this.field[y][x].norm2();
|
|
450
|
-
if (i > max) max = i;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
return max;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* Clear the field
|
|
458
|
-
*/
|
|
459
|
-
clear() {
|
|
460
|
-
for (let y = 0; y < this.height; y++) {
|
|
461
|
-
for (let x = 0; x < this.width; x++) {
|
|
462
|
-
this.field[y][x] = Complex.zero();
|
|
463
|
-
this.entropyField[y][x] = 0;
|
|
194
|
+
|
|
195
|
+
if (cluster.length > 1) {
|
|
196
|
+
clusters.push(cluster);
|
|
464
197
|
}
|
|
465
198
|
}
|
|
199
|
+
|
|
200
|
+
return clusters;
|
|
466
201
|
}
|
|
467
|
-
|
|
202
|
+
|
|
468
203
|
/**
|
|
469
|
-
*
|
|
204
|
+
* Add entry to cache with LRU eviction
|
|
470
205
|
*/
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const idx = (y * this.width + x) * 4;
|
|
478
|
-
const intensity = max > 0 ? this.field[y][x].norm2() / max : 0;
|
|
479
|
-
const phase = (this.field[y][x].phase() + Math.PI) / (2 * Math.PI);
|
|
480
|
-
|
|
481
|
-
// HSV to RGB (hue = phase, value = intensity)
|
|
482
|
-
const h = phase * 360;
|
|
483
|
-
const s = 1;
|
|
484
|
-
const v = Math.sqrt(intensity); // sqrt for gamma correction
|
|
485
|
-
|
|
486
|
-
const [r, g, b] = hsvToRgb(h, s, v);
|
|
487
|
-
data[idx] = r;
|
|
488
|
-
data[idx + 1] = g;
|
|
489
|
-
data[idx + 2] = b;
|
|
490
|
-
data[idx + 3] = 255;
|
|
206
|
+
addToCache(key, value) {
|
|
207
|
+
if (this.cache.size >= this.cacheSize) {
|
|
208
|
+
// Remove oldest entry (first key)
|
|
209
|
+
const firstKey = this.cache.keys().next().value;
|
|
210
|
+
if (firstKey !== undefined) {
|
|
211
|
+
this.cache.delete(firstKey);
|
|
491
212
|
}
|
|
492
213
|
}
|
|
493
|
-
|
|
494
|
-
return { width: this.width, height: this.height, data };
|
|
214
|
+
this.cache.set(key, value);
|
|
495
215
|
}
|
|
496
|
-
}
|
|
497
216
|
|
|
498
|
-
// Helper: HSV to RGB conversion
|
|
499
|
-
function hsvToRgb(h, s, v) {
|
|
500
|
-
const c = v * s;
|
|
501
|
-
const x = c * (1 - Math.abs((h / 60) % 2 - 1));
|
|
502
|
-
const m = v - c;
|
|
503
|
-
|
|
504
|
-
let r = 0, g = 0, b = 0;
|
|
505
|
-
if (h < 60) { r = c; g = x; }
|
|
506
|
-
else if (h < 120) { r = x; g = c; }
|
|
507
|
-
else if (h < 180) { g = c; b = x; }
|
|
508
|
-
else if (h < 240) { g = x; b = c; }
|
|
509
|
-
else if (h < 300) { r = x; b = c; }
|
|
510
|
-
else { r = c; b = x; }
|
|
511
|
-
|
|
512
|
-
return [
|
|
513
|
-
Math.round((r + m) * 255),
|
|
514
|
-
Math.round((g + m) * 255),
|
|
515
|
-
Math.round((b + m) * 255)
|
|
516
|
-
];
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Entangled Node (from ResoLang spec)
|
|
521
|
-
* A network node with PRI, phase ring, and holographic memory
|
|
522
|
-
*/
|
|
523
|
-
class EntangledNode {
|
|
524
|
-
constructor(id, pri = null) {
|
|
525
|
-
this.id = id;
|
|
526
|
-
this.pri = pri || PrimeResonanceIdentity.random();
|
|
527
|
-
this.phaseRing = new PhaseLockedRing(firstNPrimes(16));
|
|
528
|
-
this.holographicMemory = new HolographicField(32, 32);
|
|
529
|
-
this.entanglementMap = new Map(); // nodeId -> strength
|
|
530
|
-
this.coherence = 1.0;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
217
|
/**
|
|
534
|
-
*
|
|
218
|
+
* Clear the resonance cache
|
|
535
219
|
*/
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
this.entanglementMap.set(other.id, strength);
|
|
539
|
-
other.entanglementMap.set(this.id, strength);
|
|
540
|
-
return strength;
|
|
220
|
+
clearCache() {
|
|
221
|
+
this.cache.clear();
|
|
541
222
|
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Store a memory fragment
|
|
545
|
-
*/
|
|
546
|
-
storeMemory(state, x = null, y = null) {
|
|
547
|
-
this.holographicMemory.encodeState(state, x, y);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* Retrieve memory at position
|
|
552
|
-
*/
|
|
553
|
-
retrieveMemory(x, y) {
|
|
554
|
-
return this.holographicMemory.decodeAt(x, y);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Advance node state
|
|
559
|
-
*/
|
|
560
|
-
tick(dt = 0.01) {
|
|
561
|
-
this.phaseRing.tick(dt);
|
|
562
|
-
|
|
563
|
-
// Coherence decays slightly over time
|
|
564
|
-
this.coherence *= (1 - 0.001 * dt);
|
|
565
|
-
|
|
566
|
-
// But increases with synchronization
|
|
567
|
-
this.coherence = Math.min(1, this.coherence + this.phaseRing.synchronization() * 0.002 * dt);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Get current state as PrimeState
|
|
572
|
-
*/
|
|
573
|
-
getState() {
|
|
574
|
-
return this.phaseRing.toPrimeState();
|
|
575
|
-
}
|
|
576
|
-
|
|
223
|
+
|
|
577
224
|
/**
|
|
578
|
-
*
|
|
225
|
+
* Get cache statistics
|
|
579
226
|
*/
|
|
580
|
-
|
|
581
|
-
return this.coherence > 0.85 && this.phaseRing.synchronization() > 0.7;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
toJSON() {
|
|
227
|
+
getCacheStats() {
|
|
585
228
|
return {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
coherence: this.coherence,
|
|
589
|
-
synchronization: this.phaseRing.synchronization(),
|
|
590
|
-
entanglements: Array.from(this.entanglementMap.entries())
|
|
229
|
+
size: this.cache.size,
|
|
230
|
+
maxSize: this.cacheSize
|
|
591
231
|
};
|
|
592
232
|
}
|
|
593
233
|
}
|
|
594
234
|
|
|
595
235
|
/**
|
|
596
|
-
*
|
|
597
|
-
*
|
|
236
|
+
* Compute resonance signature for a set of primes
|
|
237
|
+
* This is a composite measure of internal harmony
|
|
238
|
+
*
|
|
239
|
+
* @param {number[]} primes - Set of primes
|
|
240
|
+
* @param {ResonanceCalculator} calc - Calculator instance
|
|
241
|
+
* @returns {{mean: number, variance: number, goldenCount: number}}
|
|
598
242
|
*/
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
this.centerX = centerX;
|
|
603
|
-
this.centerY = centerY;
|
|
604
|
-
this.entropy = state.entropy();
|
|
605
|
-
this.createdAt = Date.now();
|
|
243
|
+
function resonanceSignature(primes, calc = new ResonanceCalculator()) {
|
|
244
|
+
if (primes.length < 2) {
|
|
245
|
+
return { mean: 1, variance: 0, goldenCount: 0 };
|
|
606
246
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
*/
|
|
620
|
-
static fromPrimes(primes, weights = null) {
|
|
621
|
-
const state = new PrimeState();
|
|
622
|
-
for (let i = 0; i < primes.length; i++) {
|
|
623
|
-
const p = primes[i];
|
|
624
|
-
const w = weights ? weights[i] : 1 / primes.length;
|
|
625
|
-
if (state.amplitudes.has(p)) {
|
|
626
|
-
state.set(p, new Complex(w, 0));
|
|
247
|
+
|
|
248
|
+
const resonances = [];
|
|
249
|
+
let goldenCount = 0;
|
|
250
|
+
|
|
251
|
+
for (let i = 0; i < primes.length; i++) {
|
|
252
|
+
for (let j = i + 1; j < primes.length; j++) {
|
|
253
|
+
const r = calc.calculateResonance(primes[i], primes[j]);
|
|
254
|
+
resonances.push(r);
|
|
255
|
+
|
|
256
|
+
const ratio = Math.max(primes[i], primes[j]) / Math.min(primes[i], primes[j]);
|
|
257
|
+
if (calc.isGoldenRatio(ratio)) {
|
|
258
|
+
goldenCount++;
|
|
627
259
|
}
|
|
628
260
|
}
|
|
629
|
-
return new ResonantFragment(state.normalize());
|
|
630
261
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
262
|
+
|
|
263
|
+
const mean = resonances.reduce((a, b) => a + b, 0) / resonances.length;
|
|
264
|
+
const variance = resonances.reduce((sum, r) => sum + (r - mean) ** 2, 0) / resonances.length;
|
|
265
|
+
|
|
266
|
+
return { mean, variance, goldenCount };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Find Fibonacci-like sequences in primes (which approximate golden ratio)
|
|
271
|
+
* These sequences have naturally high resonance
|
|
272
|
+
*
|
|
273
|
+
* @param {number[]} primes - Sorted array of primes
|
|
274
|
+
* @param {number} minLength - Minimum sequence length
|
|
275
|
+
* @returns {number[][]} Fibonacci-like sequences
|
|
276
|
+
*/
|
|
277
|
+
function findFibonacciSequences(primes, minLength = 3) {
|
|
278
|
+
const sequences = [];
|
|
279
|
+
|
|
280
|
+
for (let i = 0; i < primes.length; i++) {
|
|
281
|
+
for (let j = i + 1; j < primes.length; j++) {
|
|
282
|
+
const seq = [primes[i], primes[j]];
|
|
283
|
+
|
|
284
|
+
// Try to extend the sequence
|
|
285
|
+
let next = primes[i] + primes[j];
|
|
286
|
+
let k = j + 1;
|
|
287
|
+
|
|
288
|
+
while (k < primes.length) {
|
|
289
|
+
if (primes[k] === next) {
|
|
290
|
+
seq.push(primes[k]);
|
|
291
|
+
next = seq[seq.length - 2] + seq[seq.length - 1];
|
|
292
|
+
k++;
|
|
293
|
+
} else if (primes[k] > next) {
|
|
294
|
+
break;
|
|
295
|
+
} else {
|
|
296
|
+
k++;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (seq.length >= minLength) {
|
|
301
|
+
sequences.push(seq);
|
|
302
|
+
}
|
|
642
303
|
}
|
|
643
|
-
return new ResonantFragment(combined.normalize());
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Rotate phase of fragment
|
|
648
|
-
*/
|
|
649
|
-
rotatePhase(angle) {
|
|
650
|
-
const rotation = Complex.fromPolar(1, angle);
|
|
651
|
-
const rotated = this.state.scale(rotation);
|
|
652
|
-
return new ResonantFragment(rotated);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
/**
|
|
656
|
-
* Check coherence with another fragment
|
|
657
|
-
*/
|
|
658
|
-
coherenceWith(other) {
|
|
659
|
-
return this.state.coherence(other.state);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Get dominant primes
|
|
664
|
-
*/
|
|
665
|
-
dominant(n = 5) {
|
|
666
|
-
return this.state.dominant(n);
|
|
667
304
|
}
|
|
668
305
|
|
|
669
|
-
|
|
670
|
-
return {
|
|
671
|
-
amplitudes: this.state.toArray(),
|
|
672
|
-
center: [this.centerX, this.centerY],
|
|
673
|
-
entropy: this.entropy,
|
|
674
|
-
dominant: this.dominant(3)
|
|
675
|
-
};
|
|
676
|
-
}
|
|
306
|
+
return sequences;
|
|
677
307
|
}
|
|
678
308
|
|
|
309
|
+
// Singleton instance for convenience
|
|
310
|
+
const defaultCalculator = new ResonanceCalculator();
|
|
311
|
+
|
|
679
312
|
module.exports = {
|
|
680
|
-
|
|
313
|
+
ResonanceCalculator,
|
|
314
|
+
resonanceSignature,
|
|
315
|
+
findFibonacciSequences,
|
|
681
316
|
PHI,
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
// Classes
|
|
686
|
-
QuaternionPrime,
|
|
687
|
-
PrimeResonanceIdentity,
|
|
688
|
-
PhaseLockedRing,
|
|
689
|
-
HolographicField,
|
|
690
|
-
EntangledNode,
|
|
691
|
-
ResonantFragment,
|
|
317
|
+
PHI_THRESHOLD,
|
|
318
|
+
PHI_BONUS,
|
|
692
319
|
|
|
693
|
-
//
|
|
694
|
-
|
|
320
|
+
// Convenience functions using default calculator
|
|
321
|
+
calculateResonance: (p1, p2) => defaultCalculator.calculateResonance(p1, p2),
|
|
322
|
+
findGoldenPairs: (primes) => defaultCalculator.findGoldenPairs(primes),
|
|
323
|
+
findMostResonant: (target, candidates) => defaultCalculator.findMostResonant(target, candidates)
|
|
695
324
|
};
|